rather than in testing. this is a major update and 3.x configurations will need changing, for details see https://github.com/Exa-Networks/exabgp/wiki/Migration-from-3.4-to-4.0
293 lines
8.8 KiB
Plaintext
293 lines
8.8 KiB
Plaintext
$OpenBSD: patch-qa_sbin_bgp,v 1.1 2019/07/11 14:14:52 sthen Exp $
|
|
|
|
From 6ec1f15da093ad395527919c93444ec50b7bcdca Mon Sep 17 00:00:00 2001
|
|
From: Thomas Mangin <thomas.mangin@exa.net.uk>
|
|
Date: Tue, 9 Jul 2019 23:00:02 +0100
|
|
Subject: [PATCH] convert the functional testing to python3 only
|
|
|
|
Index: qa/sbin/bgp
|
|
--- qa/sbin/bgp.orig
|
|
+++ qa/sbin/bgp
|
|
@@ -14,7 +14,7 @@ import sys
|
|
import time
|
|
import errno
|
|
import socket
|
|
-import thread
|
|
+import threading
|
|
import signal
|
|
import asyncore
|
|
import subprocess
|
|
@@ -26,12 +26,12 @@ SIGNAL = dict([(name,getattr(signal,name)) for name in
|
|
|
|
|
|
def flushed (*output):
|
|
- print ' '.join(str(_) for _ in output)
|
|
+ print(' '.join(str(_) for _ in output))
|
|
sys.stdout.flush()
|
|
|
|
|
|
def bytestream (value):
|
|
- return ''.join(['%02X' % ord(_) for _ in value])
|
|
+ return ''.join(['%02X' % _ for _ in value])
|
|
|
|
|
|
def dump (value):
|
|
@@ -40,7 +40,7 @@ def dump (value):
|
|
for v in value:
|
|
if even is False:
|
|
yield ' '
|
|
- yield '%02X' % ord(v)
|
|
+ yield '%02X' % v
|
|
even = not even
|
|
return ''.join(spaced(value))
|
|
|
|
@@ -60,13 +60,13 @@ def cdr_to_length (cidr):
|
|
class BGPHandler(asyncore.dispatcher_with_send):
|
|
counter = 0
|
|
|
|
- keepalive = chr(0xFF)*16 + chr(0x0) + chr(0x13) + chr(0x4)
|
|
+ keepalive = bytes([0xFF, ] * 16 + [0x0, 0x13, 0x4])
|
|
|
|
_name = {
|
|
- chr(1): 'OPEN',
|
|
- chr(2): 'UPDATE',
|
|
- chr(3): 'NOTIFICATION',
|
|
- chr(4): 'KEEPALIVE',
|
|
+ b'\x01': 'OPEN',
|
|
+ b'\x02': 'UPDATE',
|
|
+ b'\x03': 'NOTIFICATION',
|
|
+ b'\x04': 'KEEPALIVE',
|
|
}
|
|
|
|
def signal (self,myself,signal_name='SIGUSR1'):
|
|
@@ -119,54 +119,54 @@ class BGPHandler(asyncore.dispatcher_with_send):
|
|
try:
|
|
self.announce('sending signal %s to ExaBGP (pid %s)\n' % (signal_name,processes[0]))
|
|
os.kill(int(processes[0]),signal_number)
|
|
- except Exception,exc:
|
|
+ except Exception as exc:
|
|
self.announce('\n failed: %s' % str(exc))
|
|
|
|
def kind (self, header):
|
|
return header[18]
|
|
|
|
def isupdate (self, header):
|
|
- return header[18] == chr(2)
|
|
+ return header[18] == 2
|
|
|
|
def isnotification (self, header):
|
|
- return header[18] == chr(4)
|
|
+ return header[18] == 4
|
|
|
|
def name (self, header):
|
|
return self._name.get(header[18],'SOME WEIRD RFC PACKET')
|
|
|
|
def routes (self, header, body):
|
|
len_w = unpack('!H',body[0:2])[0]
|
|
- withdrawn = [ord(_) for _ in body[2:2+len_w]]
|
|
+ withdrawn = bytes([_ for _ in body[2:2+len_w]])
|
|
len_a = unpack('!H',body[2+len_w:2+len_w+2])[0]
|
|
- announced = [ord(_) for _ in body[2+len_w + 2+len_a:]]
|
|
+ announced = bytes([_ for _ in body[2+len_w + 2+len_a:]])
|
|
|
|
if not withdrawn and not announced:
|
|
if len(body) == 4:
|
|
yield 'eor:1:1'
|
|
elif len(body) == 11:
|
|
- yield 'eor:%d:%d' % (ord(body[-2]),ord(body[-1]))
|
|
+ yield 'eor:%d:%d' % (body[-2],body[-1])
|
|
else: # undecoded MP route
|
|
yield 'mp:'
|
|
return
|
|
|
|
while withdrawn:
|
|
- cdr = withdrawn.pop(0)
|
|
+ cdr,withdrawn = withdrawn[0],withdrawn[1:]
|
|
size = cdr_to_length(cdr)
|
|
r = [0,0,0,0]
|
|
for index in range(size):
|
|
- r[index] = withdrawn.pop(0)
|
|
+ r[index], withdrawn = withdrawn[0], withdrawn[1:]
|
|
yield 'withdraw:%s' % '.'.join(str(_) for _ in r) + '/' + str(cdr)
|
|
|
|
while announced:
|
|
- cdr = announced.pop(0)
|
|
+ cdr, announced = announced[0], announced[1:]
|
|
size = cdr_to_length(cdr)
|
|
r = [0,0,0,0]
|
|
for index in range(size):
|
|
- r[index] = announced.pop(0)
|
|
+ r[index], announced = announced[0], announced[1:]
|
|
yield 'announce:%s' % '.'.join(str(_) for _ in r) + '/' + str(cdr)
|
|
|
|
def notification (self, header, body):
|
|
- yield 'notification:%d,%d' % (ord(body[0]),ord(body[1])), bytestream(body)
|
|
+ yield 'notification:%d,%d' % (body[0],body[1]), bytestream(body)
|
|
|
|
def announce (self, *args):
|
|
flushed(' ',self.ip,self.port,' '.join(str(_) for _ in args) if len(args) > 1 else args[0])
|
|
@@ -211,7 +211,7 @@ class BGPHandler(asyncore.dispatcher_with_send):
|
|
return False
|
|
|
|
def read_message (self):
|
|
- header = ''
|
|
+ header = b''
|
|
while len(header) != 19:
|
|
try:
|
|
left = 19-len(header)
|
|
@@ -219,19 +219,19 @@ class BGPHandler(asyncore.dispatcher_with_send):
|
|
if left == 19-len(header): # ugly
|
|
# the TCP session is gone.
|
|
return None,None
|
|
- except socket.error,exc:
|
|
+ except socket.error as exc:
|
|
if exc.args[0] in (errno.EWOULDBLOCK,errno.EAGAIN):
|
|
continue
|
|
raise exc
|
|
|
|
length = unpack('!H',header[16:18])[0] - 19
|
|
|
|
- body = ''
|
|
+ body = b''
|
|
while len(body) != length:
|
|
try:
|
|
left = length-len(body)
|
|
body += self.recv(left)
|
|
- except socket.error,exc:
|
|
+ except socket.error as exc:
|
|
if exc.args[0] in (errno.EWOULDBLOCK,errno.EAGAIN):
|
|
continue
|
|
raise exc
|
|
@@ -241,33 +241,34 @@ class BGPHandler(asyncore.dispatcher_with_send):
|
|
def handle_open (self):
|
|
# reply with a IBGP response with the same capability (just changing routerID)
|
|
header,body = self.read_message()
|
|
- routerid = chr((ord(body[8])+1) & 0xFF)
|
|
+ routerid = bytes([body[8] + 1 & 0xFF])
|
|
o = header+body[:8]+routerid+body[9:]
|
|
|
|
if self.options['send-unknown-capability']:
|
|
# hack capability 66 into the message
|
|
- content = 'loremipsum'
|
|
- cap66 = chr(66) + chr(len(content)) + content
|
|
- param = chr(2) + chr(len(cap66)) + cap66
|
|
- o = o[:17] + chr(ord(o[17])+len(param)) + o[18:28] + \
|
|
- chr(ord(o[28])+len(param)) + o[29:] + param
|
|
|
|
+ content = b'loremipsum'
|
|
+ cap66 = bytes([66,len(content)]) + content
|
|
+ param = bytes([2, len(cap66)]) + cap66
|
|
+ o = o[:17] + bytes([o[17] + len(param)]) + o[18:28] + \
|
|
+ bytes([o[28] + len(param)]) + o[29:] + param
|
|
+
|
|
self.send(o)
|
|
self.send(self.keepalive)
|
|
|
|
if self.options['send-default-route']:
|
|
- self.send(
|
|
- chr(0xFF)*16 +
|
|
- chr(0x00) + chr(0x31) +
|
|
- chr(0x02) +
|
|
- chr(0x00) + chr(0x00) +
|
|
- chr(0x00) + chr(0x15) +
|
|
- '' + chr(0x40) + chr(0x01) + chr(0x01) + chr(0x00) +
|
|
- '' + chr(0x40) + chr(0x02) + chr(0x00) +
|
|
- '' + chr(0x40) + chr(0x03) + chr(0x04) + chr(0x7F) + chr(0x00) + chr(0x00) + chr(0x01) +
|
|
- '' + chr(0x40) + chr(0x05) + chr(0x04) + chr(0x00) + chr(0x00) + chr(0x00) + chr(0x64) +
|
|
- chr(0x20) + chr(0x00) + chr(0x00) + chr(0x00) + chr(0x00)
|
|
- )
|
|
+ self.send(bytes(
|
|
+ [0xFF, ] * 16 +
|
|
+ [0x00, 0x31] +
|
|
+ [0x02,] +
|
|
+ [0x00, 0x00] +
|
|
+ [0x00, 0x15] +
|
|
+ [] + [0x40, 0x01, 0x01, 0x00] +
|
|
+ [] + [0x40, 0x02, 0x00] +
|
|
+ [] + [0x40, 0x03, 0x04, 0x7F, 0x00, 0x00, 0x01] +
|
|
+ [] + [0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x64] +
|
|
+ [0x20, 0x00, 0x00, 0x00, 0x00]
|
|
+ ))
|
|
self.announce('sending default-route\n')
|
|
|
|
self.handle_read = self.handle_keepalive
|
|
@@ -361,19 +362,18 @@ class BGPHandler(asyncore.dispatcher_with_send):
|
|
self.send(self.keepalive)
|
|
|
|
if self.options['send-notification']:
|
|
- notification = 'closing session because we can'
|
|
- self.send(
|
|
- chr(0xFF)*16 +
|
|
- chr(0x00) + chr(19+2+len(notification)) +
|
|
- chr(0x03) +
|
|
- chr(0x06) +
|
|
- chr(0x00) +
|
|
- notification
|
|
- )
|
|
+ notification = b'closing session because we can'
|
|
+ self.send(bytes(
|
|
+ [0xFF,]*16 +
|
|
+ [0x00, 19+2+len(notification)] +
|
|
+ [0x03] +
|
|
+ [0x06] +
|
|
+ [0x00]
|
|
+ ) + notification)
|
|
|
|
_decoder = {
|
|
- chr(2): routes,
|
|
- chr(3): notification,
|
|
+ 2: routes,
|
|
+ 3: notification,
|
|
}
|
|
|
|
|
|
@@ -420,11 +420,11 @@ class BGPServer (asyncore.dispatcher):
|
|
time.sleep(delay)
|
|
self.signal(myself)
|
|
time.sleep(10)
|
|
- thread.exit()
|
|
|
|
# Python 2.6 can not perform this test as it misses the function
|
|
if 'check_output' in dir(subprocess):
|
|
- thread.start_new_thread(notify,(int(message.split(':')[-1]),os.getpid()))
|
|
+ # thread.start_new_thread(notify,(int(message.split(':')[-1]),os.getpid()))
|
|
+ threading.Thread(target=notify, args=(int(message.split(':')[-1]), os.getpid()))
|
|
else:
|
|
self.options['single-shot'] = True
|
|
continue
|
|
@@ -491,7 +491,9 @@ def drop ():
|
|
|
|
|
|
def main ():
|
|
- if len(sys.argv) <= 1:
|
|
+ port = os.environ.get('exabgp.tcp.port', os.environ.get('exabgp_tcp_port', '179'))
|
|
+
|
|
+ if not port.isdigit() and port >0 and port <= 65535 or len(sys.argv) <= 1:
|
|
flushed('--sink accept any BGP messages and reply with a keepalive')
|
|
flushed('--echo accept any BGP messages send it back to the emiter')
|
|
flushed('--port <port> port to bind to')
|
|
@@ -503,7 +505,7 @@ def main ():
|
|
options = {
|
|
'sink': False,
|
|
'echo': False,
|
|
- 'port': os.environ.get('exabgp.tcp.port', os.environ.get('exabgp_tcp_port', '179')),
|
|
+ 'port': int(port),
|
|
'messages': []
|
|
}
|
|
|
|
@@ -542,11 +544,11 @@ def main ():
|
|
BGPServer('::1',options)
|
|
drop()
|
|
asyncore.loop()
|
|
- except socket.error,exc:
|
|
+ except socket.error as exc:
|
|
if exc.errno == errno.EACCES:
|
|
- flushed('failure: could not bind to port %s - most likely not run as root' % PORT)
|
|
+ flushed('failure: could not bind to port %s - most likely not run as root' % port)
|
|
elif exc.errno == errno.EADDRINUSE:
|
|
- flushed('failure: could not bind to port %s - port already in use' % PORT)
|
|
+ flushed('failure: could not bind to port %s - port already in use' % port)
|
|
else:
|
|
flushed('failure', str(exc))
|
|
|