Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test if capability message is received as expected #1222

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion etc/exabgp/conf-hostname.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ neighbor 127.0.0.1 {
router-id 10.0.0.2;
local-address 127.0.0.1;
local-as 65533;
peer-as 65000;
peer-as 65533;
hold-time 180;
host-name my-host-name;
domain-name my-domain-name.com;
Expand Down
1 change: 1 addition & 0 deletions qa/encoding/conf-hostname.ci
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
conf-hostname.conf
2 changes: 2 additions & 0 deletions qa/encoding/conf-hostname.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
option:open:inspect-open-message
1:raw:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:0051:01:04FFFD00B40A000002340206010400010001020641040000FFFD022249200C6D792D686F73742D6E616D65126D792D646F6D61696E2D6E616D652E636F6D
69 changes: 43 additions & 26 deletions qa/sbin/bgp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def flushed(output):


def indent(msg, indent=12):
sys.stdout.write(' '*indent)
sys.stdout.write(' ' * indent)
flushed(msg)


Expand Down Expand Up @@ -68,9 +68,7 @@ def print_payload(prefix, header, body):


def print_rule(prefix, rule):
flushed(
f'{prefix:12}{rule[:32]}:{rule[32:36]}:{rule[36:38]}:{rule[38:]}'
)
flushed(f'{prefix:12}{rule[:32]}:{rule[32:36]}:{rule[36:38]}:{rule[38:]}')


def dump(value):
Expand Down Expand Up @@ -156,22 +154,31 @@ class Message:
@staticmethod
def keepalive():
return bytearray(
[0xFF, ] * 16
[
0xFF,
]
* 16
+ [0x0, 0x13, 0x4]
)

@staticmethod
def eor():
return bytearray(
[0xFF, ] * 16
+ [0x0, 0x17, 0x02] +
+ [0x00, 0x00, 0x00, 0x00]
[
0xFF,
]
* 16
+ [0x0, 0x17, 0x02]
+ +[0x00, 0x00, 0x00, 0x00]
)

@staticmethod
def default_route():
return bytearray(
[0xFF, ] * 16
[
0xFF,
]
* 16
+ [0x00, 0x31]
+ [
0x02,
Expand All @@ -192,7 +199,10 @@ class Message:
@staticmethod
def notify(notification):
return bytearray(
[0xFF, ] * 16
[
0xFF,
]
* 16
+ [0x00, 19 + 2 + len(notification)]
+ [0x03]
+ [0x06]
Expand Down Expand Up @@ -340,14 +350,7 @@ class Message:
offset += param_len + 2

# No "Support for 4 octet AS number capability" found simply replace the 16-bit ASN number field.
open = (
self.header
+ self.body[0:1]
+ pack("!H", asn)
+ self.body[3:8]
+ pack("!H", byte_id)[1:]
+ self.body[9:]
)
open = self.header + self.body[0:1] + pack("!H", asn) + self.body[3:8] + pack("!H", byte_id)[1:] + self.body[9:]
return self._add_capa66(add_capa66, open)


Expand Down Expand Up @@ -408,7 +411,7 @@ class Checker(object):
conn = 'A'
seq = int(prefix)

raw = (encoding == 'raw')
raw = encoding == 'raw'
self.raw = self.raw or raw
if raw:
content = content.replace(':', '')
Expand All @@ -429,7 +432,7 @@ class Checker(object):
return False
if not self.sequences:
return False

self.messages = self.sequences.pop(0)
return self

Expand Down Expand Up @@ -485,7 +488,7 @@ class Checker(object):
return True
flushed('received extra message')
# FIXME: change API to not have to convert
print_payload('additional', msg_bytes(received[:19*2]), msg_bytes(received[19*2:]))
print_payload('additional', msg_bytes(received[: 19 * 2]), msg_bytes(received[19 * 2 :]))
return False

for check in self.messages:
Expand All @@ -502,7 +505,7 @@ class Checker(object):
flushed('')
flushed('unexpected message:')
if self.raw:
print_payload('received', msg_bytes(received[:19*2]), msg_bytes(received[19*2:]))
print_payload('received', msg_bytes(received[: 19 * 2]), msg_bytes(received[19 * 2 :]))
else:
print_prefixed('received', received)

Expand Down Expand Up @@ -553,9 +556,9 @@ class BGPProtocol(asyncio.Protocol):
except ConnectionResetError:
if self.service.checker.completed():
self.service.exit(0)
return '',''
return '', ''
if not header:
return '',''
return '', ''
length = unpack('!H', header[16:18])[0]
body = await self.reader.read(length - 19)
return header, body
Expand Down Expand Up @@ -590,12 +593,23 @@ class BGPProtocol(asyncio.Protocol):
option_asn = self.service.options['asn']
option_capa66 = self.service.options['send-unknown-capability']
option_default = self.service.options['send-default-route']
option_open = self.service.options['inspect-open-message']

open = msg.open(option_asn, option_capa66)
print_payload('open sent', open[:19], open[19:])
self.writer.write(open)
self.writer.write(Message.keepalive())

if option_open:
for announcement in msg.parser(raw=self.service.checker.raw):
if not self.service.checker.expected(announcement, self.writer):
self.service.exit(1)
return FSM.STOP

if self.service.checker.completed():
self.service.exit(0)
return FSM.STOP

self.service.checker.perform_actions_if_required(self.writer)

if option_default:
Expand Down Expand Up @@ -684,6 +698,7 @@ def parse_cmdline():
options = {
'send-unknown-capability': False, # add an unknown capability to the open message
'send-default-route': False, # send a default route to the peer
'inspect-open-message': False, # check for received OPEN message
'asn': None, # Don't modify the local AS per default.
'sink': False, # just accept whatever is sent
'echo': False, # just accept whatever is sent
Expand Down Expand Up @@ -713,6 +728,9 @@ def parse_cmdline():
if message.strip() == 'option:open:send-unknown-capability':
options['send-unknown-capability'] = True
continue
if message.strip() == 'option:open:inspect-open-message':
options['inspect-open-message'] = True
continue
if message.strip() == 'option:update:send-default-route':
options['send-default-route'] = True
continue
Expand Down Expand Up @@ -764,8 +782,7 @@ async def main(options, checker, queue):
service = BGPService(loop, queue, options, checker)

server = await asyncio.start_server(
lambda reader, writer: BGPProtocol(service, reader, writer).handle_bgp(),
sock=sock
lambda reader, writer: BGPProtocol(service, reader, writer).handle_bgp(), sock=sock
)
# perhaps set backlog to 1 ..

Expand Down
Loading