Skip to content

Commit

Permalink
add bgpls tlv
Browse files Browse the repository at this point in the history
Signed-off-by: Peng Xiao <xiaoquwl@gmail.com>
  • Loading branch information
xiaopeng163 committed Jan 15, 2017
1 parent 5938f7d commit 59aee69
Show file tree
Hide file tree
Showing 29 changed files with 652 additions and 11 deletions.
2 changes: 1 addition & 1 deletion yabgp/common/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
BGPTYPE_SAFI_SPECIFIC_ATTR = 19 # draft-kapoor-nalawade-idr-bgp-ssa-00.txt
BGPTYPE_PMSI_TUNNEL = 22 # RFC 6514
BGPTYPE_TUNNEL_ENCAPS_ATTR = 23 # RFC5512
BGPTYPE_LINK_STATE = 99
BGPTYPE_LINK_STATE = 29
BGPTYPE_ATTRIBUTE_SET = 128

# BGP Tunnel Encapsulation Attribute Tunnel Types
Expand Down
34 changes: 34 additions & 0 deletions yabgp/message/__init__.py
Original file line number Diff line number Diff line change
@@ -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.


class TLV(object):
"""TLV basic class
"""
TYPE = -1
TYPE_STR = "UNKNOWN"

def __init__(self, value):
self.value = value

def __str__(self):
return '%s: %s' % (self.TYPE_STR, self.value)

@classmethod
def parse(cls, value):
return cls(value=str(value))

def dict(self):
return {self.TYPE_STR: self.value}
3 changes: 3 additions & 0 deletions yabgp/message/attribute/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class AttributeID(int):
IPv6_Address_Specific_Extended_Community = 0x19 # 25 [RFC5701]
# AIGP = 0x1a # 26 [draft-ietf-idr-aigp](TEMPORARY - expires 2012-03-14)

LINK_STATE = 0x1d
ATTR_SET = 0x80 # 128 [RFC6368]

Unassigned = list(range(27, 127)) + list(range(129, 254))
Expand Down Expand Up @@ -141,6 +142,8 @@ def __str__(self):
return "AS4_PATH"
if self == 0x12:
return "AS4_AGGREGATOR"
if self == 0x1d:
return "LINK_STATE"
if self == 0x0e:
return "MP_REACH_NLRI"
if self == 0x0f:
Expand Down
27 changes: 27 additions & 0 deletions yabgp/message/attribute/linkstate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 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.


from .linkstate import LinkState # noqa

# https://tools.ietf.org/html/rfc7752

from yabgp.message.attribute.linkstate.node.nodename import NodeName # noqa
from yabgp.message.attribute.linkstate.node.isis_area_id import ISISAreaID # noqa
from yabgp.message.attribute.linkstate.node.router_id import RouterID # noqa
from yabgp.message.attribute.linkstate.link.te_metric import TEMetric # noqa
from yabgp.message.attribute.linkstate.link.igp_metric import IGPMetric # noqa
from yabgp.message.attribute.linkstate.prefix.prefix_metric import PrefixMetric # noqa
from yabgp.message.attribute.linkstate.prefix.ospf_forward_addr import OspfForwardingAddr # noqa
Empty file.
47 changes: 47 additions & 0 deletions yabgp/message/attribute/linkstate/link/igp_metric.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 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.message.attribute.linkstate.linkstate import LinkState
from yabgp.message import TLV


# The IGP Metric TLV carries the metric for this link. The length of
# this TLV is variable, depending on the metric width of the underlying
# protocol. IS-IS small metrics have a length of 1 octet (the two most
# significant bits are ignored). OSPF link metrics have a length of 2
# octets. IS-IS wide metrics have a length of 3 octets.
#
# 0 1 2 3
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | Type | Length |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# // IGP Link Metric (variable length) //
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


@LinkState.register()
class IGPMetric(TLV):

TYPE = 1095
TYPE_STR = "igp-link-metric"

@classmethod
def parse(cls, value):
"""
"""
return cls(value=int(binascii.b2a_hex(value), 16))
32 changes: 32 additions & 0 deletions yabgp/message/attribute/linkstate/link/te_metric.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 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.message.attribute.linkstate.linkstate import LinkState
from yabgp.message import TLV


@LinkState.register()
class TEMetric(TLV):

TYPE = 1092
TYPE_STR = "te-default-metric"

@classmethod
def parse(cls, value):
"""
"""
return cls(value=struct.unpack('!L', value)[0])
70 changes: 70 additions & 0 deletions yabgp/message/attribute/linkstate/linkstate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# 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

from yabgp.message.attribute import Attribute
from yabgp.message.attribute import AttributeFlag
from yabgp.message.attribute import AttributeID
from yabgp.message import TLV


class LinkState(Attribute):
"""
The BGP-LS attribute is an optional, non-transitive BGP attribute
that is used to carry link, node, and prefix parameters and
attributes. It is defined as a set of Type/Length/Value (TLV)
triplets, described in the following section. This attribute SHOULD
only be included with Link-State NLRIs. This attribute MUST be
ignored for all other address families."""

ID = AttributeID.LINK_STATE
ID_STR = str(AttributeID(ID))
FLAG = AttributeFlag.OPTIONAL

registered_tlvs = {}

def __init__(self, ls_tlvs):
self.ls_tlvs = ls_tlvs

@classmethod
def register(cls, typecode=None, typestr=None):
def decorator(klass):
if typecode:
klass.TYPE = typecode
if typestr:
klass.TYPE_STR = typestr
cls.registered_tlvs[klass.TYPE] = klass
return klass

return decorator

@classmethod
def parse(cls, value):
ls_tlvs = []
while value:
type_code, length = struct.unpack('!HH', value[:4])
if type_code in cls.registered_tlvs:
klass = cls.registered_tlvs[type_code].parse(value[4:length + 4])
else:
klass = TLV(value=value[4:length + 4])
klass.TLV = type_code
ls_tlvs.append(klass)
value = value[length + 4:]

return cls(ls_tlvs=ls_tlvs)

def dict(self):
return {self.ID: [tlv.dict() for tlv in self.ls_tlvs]}
Empty file.
32 changes: 32 additions & 0 deletions yabgp/message/attribute/linkstate/node/isis_area_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 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.message.attribute.linkstate.linkstate import LinkState
from yabgp.message import TLV


@LinkState.register()
class ISISAreaID(TLV):

TYPE = 1027
TYPE_STR = "isis-area-id"

@classmethod
def parse(cls, value):
"""
"""
return cls(value='0x%s' % binascii.b2a_hex(value))
31 changes: 31 additions & 0 deletions yabgp/message/attribute/linkstate/node/nodename.py
Original file line number Diff line number Diff line change
@@ -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.message.attribute.linkstate.linkstate import LinkState
from yabgp.message import TLV


@LinkState.register()
class NodeName(TLV):

TYPE = 1026
TYPE_STR = "node-name"

@classmethod
def parse(cls, value):
"""
"""
nodename = value.decode('ascii')
return cls(value=nodename)
33 changes: 33 additions & 0 deletions yabgp/message/attribute/linkstate/node/router_id.py
Original file line number Diff line number Diff line change
@@ -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.message.attribute.linkstate.linkstate import LinkState
from yabgp.message import TLV

import netaddr


@LinkState.register(typecode=1028, typestr='local-router-id')
@LinkState.register(typecode=1029, typestr='local-router-id')
@LinkState.register(typecode=1030, typestr='remote-router-id')
@LinkState.register(typecode=1031, typestr='remote-router-id')
class RouterID(TLV):
""" Router ID
"""
@classmethod
def parse(cls, value):
return cls(value=str(netaddr.IPAddress(int(binascii.b2a_hex(value), 16))))
Empty file.
34 changes: 34 additions & 0 deletions yabgp/message/attribute/linkstate/prefix/ospf_forward_addr.py
Original file line number Diff line number Diff line change
@@ -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 binascii

from yabgp.message.attribute.linkstate.linkstate import LinkState
from yabgp.message import TLV

import netaddr


@LinkState.register()
class OspfForwardingAddr(TLV):

TYPE = 1156
TYPE_STR = "ospf-forwarding-address"

@classmethod
def parse(cls, value):
"""
"""
return cls(value=str(netaddr.IPAddress(int(binascii.b2a_hex(value), 16))))
Loading

0 comments on commit 59aee69

Please sign in to comment.