From c4edb3a453b524fa5e4f81706f997a6667287f2c Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 10 Oct 2023 16:43:17 -0400 Subject: [PATCH] Revert "tests: add bgp_linkstate_topo1" This reverts commit a0e6cd4c8fb954f66546b056b0016b4ca7a0a430. --- .../topotests/bgp_linkstate_topo1/__init__.py | 0 .../bgp_linkstate_topo1/r1/bgp_injector.cfg | 202 ------ .../bgp_linkstate_topo1/r1/bgp_injector.py | 596 ------------------ .../bgp_linkstate_topo1/r1/staticd.conf | 1 - .../bgp_linkstate_topo1/r1/zebra.conf | 7 - .../bgp_linkstate_topo1/r2/bgpd.conf | 20 - .../bgp_linkstate_topo1/r2/linkstate.json | 189 ------ .../bgp_linkstate_topo1/r2/staticd.conf | 2 - .../bgp_linkstate_topo1/r2/zebra.conf | 11 - .../bgp_linkstate_topo1/r3/bgpd.conf | 14 - .../bgp_linkstate_topo1/r3/linkstate.json | 1 - .../bgp_linkstate_topo1/r3/staticd.conf | 1 - .../bgp_linkstate_topo1/r3/zebra.conf | 7 - .../test_bgp_linkstate_topo1.py | 113 ---- 14 files changed, 1164 deletions(-) delete mode 100644 tests/topotests/bgp_linkstate_topo1/__init__.py delete mode 100644 tests/topotests/bgp_linkstate_topo1/r1/bgp_injector.cfg delete mode 100755 tests/topotests/bgp_linkstate_topo1/r1/bgp_injector.py delete mode 100644 tests/topotests/bgp_linkstate_topo1/r1/staticd.conf delete mode 100644 tests/topotests/bgp_linkstate_topo1/r1/zebra.conf delete mode 100644 tests/topotests/bgp_linkstate_topo1/r2/bgpd.conf delete mode 100644 tests/topotests/bgp_linkstate_topo1/r2/linkstate.json delete mode 100644 tests/topotests/bgp_linkstate_topo1/r2/staticd.conf delete mode 100644 tests/topotests/bgp_linkstate_topo1/r2/zebra.conf delete mode 100644 tests/topotests/bgp_linkstate_topo1/r3/bgpd.conf delete mode 120000 tests/topotests/bgp_linkstate_topo1/r3/linkstate.json delete mode 100644 tests/topotests/bgp_linkstate_topo1/r3/staticd.conf delete mode 100644 tests/topotests/bgp_linkstate_topo1/r3/zebra.conf delete mode 100644 tests/topotests/bgp_linkstate_topo1/test_bgp_linkstate_topo1.py diff --git a/tests/topotests/bgp_linkstate_topo1/__init__.py b/tests/topotests/bgp_linkstate_topo1/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/topotests/bgp_linkstate_topo1/r1/bgp_injector.cfg b/tests/topotests/bgp_linkstate_topo1/r1/bgp_injector.cfg deleted file mode 100644 index 30fbc7d847..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r1/bgp_injector.cfg +++ /dev/null @@ -1,202 +0,0 @@ -// Check content with -// cat bgp_injector.cfg | sed -e 's|//.*||g' | jq . -{ -"my_as": 65001, -"hold_time": 30, -"bgp_identifier": "192.0.2.1", -"local_address": "192.0.2.1", -"peer_address": "192.0.2.2", -"mss": 4000, -"port": 179, -"path_attributes": -{ - "as-path": "65001", - "next-hop": "192.0.2.1", - "origin": 0 -}, -"link_states": -[ - { - "nlri": - { - "proto": "01", // IS-IS L1 - "id": "0000000000000020", - "type": "0002", // Link-NLRI - "256": { // Local Link-Node Descriptor TLV - "512": "0000fde9", // AS 65001 - "513": "00000000", // BGP-LS ID - "515": "000000001001" // router-id: 0000.0000.1001 - }, - "257": { // Remote Link-Node Descriptor TLV - "512": "0000fde9", // AS 65001 - "513": "00000000", // BGP-LS ID - "515": "000000001000" // router-id: 0000.0000.1000 - }, - "259": "0a010001", // IPv4 interface address TLV - "260": "0a010002", // IPv4 Neighbor address TLV - "261": "20010000000000000000000000000001", // IPv6 interface address TLV - "262": "20010000000000000000000000000002", // IPv6 Neighbor address TLV - "263": "00000002" // MT-ID - }, - "attr": - { - "1028": "01010101", //IPv4 Router-ID of Local Node TLV - "1030": "0a0a0a0a", //IPv4 Router-ID of Remote Node TLV - "1089": "4d2817c8", // Maximum link bandwidth TLV 1410.07 Mbps - "1090": "4d2817c8", // Maximum reservable link bandwidth TLV 1410.07 Mbps - "1091": "4d2817c84d2817c84d2817c84d2817c84d2817c84d2817c84d2817c84d2817c8", // Unreserved bandwidth TLV - "1092": "00000064", // TE Default Metric TLV - "1095": "00000a", // Metric TLV - // Adjacency SID TLV - // Flags: 0x30, Value Flag (V), Local Flag (L) - // Weight: 0 - // .... 0000 0011 1010 1001 1000 = SID/Label: 15000 - "1099": "30000000003a98", - //Unidirectional Link Delay TLV - // TE Metric Flags: 0x00 - // Delay: 8500 - "1114": "00002134", - //Min/Max Unidirectional Link Delay TLV - // TE Metric Flags: 0x00 - // Min Delay: 8000 - // Reserved: 0x00 - // Max Delay: 9000 - "1115": "00001f4000002328", - "1122": { //Application-Specific Link Attributes TLV - // Type: 1122 - // Length: 48 - // SABM Length: 4 - // UDABM Length: 4 - // Reserved: 0x0000 - // Standard Application Identifier Bit Mask: 0x10000000, Flexible Algorithm (X) - // User-Defined Application Identifier Bit Mask: 00 00 00 00 - "0": "040400001000000000000000", // 0 means encode data directly - "1088": "00000001", // Administrative group (color) TLV - "1092": "00000064", // TE Default Metric TLV - "1115": "00001f4000002328", // Min/Max Unidirectional Link Delay TLV - "1173": "00000001"// Extended Administrative Group TLV - } - } - }, - { - "nlri": - { - "proto": "01", // IS-IS L1 - "id": "0000000000000020", - "type": "0001", // Node-NLRI - "256": { // Local Link-Node Descriptor TLV - "512": "0000fde9", // AS 65001 - "513": "00000000", // BGP-LS ID - "515": "00000000100300" // router-id: 0000.0000.1003.00 - } - }, - "attr": - { - "0": "0107000400000002010a00020108040200027233040300034910000404000403030303040a000cc000000fa004890003004e20040b0003008082040c000c00000003e804890003003a98" - } - }, - { - "nlri": - { - "proto": "03", // OSPFv2 - "id": "0000000000000020", - "type": "0001", // Node-NLRI - "256": { // Local Link-Node Descriptor TLV - "512": "0000fde9", // AS 65001 - "513": "00000000", // BGP-LS ID - "514": "00000000", // Area 0 - "515": "0a0a0a0a" // router-id: 10.10.10.10 - } - } - }, - { - "nlri": - { - "proto": "03", // OSPFv2 - "id": "0000000000000020", - "type": "0001", // Node-NLRI - "256": { // Local Link-Node Descriptor TLV - "512": "0000fde9", // AS 65001 - "513": "00000000", // BGP-LS ID - "514": "00000000", // Area 0 - "515": "0a0a0a0a01010101" // router-id: 10.10.10.10:1.1.1.1 - } - } - }, - { - "nlri": - { - "proto": "03", // OSPFv2 - "id": "0000000000000020", - "type": "0003", // IPv4-topo-prefix-NLRI - "256": { // Local Link-Node Descriptor TLV - "512": "0000fde9", // AS 65001 - "513": "00000000", // BGP-LS ID - "514": "00000000", // Area 0 - "515": "0a0a0a0a01010101" // router-id: 10.10.10.10:1.1.1.1 - }, - "265": "18590a0b" // IP Reachability Information TLV (89.10.11.0/24) - } - }, - { - "nlri": - { - "proto": "02", // IS-IS L2 - "id": "0000000000000020", - "type": "0004", // IPv6-topo-prefix-NLRI - "256": { // Local Link-Node Descriptor TLV - "512": "0000fde9", // AS 65001 - "513": "00000000", // BGP-LS ID - "515": "00000000100300" // router-id: 0000.0000.1003.00 - }, - "263": "0002", // MT-ID - // IP Reachability Information TLV (12:12::12:12/128) - "265": "8000120012000000000000000000120012" - } - }, - { - "nlri": - { - "proto": "06", // OSPFv3 - "id": "0000000000000020", - "type": "0004", // IPv6-topo-prefix-NLRI - "256": { // Local Link-Node Descriptor TLV - "512": "0000fde9", // AS 65001 - "513": "00000000", // BGP-LS ID - "514": "00000000", // Area 0 - "515": "0a0a0a0a" // router-id: 10.10.10.10 - }, - "263": "0002", // MT-ID - "264": "01", // OSPF: route-type Intra-Area (0x1) - // IP Reachability Information TLV (12:12::12:12/128) - "265": "8000120012000000000000000000120012" - } - }, - { - "nlri": - { - "proto": "06", // OSPFv3 - "id": "ffffffffffffffff", - "type": "0002", // Link-NLRI - "256": { // Local Link-Node Descriptor TLV - "512": "ffffffff", // AS - "513": "ffffffff", // BGP-LS ID - "514": "ffffffff", // OSPF area ID - "515": "0a0a0a0b02020202" // router-id: 10.10.10.11:2.2.2.2 - }, - "257": { // Remote Link-Node Descriptor TLV - "512": "ffffffff", // AS - "513": "ffffffff", // BGP-LS ID - "514": "ffffffff", // OSPF area ID - "515": "0a0a0a0a01010101" // router-id: 10.10.10.10:1.1.1.1 - }, - "259": "0a010001", // IPv4 interface address TLV - "260": "0a010002", // IPv4 Neighbor address TLV - "261": "20010000000000000000000000000001", // IPv6 interface address TLV - "262": "20010000000000000000000000000002", // IPv6 Neighbor address TLV - "263": "00000002", // MT-ID - "424": "200100000000000001" // unknown TLV - } - } -] -} diff --git a/tests/topotests/bgp_linkstate_topo1/r1/bgp_injector.py b/tests/topotests/bgp_linkstate_topo1/r1/bgp_injector.py deleted file mode 100755 index 314b8fe44c..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r1/bgp_injector.py +++ /dev/null @@ -1,596 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: MIT - -# -# Copyright 2018 Jorge Borreicho -# Copyright 2023 6WIND S.A. - -""" - BGP prefix injection tool -""" - -import socket -import sys -import time -from datetime import datetime -import struct -import threading -import json -import os -import re -import signal -import errno - - -AFI_IPV4 = 1 -SAFI_UNICAST = 1 - -AFI_LINKSTATE = 16388 -SAFI_LINKSTATE = 71 - -saved_pid = False -global pid_file - -class Unbuffered(object): - def __init__(self, stream): - self.stream = stream - def write(self, data): - self.stream.write(data) - self.stream.flush() - def writelines(self, datas): - self.stream.writelines(datas) - self.stream.flush() - def __getattr__(self, attr): - return getattr(self.stream, attr) - -def keepalive_thread(conn, interval): - - # infinite loop so that function do not terminate and thread do not end. - while True: - time.sleep(interval) - keepalive_bgp(conn) - - -def receive_thread(conn): - - # infinite loop so that function do not terminate and thread do not end. - while True: - - # Receiving from client - r = conn.recv(1500) - while True: - start_ptr = ( - r.find( - b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - ) - + 16 - ) - end_ptr = ( - r[16:].find( - b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - ) - + 16 - ) - if ( - start_ptr >= end_ptr - ): # a single message was sent in the BGP packet OR it is the last message of the BGP packet - decode_bgp(r[start_ptr:]) - break - else: # more messages left to decode - decode_bgp(r[start_ptr:end_ptr]) - r = r[end_ptr:] - - -def decode_bgp(msg): - if len(msg) < 3: - return - msg_length, msg_type = struct.unpack("!HB", msg[0:3]) - if msg_type == 4: - # print(timestamp + " - " + "Received KEEPALIVE") #uncomment to debug - pass - elif msg_type == 2: - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "Received UPDATE") - elif msg_type == 1: - version, remote_as, holdtime, i1, i2, i3, i4, opt_length = struct.unpack( - "!BHHBBBBB", msg[3:13] - ) - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "Received OPEN") - print() - print( - "--> Version:" - + str(version) - + ", Remote AS: " - + str(remote_as) - + ", Hold Time:" - + str(holdtime) - + ", Remote ID: " - + str(i1) - + "." - + str(i2) - + "." - + str(i3) - + "." - + str(i4) - ) - print() - elif msg_type == 3: - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "Received NOTIFICATION") - - -def multiprotocol_capability(afi, safi): - hexstream = bytes.fromhex("02060104") - hexstream += struct.pack("!H", afi) - hexstream += struct.pack("!B", 0) - hexstream += struct.pack("!B", safi) - - return hexstream - - -def open_bgp(conn, config): - - # Build the BGP Message - bgp_version = b"\x04" - bgp_as = struct.pack("!H", config["my_as"]) - bgp_hold_time = struct.pack("!H", config["hold_time"]) - - octet = config["bgp_identifier"].split(".") - bgp_identifier = struct.pack( - "!BBBB", int(octet[0]), int(octet[1]), int(octet[2]), int(octet[3]) - ) - - bgp_opt = b"" - bgp_opt += multiprotocol_capability(AFI_IPV4, SAFI_UNICAST) - bgp_opt += multiprotocol_capability(AFI_LINKSTATE, SAFI_LINKSTATE) - - bgp_opt_lenght = struct.pack("!B", len(bgp_opt)) - - bgp_message = ( - bgp_version + bgp_as + bgp_hold_time + bgp_identifier + bgp_opt_lenght + bgp_opt - ) - - # Build the BGP Header - total_length = len(bgp_message) + 16 + 2 + 1 - bgp_marker = b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - bgp_length = struct.pack("!H", total_length) - bgp_type = b"\x01" - bgp_header = bgp_marker + bgp_length + bgp_type - - bgp_packet = bgp_header + bgp_message - - conn.send(bgp_packet) - return 0 - - -def keepalive_bgp(conn): - - # Build the BGP Header - total_length = 16 + 2 + 1 - bgp_marker = b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - bgp_length = struct.pack("!H", total_length) - bgp_type = b"\x04" - bgp_header = bgp_marker + bgp_length + bgp_type - - bgp_packet = bgp_header - - conn.send(bgp_packet) - return 0 - - -def encode_ipv4_prefix(address, netmask): - - octet = address.split(".") - length = struct.pack("!B", int(netmask)) - - if int(netmask) <= 8: - prefix = struct.pack("!B", int(octet[0])) - elif int(netmask) <= 16: - prefix = struct.pack("!BB", int(octet[0]), int(octet[1])) - elif int(netmask) <= 24: - prefix = struct.pack("!BBB", int(octet[0]), int(octet[1]), int(octet[2])) - else: - prefix = struct.pack( - "!BBBB", int(octet[0]), int(octet[1]), int(octet[2]), int(octet[3]) - ) - - return length + prefix - - -def encode_path_attribute_mp_reach_nrli(afi, safi, data, config): - hexstream = b"" - hexstream += b"\x90" # flags optional, extended - hexstream += struct.pack("!B", 14) # type code MP_REACH_NLRI - - hexstream2 = b"" - hexstream2 += struct.pack("!H", afi) - hexstream2 += struct.pack("!B", safi) - hexstream2 += struct.pack("!B", 4) # nexthop length - hexstream2 += socket.inet_aton(config["local_address"]) # nexthop IPv4 - hexstream2 += b"\x00" # SNPA - hexstream2 += data - - hexstream += struct.pack("!H", len(hexstream2)) # length - hexstream += hexstream2 - - return hexstream - - -def encode_path_attribute_linkstate(data): - hexstream = b"" - hexstream += b"\x80" # flags optional - hexstream += struct.pack("!B", 29) # type code BGP-LS - hexstream += struct.pack("!B", len(data)) # length - hexstream += data - - return hexstream - - -def encode_path_attribute(type, value): - - path_attributes = { - "origin": [b"\x40", 1], - "as-path": [b"\x40", 2], - "next-hop": [b"\x40", 3], - "med": [b"\x80", 4], - "local_pref": [b"\x40", 5], - "communities": [b"\xc0", 8], - } - - attribute_flag = path_attributes[type][0] - attribute_type_code = struct.pack("!B", int(path_attributes[type][1])) - - if type == "origin": - attribute_value = struct.pack("!B", value) - elif type == "as-path": - as_number_list = value.split(" ") - attribute_value = struct.pack("!BB", 2, len(as_number_list)) - for as_number in as_number_list: - attribute_value += struct.pack("!H", int(as_number)) - elif type == "next-hop": - octet = value.split(".") - attribute_value = struct.pack( - "!BBBB", int(octet[0]), int(octet[1]), int(octet[2]), int(octet[3]) - ) - elif type == "med": - attribute_value = struct.pack("!I", value) - elif type == "local_pref": - attribute_value = struct.pack("!I", value) - elif type == "communities": - communities_list = value.split(" ") - attribute_value = b"" - for community in communities_list: - aux = community.split(":") - attribute_value += struct.pack("!HH", int(aux[0]), int(aux[1])) - - attribute_length = struct.pack("!B", len(attribute_value)) - - return attribute_flag + attribute_type_code + attribute_length + attribute_value - - -def encode_tlvs(tlvs): - stream = b"" - for key, tlv_data in tlvs.items(): - if isinstance(key, str) and key.isdigit(): - tlv_type = int(key) - else: - # key is not a TLV - continue - if isinstance(tlv_data, str): - if tlv_type != 0: - # TLV type 0 is fake TLV - stream += struct.pack("!H", tlv_type) - stream += struct.pack("!H", len(bytes.fromhex(tlv_data))) - stream += bytes.fromhex(tlv_data) - elif isinstance(tlv_data, dict): - # TLV contains sub-TLV - stream += struct.pack("!H", tlv_type) - - stream_subtlv = encode_tlvs(tlv_data) - stream += struct.pack("!H", len(stream_subtlv)) - stream += stream_subtlv - else: - # invalid input - assert 0 - - return stream - - -def encode_linkstate_nrli_tlv(nlri): - stream = b"" - stream += bytes.fromhex(nlri["type"]) - - stream2 = b"" - stream2 += bytes.fromhex(nlri["proto"]) - stream2 += bytes.fromhex(nlri["id"]) - stream2 += encode_tlvs(nlri) - - stream += struct.pack("!H", len(stream2)) - stream += stream2 - - return stream - - -def update_bgp(conn, link_state, config): - - # Build the BGP Message - - # Expired Routes - # 1 - Withdrawn Routes - - bgp_withdrawn_routes = b"" - max_length_reached = False - - bgp_withdrawn_routes_length = struct.pack("!H", len(bgp_withdrawn_routes)) - bgp_withdrawn_routes = bgp_withdrawn_routes_length + bgp_withdrawn_routes - - # New Routes - # 2 - Path Attributes - - path_attributes = config["path_attributes"] - bgp_mss = config["mss"] - - bgp_total_path_attributes = b"" - - # encode link-state MP_REACH NLRI - data = encode_linkstate_nrli_tlv(link_state["nlri"]) - bgp_total_path_attributes += encode_path_attribute_mp_reach_nrli( - AFI_LINKSTATE, SAFI_LINKSTATE, data, config - ) - - # encode classic attributes - for key in path_attributes.keys(): - bgp_total_path_attributes += encode_path_attribute(key, path_attributes[key]) - - # encode link-state attributes - if "attr" in link_state: - data = encode_tlvs(link_state["attr"]) - else: - data = b"" - bgp_total_path_attributes += encode_path_attribute_linkstate(data) - - bgp_total_path_attributes_length = struct.pack("!H", len(bgp_total_path_attributes)) - bgp_total_path_attributes = ( - bgp_total_path_attributes_length + bgp_total_path_attributes - ) - - # 3- Network Layer Reachability Information (NLRI) - - bgp_new_routes = b"" - - bgp_message = bgp_withdrawn_routes + bgp_total_path_attributes + bgp_new_routes - - # Build the BGP Header - total_length = len(bgp_message) + 16 + 2 + 1 - bgp_marker = b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - bgp_length = struct.pack("!H", total_length) - bgp_type = b"\x02" - bgp_header = bgp_marker + bgp_length + bgp_type - - bgp_packet = bgp_header + bgp_message - - conn.send(bgp_packet) - - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "Sent UPDATE") - - return 0 - - -def str2ip(ip_str): - s_octet = ip_str.split(".") - ip_addr = struct.pack( - "!BBBB", int(s_octet[0]), int(s_octet[1]), int(s_octet[2]), int(s_octet[3]) - ) - return ip_addr - - -def check_pid(pid): - if pid < 0: # user input error - return False - if pid == 0: # all processes - return False - try: - os.kill(pid, 0) - return True - except OSError as err: - if err.errno == errno.EPERM: # a process we were denied access to - return True - if err.errno == errno.ESRCH: # No such process - return False - # should never happen - return False - - -def savepid(): - ownid = os.getpid() - - flags = os.O_CREAT | os.O_EXCL | os.O_WRONLY - mode = ((os.R_OK | os.W_OK) << 6) | (os.R_OK << 3) | os.R_OK - - try: - fd = os.open(pid_file, flags, mode) - except OSError: - try: - pid = open(pid_file, "r").readline().strip() - if check_pid(int(pid)): - sys.stderr.write( - "PIDfile already exists and program still running %s\n" % pid_file - ) - return False - else: - # If pid is not running, reopen file without O_EXCL - fd = os.open(pid_file, flags ^ os.O_EXCL, mode) - except (OSError, IOError, ValueError): - sys.stderr.write( - "issue accessing PID file %s (most likely permission or ownership)\n" - % pid_file - ) - return False - - try: - f = os.fdopen(fd, "w") - line = "%d\n" % ownid - f.write(line) - f.close() - saved_pid = True - except IOError: - sys.stderr.write("Can not create PIDfile %s\n" % pid_file) - return False - print("Created PIDfile %s with value %d\n" % (pid_file, ownid)) - return True - - -def removepid(): - if not saved_pid: - return - try: - os.remove(pid_file) - except OSError as exc: - if exc.errno == errno.ENOENT: - pass - else: - sys.stderr.write("Can not remove PIDfile %s\n" % pid_file) - return - sys.stderr.write("Removed PIDfile %s\n" % pid_file) - - -def daemonize(): - try: - pid = os.fork() - if pid > 0: - # Exit first parent - sys.exit(0) - except OSError as e: - print("Fork #1 failed: %d (%s)" % (e.errno, e.strerror)) - sys.exit(1) - - # Decouple from parent environment - os.chdir("/") - os.setsid() - os.umask(0) - - # Do second fork - try: - pid = os.fork() - if pid > 0: - # Exit from second parent - sys.exit(0) - except OSError as e: - print("Fork #2 failed: %d (%s)" % (e.errno, e.strerror)) - sys.exit(1) - - # Redirect standard file descriptors - sys.stdout.flush() - sys.stderr.flush() - si = open(os.devnull, "r") - so = open(os.devnull, "a+") - se = open(os.devnull, "a+") - - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) - - -def term(signal, frame): - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "^C received, shutting down.\n") - bgp_socket.close() - removepid() - exit() - - -if __name__ == "__main__": - if len(sys.argv) > 1: - # daemonize and log to file - daemonize() - pid_file = os.path.join(sys.argv[1], "bgp_injector.pid") - savepid() - # deal with daemon termination - signal.signal(signal.SIGTERM, term) - signal.signal(signal.SIGINT, term) # CTRL + C - - log_dir = os.path.join(sys.argv[1], "bgp_injector.log") - f = open(log_dir, 'w') - sys.stdout = Unbuffered(f) - sys.stderr = Unbuffered(f) - - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "Starting BGP injector ") - - CONFIG_FILENAME = os.path.join(sys.path[0], "bgp_injector.cfg") - - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "Reading config file " + CONFIG_FILENAME) - - input_file = open(CONFIG_FILENAME, "r") - - input = input_file.read() - # cleanup comments that are not supported by JSON - json_input = re.sub(r"//.*\n", "", input, flags=re.MULTILINE) - - config = json.loads(json_input) - - bgp_peer = config["peer_address"] - bgp_local = config["local_address"] - bgp_mss = config["mss"] - bgp_port = config["port"] - rib = dict() - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "Starting BGP... (peer: " + str(bgp_peer) + ")") - - retry = 30 - while retry: - retry -= 1 - try: - bgp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - bgp_socket.bind((bgp_local, 0)) - bgp_socket.connect((bgp_peer, bgp_port)) - open_bgp(bgp_socket, config) - break - except TimeoutError: - if retry == 0: - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "Error: timeout connecting to the peer.") - exit() - time.sleep(1) - except OSError as e: - if retry == 0: - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "Error: cannot connect to the peer: " + str(e)) - exit() - time.sleep(1) - - receive_worker = threading.Thread( - target=receive_thread, args=(bgp_socket,) - ) # wait from BGP msg from peer and process them - receive_worker.setDaemon(True) - receive_worker.start() - - keepalive_worker = threading.Thread( - target=keepalive_thread, - args=( - bgp_socket, - (config["hold_time"]) / 3, - ), - ) # send keep alives every 10s by default - keepalive_worker.setDaemon(True) - keepalive_worker.start() - - # send a first keepalive packet before sending the initial UPDATE packet - keepalive_bgp(bgp_socket) - - timestamp = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) - print(timestamp + " - " + "BGP is up.") - - time.sleep(3) - for link_state in config["link_states"]: - update_bgp( - bgp_socket, - link_state, - config, - ) - - while True: - time.sleep(60) diff --git a/tests/topotests/bgp_linkstate_topo1/r1/staticd.conf b/tests/topotests/bgp_linkstate_topo1/r1/staticd.conf deleted file mode 100644 index 7f2f057bfe..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r1/staticd.conf +++ /dev/null @@ -1 +0,0 @@ -ip route 192.0.2.2/32 192.168.1.2 diff --git a/tests/topotests/bgp_linkstate_topo1/r1/zebra.conf b/tests/topotests/bgp_linkstate_topo1/r1/zebra.conf deleted file mode 100644 index 3307c123f8..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r1/zebra.conf +++ /dev/null @@ -1,7 +0,0 @@ -! -interface lo - ip address 192.0.2.1/32 -! -interface r1-eth0 - ip address 192.168.1.1/24 -! \ No newline at end of file diff --git a/tests/topotests/bgp_linkstate_topo1/r2/bgpd.conf b/tests/topotests/bgp_linkstate_topo1/r2/bgpd.conf deleted file mode 100644 index 26ffee9c1b..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r2/bgpd.conf +++ /dev/null @@ -1,20 +0,0 @@ -router bgp 65002 - no bgp ebgp-requires-policy - neighbor 192.0.2.1 remote-as 65001 - neighbor 192.0.2.1 timers connect 1 - neighbor 192.0.2.1 ebgp-multihop 3 - neighbor 192.0.2.1 update-source 192.0.2.2 - neighbor 192.0.2.3 remote-as 65003 - neighbor 192.0.2.3 timers 1 3 - neighbor 192.0.2.3 timers connect 1 - neighbor 192.0.2.3 ebgp-multihop 3 - neighbor 192.0.2.3 update-source 192.0.2.2 - address-family ipv4 unicast - no neighbor 192.0.2.1 activate - no neighbor 192.0.2.3 activate - exit-address-family - address-family link-state link-state - neighbor 192.0.2.1 activate - neighbor 192.0.2.3 activate - exit-address-family -! \ No newline at end of file diff --git a/tests/topotests/bgp_linkstate_topo1/r2/linkstate.json b/tests/topotests/bgp_linkstate_topo1/r2/linkstate.json deleted file mode 100644 index 1e653c5531..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r2/linkstate.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "routes": { - "Link OSPFv3 ID:0xffffffffffffffff {Local {AS:4294967295 ID:4294967295 Area:4294967295 Rtr:10.10.10.11:2.2.2.2} Remote {AS:4294967295 ID:4294967295 Area:4294967295 Rtr:10.10.10.10:1.1.1.1} IPv4:10.1.0.1 Neigh-IPv4:10.1.0.2 IPv6:2001::1 Neigh-IPv6:2001::2 MT:0,2 424:0x200100000000000001}/XX": [ - { - "valid": true, - "bestpath": true, - "pathFrom": "external", - "linkStateNLRI": { - "nlriType": "Link", - "protocol": "OSPFv3", - "identifier": "0xffffffffffffffff", - "localNode": { - "as": 4294967295, - "identifier": 4294967295, - "area": 4294967295, - "routerID": "10.10.10.11:2.2.2.2" - }, - "remoteNode": { - "as": 4294967295, - "identifier": 4294967295, - "area": 4294967295, - "routerID": "10.10.10.10:1.1.1.1" - }, - "interfaceIPv4": "10.1.0.1", - "neighborIPv4": "10.1.0.2", - "interfaceIPv6": "2001::1", - "neighborIPv6": "2001::2", - "mtID": [0, 2], - "424": ["0x2001000000000000", "0x01"] - }, - "weight": 0, - "origin": "IGP" - } - ], - "IPv6-Prefix OSPFv3 ID:0x20 {Local {AS:65001 ID:0 Area:0 Rtr:10.10.10.10} MT:2 OSPF-Route-Type:1 IPv6:12:12::12:12/128}/XX": [ - { - "valid": true, - "bestpath": true, - "pathFrom": "external", - "linkStateNLRI": { - "nlriType": "IPv6-Prefix", - "protocol": "OSPFv3", - "identifier": "0x20", - "localNode": { - "as": 65001, - "identifier": 0, - "area": 0, - "routerID": "10.10.10.10" - }, - "ospfRouteType": 1, - "ipReachability": "12:12::12:12/128", - "mtID": [2] - }, - "weight": 0, - "origin": "IGP" - } - ], - "IPv6-Prefix ISIS-L2 ID:0x20 {Local {AS:65001 ID:0 Rtr:0000.0000.1003.00} MT:2 IPv6:12:12::12:12/128}/XX": [ - { - "valid": true, - "bestpath": true, - "pathFrom": "external", - "linkStateNLRI": { - "nlriType": "IPv6-Prefix", - "protocol": "ISIS-L2", - "identifier": "0x20", - "localNode": { - "as": 65001, - "identifier": 0, - "routerID": "0000.0000.1003.00" - }, - "ipReachability": "12:12::12:12/128", - "mtID": [2] - }, - "weight": 0, - "origin": "IGP" - } - ], - "IPv4-Prefix OSPFv2 ID:0x20 {Local {AS:65001 ID:0 Area:0 Rtr:10.10.10.10:1.1.1.1} IPv4:89.10.11.0/24}/XX": [ - { - "valid": true, - "bestpath": true, - "pathFrom": "external", - "linkStateNLRI": { - "nlriType": "IPv4-Prefix", - "protocol": "OSPFv2", - "identifier": "0x20", - "localNode": { - "as": 65001, - "identifier": 0, - "area": 0, - "routerID": "10.10.10.10:1.1.1.1" - }, - "ipReachability": "89.10.11.0/24" - }, - "weight": 0, - "origin": "IGP" - } - ], - "Node OSPFv2 ID:0x20 {Local {AS:65001 ID:0 Area:0 Rtr:10.10.10.10:1.1.1.1}}/XX": [ - { - "valid": true, - "bestpath": true, - "pathFrom": "external", - "linkStateNLRI": { - "nlriType": "Node", - "protocol": "OSPFv2", - "identifier": "0x20", - "localNode": { - "as": 65001, - "identifier": 0, - "area": 0, - "routerID": "10.10.10.10:1.1.1.1" - } - }, - "weight": 0, - "origin": "IGP" - } - ], - "Node OSPFv2 ID:0x20 {Local {AS:65001 ID:0 Area:0 Rtr:10.10.10.10}}/XX": [ - { - "valid": true, - "bestpath": true, - "pathFrom": "external", - "linkStateNLRI": { - "nlriType": "Node", - "protocol": "OSPFv2", - "identifier": "0x20", - "localNode": { - "as": 65001, - "identifier": 0, - "area": 0, - "routerID": "10.10.10.10" - } - }, - "weight": 0, - "origin": "IGP" - } - ], - "Node ISIS-L1 ID:0x20 {Local {AS:65001 ID:0 Rtr:0000.0000.1003.00}}/XX": [ - { - "valid": true, - "bestpath": true, - "pathFrom": "external", - "linkStateNLRI": { - "nlriType": "Node", - "protocol": "ISIS-L1", - "identifier": "0x20", - "localNode": { - "as": 65001, - "identifier": 0, - "routerID": "0000.0000.1003.00" - } - }, - "weight": 0, - "origin": "IGP" - } - ], - "Link ISIS-L1 ID:0x20 {Local {AS:65001 ID:0 Rtr:0000.0000.1001} Remote {AS:65001 ID:0 Rtr:0000.0000.1000} IPv4:10.1.0.1 Neigh-IPv4:10.1.0.2 IPv6:2001::1 Neigh-IPv6:2001::2 MT:0,2}/XX": [ - { - "valid": true, - "bestpath": true, - "pathFrom": "external", - "linkStateNLRI": { - "nlriType": "Link", - "protocol": "ISIS-L1", - "identifier": "0x20", - "localNode": { - "as": 65001, - "identifier": 0, - "routerID": "0000.0000.1001" - }, - "remoteNode": { - "as": 65001, - "identifier": 0, - "routerID": "0000.0000.1000" - }, - "interfaceIPv4": "10.1.0.1", - "neighborIPv4": "10.1.0.2", - "interfaceIPv6": "2001::1", - "neighborIPv6": "2001::2", - "mtID": [0, 2] - }, - "weight": 0, - "origin": "IGP" - } - ] - } -} diff --git a/tests/topotests/bgp_linkstate_topo1/r2/staticd.conf b/tests/topotests/bgp_linkstate_topo1/r2/staticd.conf deleted file mode 100644 index 4ce3f7b9b1..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r2/staticd.conf +++ /dev/null @@ -1,2 +0,0 @@ -ip route 192.0.2.1/32 192.168.1.1 -ip route 192.0.2.3/32 192.168.2.3 \ No newline at end of file diff --git a/tests/topotests/bgp_linkstate_topo1/r2/zebra.conf b/tests/topotests/bgp_linkstate_topo1/r2/zebra.conf deleted file mode 100644 index 586dc0acad..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r2/zebra.conf +++ /dev/null @@ -1,11 +0,0 @@ -! -int lo - ip address 192.0.2.2/32 -! -interface r2-eth0 - ip address 192.168.1.2/24 -! -interface r2-eth1 - ip address 192.168.2.2/24 -! - diff --git a/tests/topotests/bgp_linkstate_topo1/r3/bgpd.conf b/tests/topotests/bgp_linkstate_topo1/r3/bgpd.conf deleted file mode 100644 index 88693a3750..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r3/bgpd.conf +++ /dev/null @@ -1,14 +0,0 @@ -router bgp 65003 - no bgp ebgp-requires-policy - neighbor 192.0.2.2 remote-as 65002 - neighbor 192.0.2.2 timers 1 3 - neighbor 192.0.2.2 timers connect 1 - neighbor 192.0.2.2 ebgp-multihop 3 - neighbor 192.0.2.2 update-source 192.0.2.3 - address-family ipv4 unicast - no neighbor 192.0.2.2 activate - exit-address-family - address-family link-state link-state - neighbor 192.0.2.2 activate - exit-address-family -! \ No newline at end of file diff --git a/tests/topotests/bgp_linkstate_topo1/r3/linkstate.json b/tests/topotests/bgp_linkstate_topo1/r3/linkstate.json deleted file mode 120000 index 588691dcf7..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r3/linkstate.json +++ /dev/null @@ -1 +0,0 @@ -../r2/linkstate.json \ No newline at end of file diff --git a/tests/topotests/bgp_linkstate_topo1/r3/staticd.conf b/tests/topotests/bgp_linkstate_topo1/r3/staticd.conf deleted file mode 100644 index e8a3198ba7..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r3/staticd.conf +++ /dev/null @@ -1 +0,0 @@ -ip route 192.0.2.2/32 192.168.2.2 \ No newline at end of file diff --git a/tests/topotests/bgp_linkstate_topo1/r3/zebra.conf b/tests/topotests/bgp_linkstate_topo1/r3/zebra.conf deleted file mode 100644 index 532aede2e8..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/r3/zebra.conf +++ /dev/null @@ -1,7 +0,0 @@ -! -int lo - ip address 192.0.2.3/32 -! -interface r3-eth0 - ip address 192.168.2.3/24 -! diff --git a/tests/topotests/bgp_linkstate_topo1/test_bgp_linkstate_topo1.py b/tests/topotests/bgp_linkstate_topo1/test_bgp_linkstate_topo1.py deleted file mode 100644 index 805159ca90..0000000000 --- a/tests/topotests/bgp_linkstate_topo1/test_bgp_linkstate_topo1.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python -# SPDX-License-Identifier: ISC - -# Copyright 2023 6WIND S.A. - -import os -import sys -import json -import pytest -import functools - -CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, "../")) - -# pylint: disable=C0413 -from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.common_config import step -from lib.topolog import logger - -pytestmark = [pytest.mark.bgpd] - - -def build_topo(tgen): - for routern in range(1, 4): - tgen.add_router("r{}".format(routern)) - - switch = tgen.add_switch("s1") - switch.add_link(tgen.gears["r1"]) - switch.add_link(tgen.gears["r2"]) - - switch = tgen.add_switch("s2") - switch.add_link(tgen.gears["r2"]) - switch.add_link(tgen.gears["r3"]) - - -def setup_module(mod): - tgen = Topogen(build_topo, mod.__name__) - tgen.start_topology() - - router_list = tgen.routers() - - for i, (rname, router) in enumerate(router_list.items(), 1): - router.load_config( - TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) - ) - router.load_config( - TopoRouter.RD_STATIC, os.path.join(CWD, "{}/staticd.conf".format(rname)) - ) - if rname == "r1": - # use bgp_injector.py to inject BGP prefixes - continue - router.load_config( - TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) - ) - - tgen.start_router() - - r1_path = os.path.join(CWD, "r1") - log_dir = os.path.join(tgen.logdir, "r1") - tgen.gears["r1"].cmd("chmod u+x {}/bgp_injector.py".format(r1_path)) - tgen.gears["r1"].run("{}/bgp_injector.py {}".format(r1_path, log_dir)) - - -def teardown_module(mod): - tgen = get_topogen() - - log_dir = os.path.join(tgen.logdir, "r1") - pid_file = os.path.join(log_dir, "bgp_injector.pid") - - logger.info("r1: sending SIGTERM to bgp_injector") - tgen.gears["r1"].cmd("kill $(cat {})".format(pid_file)) - tgen.stop_topology() - - -def test_show_bgp_link_state(): - tgen = get_topogen() - - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - def _remove_prefixlen(tmp_json): - new_json = { - prefix.split("}/")[0] + "}/XX": data - for prefix, data in tmp_json["routes"].items() - } - - return new_json - - def _show_bgp_link_state_json(rname, tmp_expected): - tmp_output = json.loads( - tgen.gears[rname].vtysh_cmd("show bgp link-state link-state json") - ) - # prefix length is the size of prefix in memory - # which differs on 32 and 64 bits. - # do not compare the prefix length - output = _remove_prefixlen(tmp_output) - expected = _remove_prefixlen(tmp_expected) - - return topotest.json_cmp(output, expected) - - step("Check BGP Link-State tables") - for rname in ["r2", "r3"]: - expected = open(os.path.join(CWD, "{}/linkstate.json".format(rname))).read() - expected_json = json.loads(expected) - test_func = functools.partial(_show_bgp_link_state_json, rname, expected_json) - _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert result is None, "Failed to see BGP prefixes on {}".format(rname) - - -if __name__ == "__main__": - args = ["-s"] + sys.argv[1:] - sys.exit(pytest.main(args)) -- 2.39.5