From 90a42b4826f411e74bbac06e16c082a1dd91d88f Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Thu, 4 May 2017 10:33:41 +0800 Subject: [PATCH] more tlvs for bgpls Signed-off-by: Peng Xiao --- yabgp/message/attribute/linkstate.py | 67 ------------------- yabgp/message/attribute/linkstate/__init__.py | 27 ++++++++ .../attribute/linkstate/link/__init__.py | 34 ++++++++++ .../attribute/linkstate/link/admingroup.py | 33 +++++++++ .../attribute/linkstate/link/igp_metric.py | 38 +++++++++++ .../attribute/linkstate/link/link_name.py | 33 +++++++++ .../attribute/linkstate/link/max_bw.py | 33 +++++++++ .../attribute/linkstate/link/max_rsv_bw.py | 33 +++++++++ .../linkstate/link/remote_router_id.py | 33 +++++++++ .../attribute/linkstate/link/te_metric.py | 33 +++++++++ .../attribute/linkstate/link/unsrv_bw.py | 34 ++++++++++ .../message/attribute/linkstate/linkstate.py | 67 +++++++++++++++++++ .../attribute/linkstate/node/__init__.py | 23 +++++++ .../attribute/linkstate/node/isisarea.py | 33 +++++++++ .../linkstate/node/local_router_id.py | 33 +++++++++ .../message/attribute/linkstate/node/name.py | 31 +++++++++ yabgp/message/update.py | 4 ++ yabgp/net/__init__.py | 31 +++++++++ .../attribute/linkstate/test_linkstate.py | 33 +++++++++ yabgp/tests/unit/message/test_update.py | 2 +- yabgp/tlv.py | 44 ++++++++++++ 21 files changed, 631 insertions(+), 68 deletions(-) delete mode 100644 yabgp/message/attribute/linkstate.py create mode 100644 yabgp/message/attribute/linkstate/__init__.py create mode 100644 yabgp/message/attribute/linkstate/link/__init__.py create mode 100644 yabgp/message/attribute/linkstate/link/admingroup.py create mode 100644 yabgp/message/attribute/linkstate/link/igp_metric.py create mode 100644 yabgp/message/attribute/linkstate/link/link_name.py create mode 100644 yabgp/message/attribute/linkstate/link/max_bw.py create mode 100644 yabgp/message/attribute/linkstate/link/max_rsv_bw.py create mode 100644 yabgp/message/attribute/linkstate/link/remote_router_id.py create mode 100644 yabgp/message/attribute/linkstate/link/te_metric.py create mode 100644 yabgp/message/attribute/linkstate/link/unsrv_bw.py create mode 100644 yabgp/message/attribute/linkstate/linkstate.py create mode 100644 yabgp/message/attribute/linkstate/node/__init__.py create mode 100644 yabgp/message/attribute/linkstate/node/isisarea.py create mode 100644 yabgp/message/attribute/linkstate/node/local_router_id.py create mode 100644 yabgp/message/attribute/linkstate/node/name.py create mode 100644 yabgp/net/__init__.py create mode 100644 yabgp/tests/unit/message/attribute/linkstate/test_linkstate.py create mode 100644 yabgp/tlv.py diff --git a/yabgp/message/attribute/linkstate.py b/yabgp/message/attribute/linkstate.py deleted file mode 100644 index 44b2467..0000000 --- a/yabgp/message/attribute/linkstate.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2015 Cisco Systems, Inc. -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import struct -import binascii - -from yabgp.message.attribute import Attribute -from yabgp.message.attribute import AttributeID -from yabgp.message.attribute import AttributeFlag - - -class LinkState(Attribute): - """BGP Link State - """ - - ID = AttributeID.LINKSTATE - FLAG = AttributeFlag.OPTIONAL - MULTIPLE = False - - MUTI_TOPO_ID = 263 - NODE_FLAG = 1024 - OPA_NODE = 1025 - NODE_NAME = 1026 - ISIS_AREA_ID = 1027 - IPV4_ROUTER_ID = 1028 - IPV6_ROUTER_ID = 1029 - - @classmethod - def parse(cls, value): - - """ - parse linkstate - :param value: raw binary value - """ - value_dict = dict() - while value: - _type, _len = struct.unpack('!HH', value[0:2]) - _value = value[2: 2+_len] - - if _type == cls.NODE_NAME: - value_dict[_type] = _value.decode('ascii') - - else: - value_dict[_type] = binascii.b2a_hex(_value) - - value = value[3+_len:] - - return value_dict - - @classmethod - def construct(cls, value): - """ - :param value: interger value - """ - pass diff --git a/yabgp/message/attribute/linkstate/__init__.py b/yabgp/message/attribute/linkstate/__init__.py new file mode 100644 index 0000000..b9c3fa8 --- /dev/null +++ b/yabgp/message/attribute/linkstate/__init__.py @@ -0,0 +1,27 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from .linkstate import LinkState # noqa +from .node.local_router_id import LocalRouterID # noqa +from .node.name import NodeName # noqa +from .node.isisarea import ISISArea # noqa +from .link.admingroup import AdminGroup # noqa +from .link.remote_router_id import RemoteRouterID # noqa +from .link.max_bw import MaxBandwidth # noqa +from .link.max_rsv_bw import MaxResvBandwidth # noqa +from .link.unsrv_bw import UnrsvBandwidth # noqa +from .link.te_metric import TeMetric # noqa +from .link.link_name import LinkName # noqa +from .link.igp_metric import IGPMetric # noqa diff --git a/yabgp/message/attribute/linkstate/link/__init__.py b/yabgp/message/attribute/linkstate/link/__init__.py new file mode 100644 index 0000000..8685f22 --- /dev/null +++ b/yabgp/message/attribute/linkstate/link/__init__.py @@ -0,0 +1,34 @@ +# # +# +-----------+---------------------+--------------+------------------+ +# | TLV Code | Description | IS-IS TLV | Reference | +# | Point | | /Sub-TLV | (RFC/Section) | +# +-----------+---------------------+--------------+------------------+ +# | 1028 | IPv4 Router-ID of | 134/--- | [RFC5305]/4.3 | +# | | Local Node | | | +# | 1029 | IPv6 Router-ID of | 140/--- | [RFC6119]/4.1 | +# | | Local Node | | | +# | 1030 | IPv4 Router-ID of | 134/--- | [RFC5305]/4.3 | +# | | Remote Node | | | +# | 1031 | IPv6 Router-ID of | 140/--- | [RFC6119]/4.1 | +# | | Remote Node | | | +# | 1088 | Administrative | 22/3 | [RFC5305]/3.1 | +# | | group (color) | | | +# | 1089 | Maximum link | 22/9 | [RFC5305]/3.4 | +# | | bandwidth | | | +# | 1090 | Max. reservable | 22/10 | [RFC5305]/3.5 | +# | | link bandwidth | | | +# | 1091 | Unreserved | 22/11 | [RFC5305]/3.6 | +# | | bandwidth | | | +# | 1092 | TE Default Metric | 22/18 | Section 3.3.2.3 | +# | 1093 | Link Protection | 22/20 | [RFC5307]/1.2 | +# | | Type | | | +# | 1094 | MPLS Protocol Mask | --- | Section 3.3.2.2 | +# | 1095 | IGP Metric | --- | Section 3.3.2.4 | +# | 1096 | Shared Risk Link | --- | Section 3.3.2.5 | +# | | Group | | | +# | 1097 | Opaque Link | --- | Section 3.3.2.6 | +# | | Attribute | | | +# | 1098 | Link Name | --- | Section 3.3.2.7 | +# +-----------+---------------------+--------------+------------------+ + +# Table 9: Link Attribute TLVs diff --git a/yabgp/message/attribute/linkstate/link/admingroup.py b/yabgp/message/attribute/linkstate/link/admingroup.py new file mode 100644 index 0000000..3a55165 --- /dev/null +++ b/yabgp/message/attribute/linkstate/link/admingroup.py @@ -0,0 +1,33 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import binascii + +from yabgp.tlv import TLV +from ..linkstate import LinkState + + +@LinkState.register() +class AdminGroup(TLV): + """ + admin group + """ + TYPE = 1088 + TYPE_STR = 'admin-group' + + @classmethod + def unpack(cls, data): + + return cls(value=int(binascii.b2a_hex(data), 16)) diff --git a/yabgp/message/attribute/linkstate/link/igp_metric.py b/yabgp/message/attribute/linkstate/link/igp_metric.py new file mode 100644 index 0000000..a2f1718 --- /dev/null +++ b/yabgp/message/attribute/linkstate/link/igp_metric.py @@ -0,0 +1,38 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import struct +import binascii + +from yabgp.tlv import TLV +from ..linkstate import LinkState + + +@LinkState.register() +class IGPMetric(TLV): + """ + IGP Metric + """ + TYPE = 1095 + TYPE_STR = 'igp-metric' + + @classmethod + def unpack(cls, data): + if len(data) == 2: + return cls(value=struct.unpack('!H', data)[0]) + elif len(data) == 1: + return cls(value=struct.unpack('!B', data)[0]) + elif len(data) == 3: + return cls(value=int(binascii.b2a_hex(data), 16)) diff --git a/yabgp/message/attribute/linkstate/link/link_name.py b/yabgp/message/attribute/linkstate/link/link_name.py new file mode 100644 index 0000000..b276ee5 --- /dev/null +++ b/yabgp/message/attribute/linkstate/link/link_name.py @@ -0,0 +1,33 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import binascii + +from yabgp.tlv import TLV +from ..linkstate import LinkState + + +@LinkState.register() +class LinkName(TLV): + """ + link name + """ + TYPE = 1098 + TYPE_STR = 'link-name' + + @classmethod + def unpack(cls, data): + + return cls(value=binascii.b2a_uu(data)) diff --git a/yabgp/message/attribute/linkstate/link/max_bw.py b/yabgp/message/attribute/linkstate/link/max_bw.py new file mode 100644 index 0000000..dc69004 --- /dev/null +++ b/yabgp/message/attribute/linkstate/link/max_bw.py @@ -0,0 +1,33 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import struct + +from yabgp.tlv import TLV +from ..linkstate import LinkState + + +@LinkState.register() +class MaxBandwidth(TLV): + """ + max bandwidth + """ + TYPE = 1089 + TYPE_STR = 'max-bandwidth' + + @classmethod + def unpack(cls, data): + + return cls(value=struct.unpack('!f', data)[0]) diff --git a/yabgp/message/attribute/linkstate/link/max_rsv_bw.py b/yabgp/message/attribute/linkstate/link/max_rsv_bw.py new file mode 100644 index 0000000..cf32643 --- /dev/null +++ b/yabgp/message/attribute/linkstate/link/max_rsv_bw.py @@ -0,0 +1,33 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import struct + +from yabgp.tlv import TLV +from ..linkstate import LinkState + + +@LinkState.register() +class MaxResvBandwidth(TLV): + """ + max reserved bandwidth + """ + TYPE = 1090 + TYPE_STR = 'max-rsv-bandwidth' + + @classmethod + def unpack(cls, data): + + return cls(value=struct.unpack('!f', data)[0]) diff --git a/yabgp/message/attribute/linkstate/link/remote_router_id.py b/yabgp/message/attribute/linkstate/link/remote_router_id.py new file mode 100644 index 0000000..03ebd56 --- /dev/null +++ b/yabgp/message/attribute/linkstate/link/remote_router_id.py @@ -0,0 +1,33 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from yabgp.tlv import TLV +from yabgp.net import IPAddress +from ..linkstate import LinkState + + +@LinkState.register(_type=1030) +@LinkState.register(_type=1031) +class RemoteRouterID(TLV): + """ + remote ipv4 or ipv6 router id + """ + TYPE_STR = 'remote-router-id' + + @classmethod + def unpack(cls, data): + + router_id = IPAddress.unpack(data) + return cls(value=router_id) diff --git a/yabgp/message/attribute/linkstate/link/te_metric.py b/yabgp/message/attribute/linkstate/link/te_metric.py new file mode 100644 index 0000000..bf041ef --- /dev/null +++ b/yabgp/message/attribute/linkstate/link/te_metric.py @@ -0,0 +1,33 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import struct + +from yabgp.tlv import TLV +from ..linkstate import LinkState + + +@LinkState.register() +class TeMetric(TLV): + """ + TE metric + """ + TYPE = 1092 + TYPE_STR = 'te-metric' + + @classmethod + def unpack(cls, data): + + return cls(value=struct.unpack('!L', data)[0]) diff --git a/yabgp/message/attribute/linkstate/link/unsrv_bw.py b/yabgp/message/attribute/linkstate/link/unsrv_bw.py new file mode 100644 index 0000000..fdbf99e --- /dev/null +++ b/yabgp/message/attribute/linkstate/link/unsrv_bw.py @@ -0,0 +1,34 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import struct + +from yabgp.tlv import TLV +from ..linkstate import LinkState + + +@LinkState.register() +class UnrsvBandwidth(TLV): + """ + un reserved bandwidth + """ + TYPE = 1091 + TYPE_STR = 'unrsv-bandwidth' + + @classmethod + def unpack(cls, data): + + value = [p for p in struct.unpack('!ffffffff', data)] + return cls(value=value) diff --git a/yabgp/message/attribute/linkstate/linkstate.py b/yabgp/message/attribute/linkstate/linkstate.py new file mode 100644 index 0000000..7c0aa66 --- /dev/null +++ b/yabgp/message/attribute/linkstate/linkstate.py @@ -0,0 +1,67 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import struct +import binascii + +from yabgp.message.attribute import Attribute, AttributeFlag, AttributeID + + +class LinkState(Attribute): + """BGP linksate attribute + """ + ID = AttributeID.LINKSTATE + FLAG = AttributeFlag.OPTIONAL + + registered_tlvs = dict() + + def __init__(self, value, hex_value=None): + self.value = value + self.hex_value = hex_value + + @classmethod + def register(cls, _type=None): + """register tlvs + """ + def decorator(klass): + """decorator + """ + _id = klass.TYPE if _type is None else _type + if _id in cls.registered_tlvs: + raise RuntimeError('duplicated attribute type') + cls.registered_tlvs[_id] = klass + return klass + return decorator + + def dict(self): + """return dict + """ + return {self.ID: self.value} + + @classmethod + def unpack(cls, data): + """unpack binary data + """ + tlvs = dict() + while data: + type_code, length = struct.unpack('!HH', data[:4]) + value = data[4: 4+length] + if type_code in cls.registered_tlvs: + tlvs.update(cls.registered_tlvs[type_code].unpack(value).dict()) + else: + tlvs[type_code] = binascii.b2a_hex(value) + data = data[4+length:] + + return cls(value=tlvs) diff --git a/yabgp/message/attribute/linkstate/node/__init__.py b/yabgp/message/attribute/linkstate/node/__init__.py new file mode 100644 index 0000000..2ea593b --- /dev/null +++ b/yabgp/message/attribute/linkstate/node/__init__.py @@ -0,0 +1,23 @@ +# 3.3.1. Node Attribute TLVs + +# Node attribute TLVs are the TLVs that may be encoded in the BGP-LS +# attribute with a Node NLRI. The following Node Attribute TLVs are +# defined: + +# +-------------+----------------------+----------+-------------------+ +# | TLV Code | Description | Length | Reference | +# | Point | | | (RFC/Section) | +# +-------------+----------------------+----------+-------------------+ +# | 263 | Multi-Topology | variable | Section 3.2.1.5 | +# | | Identifier | | | +# | 1024 | Node Flag Bits | 1 | Section 3.3.1.1 | +# | 1025 | Opaque Node | variable | Section 3.3.1.5 | +# | | Attribute | | | +# | 1026 | Node Name | variable | Section 3.3.1.3 | +# | 1027 | IS-IS Area | variable | Section 3.3.1.2 | +# | | Identifier | | | +# | 1028 | IPv4 Router-ID of | 4 | [RFC5305]/4.3 | +# | | Local Node | | | +# | 1029 | IPv6 Router-ID of | 16 | [RFC6119]/4.1 | +# | | Local Node | | | +# +-------------+----------------------+----------+-------------------+ diff --git a/yabgp/message/attribute/linkstate/node/isisarea.py b/yabgp/message/attribute/linkstate/node/isisarea.py new file mode 100644 index 0000000..548ee2b --- /dev/null +++ b/yabgp/message/attribute/linkstate/node/isisarea.py @@ -0,0 +1,33 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import binascii + +from yabgp.tlv import TLV +from ..linkstate import LinkState + + +@LinkState.register() +class ISISArea(TLV): + """ + isis area id + """ + TYPE = 1027 + TYPE_STR = 'isis-area' + + @classmethod + def unpack(cls, data): + + return cls(value=int(binascii.b2a_hex(data), 16)) diff --git a/yabgp/message/attribute/linkstate/node/local_router_id.py b/yabgp/message/attribute/linkstate/node/local_router_id.py new file mode 100644 index 0000000..717b012 --- /dev/null +++ b/yabgp/message/attribute/linkstate/node/local_router_id.py @@ -0,0 +1,33 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from yabgp.tlv import TLV +from yabgp.net import IPAddress +from ..linkstate import LinkState + + +@LinkState.register(_type=1028) +@LinkState.register(_type=1029) +class LocalRouterID(TLV): + """ + local ipv4 or ipv6 router id + """ + TYPE_STR = 'local-router-id' + + @classmethod + def unpack(cls, data): + + router_id = IPAddress.unpack(data) + return cls(value=router_id) diff --git a/yabgp/message/attribute/linkstate/node/name.py b/yabgp/message/attribute/linkstate/node/name.py new file mode 100644 index 0000000..01ab617 --- /dev/null +++ b/yabgp/message/attribute/linkstate/node/name.py @@ -0,0 +1,31 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from yabgp.tlv import TLV +from ..linkstate import LinkState + + +@LinkState.register() +class NodeName(TLV): + """ + node name + """ + TYPE = 1026 + TYPE_STR = 'node-name' + + @classmethod + def unpack(cls, data): + + return cls(value=data.decode('ascii')) diff --git a/yabgp/message/update.py b/yabgp/message/update.py index f0af55a..5c77602 100644 --- a/yabgp/message/update.py +++ b/yabgp/message/update.py @@ -39,6 +39,7 @@ from yabgp.message.attribute.mpunreachnlri import MpUnReachNLRI from yabgp.message.attribute.extcommunity import ExtCommunity from yabgp.message.attribute.pmsitunnel import PMSITunnel +from yabgp.message.attribute.linkstate.linkstate import LinkState LOG = logging.getLogger() @@ -368,6 +369,9 @@ def parse_attributes(data, asn4=False): decode_value = ExtCommunity.parse(value=attr_value) elif type_code == bgp_cons.BGPTYPE_PMSI_TUNNEL: decode_value = PMSITunnel.parse(value=attr_value) + elif type_code == bgp_cons.BGPTYPE_LINK_STATE: + attributes.update(LinkState.unpack(data=attr_value).dict()) + continue else: decode_value = binascii.b2a_hex(attr_value) attributes[type_code] = decode_value diff --git a/yabgp/net/__init__.py b/yabgp/net/__init__.py new file mode 100644 index 0000000..28fb315 --- /dev/null +++ b/yabgp/net/__init__.py @@ -0,0 +1,31 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import socket + + +class IPAddress(object): + + @staticmethod + def unpack(data): + return socket.inet_ntop(socket.AF_INET if len(data) == 4 else socket.AF_INET6, data) + + @staticmethod + def pack(data): + return socket.inet_pton(socket.AF_INET if len(data.split('.')) == 4 else socket.AF_INET6, data) + + +class IPNetwork(object): + pass diff --git a/yabgp/tests/unit/message/attribute/linkstate/test_linkstate.py b/yabgp/tests/unit/message/attribute/linkstate/test_linkstate.py new file mode 100644 index 0000000..fcd1d29 --- /dev/null +++ b/yabgp/tests/unit/message/attribute/linkstate/test_linkstate.py @@ -0,0 +1,33 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" Test Link State attribute""" + +import unittest +from yabgp.message.attribute.linkstate.linkstate import LinkState + + +class TestLinkState(unittest.TestCase): + + def test_unpack(self): + data_bin = b'\x04\x04\x00\x04\x02\x02\x02\x02\x04\x06\x00\x04\x01\x01\x01\x01' \ + b'\x04\x40\x00\x04\x00\x00\x00\x00\x04\x41\x00\x04\x4c\xee\x6b\x28' \ + b'\x04\x42\x00\x04\x00\x00\x00\x00\x04\x43\x00\x20\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x44\x00\x04' \ + b'\x00\x00\x00\x0a\x04\x47\x00\x03\x00\x00\x0a\x04\x4b\x00\x07\x70' \ + b'\x00\x00\x00\x00\x61\xa8\x04\x4b\x00\x07\x30\x00\x00\x00\x00\x61' \ + b'\xa9' + self.assertEqual(None, LinkState.unpack(data_bin).dict()) diff --git a/yabgp/tests/unit/message/test_update.py b/yabgp/tests/unit/message/test_update.py index e04e199..a69d758 100644 --- a/yabgp/tests/unit/message/test_update.py +++ b/yabgp/tests/unit/message/test_update.py @@ -246,7 +246,7 @@ def test_parse_link_state(self): 'nlri': [{'type': 'link', 'value': [{'type': 'link_local_ipv4', 'value': '1.3.0.1'}, {'type': 'link_remote_ipv4', 'value': '1.3.0.2'}]}]}, - 29: b'044400040000000a0447000300000a044b0007700000000061aa044b0007300000000061ab'} + 29: {1099: b'300000000061ab', 'igp-metric': 10, 'te-metric': 10}} self.assertEqual(data_dict, Update.parse(None, data_bin[HDR_LEN:])['attr']) if __name__ == '__main__': diff --git a/yabgp/tlv.py b/yabgp/tlv.py new file mode 100644 index 0000000..d4e5e5f --- /dev/null +++ b/yabgp/tlv.py @@ -0,0 +1,44 @@ +# Copyright 2015-2017 Cisco Systems, Inc. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import binascii + + +class TLV(object): + """TLV basic class + """ + TYPE = -1 + TYPE_STR = "UNKNOWN" + + __slots__ = ['value'] + + def __init__(self, value): + self.value = value + + def __str__(self): + return '%s: %s' % (self.TYPE_STR, self.value) + + @classmethod + def unpack(cls, value): + """unpack binary data + """ + return cls(value=binascii.b2a_hex(value)) + + def dict(self, str_key=True): + """return dict format + """ + if str_key: + return {self.TYPE_STR: self.value} + return {self.TYPE: self.value}