Skip to content

Commit

Permalink
add sr te sub tlv (#104)
Browse files Browse the repository at this point in the history
* update sr sub tlv

* unit test tunnelencaps

* update msg format
  • Loading branch information
zlpqingmei authored and meidli committed Sep 12, 2019
1 parent 0646030 commit 7609409
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 6 deletions.
10 changes: 9 additions & 1 deletion doc/source/msg_format.rst
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,11 @@ IPv4 Sr-policy
"16": ["route-target:10.75.195.199:00"],
"23": {
"0": "new",
"6": {"asn":400,"afi":"ipv4","address": "1.1.1.1"},
"12": 100,
"13": 25102,
"14": 1,
"15": 23,
"128": [
{
"9": 10,
Expand All @@ -473,7 +476,8 @@ IPv4 Sr-policy
}
]
}
]
],
"129": "policy_test",
}
}
}
Expand All @@ -488,8 +492,11 @@ attribute explaination(only for this format):
"0": if the ios version lower than 6.4.1.14(Cisco facility), the value should be 'old', and in the meantime,
the key of Preference should be '6', key of Binding SID should be '7', else it should be 'new' and key
of Preference and Binding SID should be '12' and '13'
"6": RemoteEndpoint
"6"/"12": Preference
"7"/"13": Binding SID
"14": ELNP
"15": Priority
"128": Multiple segement lists
"9": Weighted
"1": Segement list
Expand All @@ -501,6 +508,7 @@ attribute explaination(only for this format):
"3": Segement type 3
"node": An Ipv4 Address
"SID": Assign Optionally, inner structure similar to Segement type 1
"129": Policy name

IPv6 Unicast
""""""""""""
Expand Down
2 changes: 1 addition & 1 deletion yabgp/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,4 +277,4 @@ def update_send_version(peer_ip, attr, nlri, withdraw):
:param withdraw:
:return:
"""
cfg.CONF.bgp.running_config['factory'].fsm.protocol.update_send_verion(peer_ip, attr, nlri, withdraw)
cfg.CONF.bgp.running_config['factory'].fsm.protocol.update_send_version(peer_ip, attr, nlri, withdraw)
4 changes: 4 additions & 0 deletions yabgp/common/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,14 @@
# Sub-TLVs as defined in SR TE Policy draft
BGP_BSID_PREFERENCE_OLD_OR_NEW = 0
BGPSUB_TLV_PREFERENCE = 6
BGPSUB_TLV_REMOTEENDPOINT_NEW = 6
BGPSUB_TLV_BINDGINGSID = 7
BGPSUB_TLV_PREFERENCE_NEW = 12
BGPSUB_TLV_BINDGINGSID_NEW = 13
BGPSUB_TLV_ENLP_NEW = 14
BGPSUB_TLV_PRIORITY_NEW = 15
BGPSUB_TLV_SIDLIST = 128
BGPSUB_TLV_POLICYNAME_NEW = 129

# Sub-TLVs as defined in SR TE Policy draft and used in BGPSUB_TLV_SIDLIST
BGPSUB_TLV_WEIGHTED = 9
Expand Down
2 changes: 1 addition & 1 deletion yabgp/core/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ def ip_longest_match(self, prefix_ip):
}
return results

def update_send_verion(self, peer_ip, attr, nlri, withdraw):
def update_send_version(self, peer_ip, attr, nlri, withdraw):
if 14 in attr:
if attr[14]['afi_safi'] == [1, 133]:
LOG.info("send flowspec")
Expand Down
41 changes: 38 additions & 3 deletions yabgp/message/attribute/tunnelencaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

"""BGP Attribute MP_REACH_NLRI
"""

import struct

import netaddr
Expand Down Expand Up @@ -210,9 +211,10 @@ def construct(cls, value):
if bgp_cons.BGPSUB_TLV_PREFERENCE_NEW in items:
policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE_NEW) + struct.pack('!B', 6) + \
b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE_NEW])
else:
policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE_NEW) + struct.pack('!B', 6) + \
b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE])
# else:
# policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PREFERENCE_NEW) + \
# struct.pack('!B', 6) + b'\x00\x00' \
# + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_PREFERENCE])
# Binding SID Sub-TLV
if bgp_cons.BGPSUB_TLV_BINDGINGSID not in items:
if bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW not in items:
Expand All @@ -224,6 +226,39 @@ def construct(cls, value):
else:
policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_BINDGINGSID_NEW) + struct.pack('!B', 6) +\
b'\x00\x00' + struct.pack('!I', data[bgp_cons.BGPSUB_TLV_BINDGINGSID] << 12)
# Explicit NULL Label Policy Sub-TLV
if bgp_cons.BGPSUB_TLV_ENLP_NEW in items:
policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_ENLP_NEW) + struct.pack('!B', 3) + \
b'\x00\x00' + struct.pack('!B', data[bgp_cons.BGPSUB_TLV_ENLP_NEW])
# Policy Priority Sub-TLV
if bgp_cons.BGPSUB_TLV_PRIORITY_NEW in items:
policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_PRIORITY_NEW) + struct.pack('!B', 2) + \
struct.pack('!B', data[bgp_cons.BGPSUB_TLV_PRIORITY_NEW]) + b'\x00'
# Policy Name Sub-TLV
if bgp_cons.BGPSUB_TLV_POLICYNAME_NEW in items:
length = len(data[bgp_cons.BGPSUB_TLV_POLICYNAME_NEW]) + 1
policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_POLICYNAME_NEW) + struct.pack('!H', length) + \
b'\x00' + str(data[bgp_cons.BGPSUB_TLV_POLICYNAME_NEW]).encode('ascii')
# 3.1. The Remote Endpoint Sub-TLV:
if bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW in items:
asn = data[bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW].get('asn')
af = data[bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW].get('afi')
address = data[bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW].get('address')
if af == 'ipv4':
length = 10
af_value = 1
elif af == 'ipv6':
length = 22
af_value = 2
else:
raise excep.ConstructAttributeFailed(
reason='failed to construct attributes: %s' % 'remote endpoint address family'
' is ipv4 or ipv6',
data={}
)
policy_value_hex += struct.pack('!B', bgp_cons.BGPSUB_TLV_REMOTEENDPOINT_NEW) + struct.pack('!B', length) \
+ struct.pack('!I', asn) + struct.pack('!H', af_value) + netaddr.IPAddress(address).packed

else:
raise excep.ConstructAttributeFailed(
reason='failed to construct attributes: %s' % 'TLV encoding must be one value of new or old',
Expand Down
42 changes: 42 additions & 0 deletions yabgp/tests/unit/message/attribute/test_tunnelencaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,47 @@ def test_construct_segement_lists(self):
b'\x00\x00\x7d\x00\xff\x03\x0a\x00\x00\x0a\x01\x01\x01\x00\x7d\x00\xff'
self.assertTrue(TunnelEncaps.construct(data_dict)[8:] in [data_hex_1, data_hex_2])

def test_construct_enlp(self):
data_dict = {
"0": "new",
"14": 1
}
data_hex = b'\x0e\x03\x00\x00\x01'
self.assertEqual(data_hex, TunnelEncaps.construct(data_dict)[12:])

def test_construct_priority(self):
data_dict = {
"0": "new",
"15": 200
}
data_hex = data_hex = b'\x0f\x02\xc8\x00'
self.assertEqual(data_hex, TunnelEncaps.construct(data_dict)[12:])

def test_construct_policy_name(self):
data_dict = {
"0": "new",
"129": "test"
}
data_hex = data_hex = b'\x81\x00\x05\x00\x74\x65\x73\x74'
self.assertEqual(data_hex, TunnelEncaps.construct(data_dict)[12:])

def test_construct_remote_endpoint_ipv4(self):
data_dict = {
"0": "new",
"6": {"asn": 300, 'afi': 'ipv4', 'address': '1.1.1.1'}
}
data_hex = b'\x06\x0a\x00\x00\x01\x2c\x00\x01\x01\x01\x01\x01'
self.assertEqual(data_hex, TunnelEncaps.construct(data_dict)[12:])

def test_construct_remote_endpoint_ipv6(self):
data_dict = {
"0": "new",
"6": {"asn": 300, 'afi': 'ipv6', 'address': 'ABCD:EF01:2345:6789:ABCD:EF01:2345:6789'}
}
data_hex = b'\x06\x16\x00\x00\x01\x2c\x00\x02\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef' \
b'\x01\x23\x45\x67\x89'
self.assertEqual(data_hex, TunnelEncaps.construct(data_dict)[12:])


if __name__ == '__main__':
unittest.main()

0 comments on commit 7609409

Please sign in to comment.