Skip to content

Commit

Permalink
close rib (#98)
Browse files Browse the repository at this point in the history
* close rib

* attr 14 ipv4 unicast
  • Loading branch information
zlpqingmei authored and meidli committed Jul 10, 2019
1 parent c188649 commit d32cd5a
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 45 deletions.
4 changes: 2 additions & 2 deletions yabgp/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@
help='The Global config for address family and sub address family'),
cfg.BoolOpt(
'rib',
default=True,
help='maintain rib in or not, default is True'
default=False,
help='maintain rib in or not, default is False'
)
]

Expand Down
47 changes: 4 additions & 43 deletions yabgp/core/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ def closeConnection(self):
self.disconnected = True

def _update_received(self, timestamp, msg):
# if self.msg_recv_stat['Updates'] % 1000 == 0:
# LOG.info(self.msg_recv_stat['Updates'])
# LOG.info(time.time())

"""Called when a BGP Update message was received."""
result = Update().parse(
Expand Down Expand Up @@ -297,7 +300,7 @@ def _update_received(self, timestamp, msg):
# try to update bgp rib in
if msg.get('afi_safi') == 'ipv4':
self.update_rib_in_ipv4(msg)
LOG.info(msg)
# LOG.info(msg)
self.handler.update_received(self, timestamp, msg)

self.msg_recv_stat['Updates'] += 1
Expand Down Expand Up @@ -622,27 +625,6 @@ def ip_longest_match(self, prefix_ip):
return results

def update_send_verion(self, peer_ip, attr, nlri, withdraw):
# ipv4 send
# if (attr and nlri) or withdraw:
# if withdraw:
# for prefix in withdraw:
# if prefix in self.ipv4_send_dict:
# self.send_version['ipv4'] += 1
# del self.ipv4_send_dict[prefix]
# else:
# LOG.info("Do not have %s in send ipv4 dict" % prefix)
# if attr and nlri:
# for prefix in nlri:
# if prefix not in self.ipv4_send_dict:
# self.send_version['ipv4'] += 1
# self.ipv4_send_dict[prefix] = attr
# else:
# if attr == self.ipv4_send_dict[prefix]:
# pass
# else:
# self.send_version['ipv4'] += 1
# self.ipv4_send_dict[prefix] = attr
# flowspec sr mpls send
if 14 in attr:
if attr[14]['afi_safi'] == [1, 133]:
LOG.info("send flowspec")
Expand Down Expand Up @@ -760,27 +742,6 @@ def update_send_verion(self, peer_ip, attr, nlri, withdraw):
LOG.info("Do not have %s in send flowspec dict" % key)

def update_receive_verion(self, attr, nlri, withdraw):
# receive ipv4
# if (attr and nlri) or withdraw:
# if withdraw:
# for prefix in withdraw:
# if prefix in self.ipv4_receive_dict:
# self.receive_version['ipv4'] += 1
# del self.ipv4_receive_dict[prefix]
# else:
# LOG.info("Do not have %s in recieve ipv4 dict" % prefix)
# if attr and nlri:
# for prefix in nlri:
# if prefix not in self.ipv4_receive_dict:
# self.receive_version['ipv4'] += 1
# self.ipv4_receive_dict[prefix] = attr
# else:
# if attr == self.ipv4_receive_dict[prefix]:
# pass
# else:
# self.receive_version['ipv4'] += 1
# self.ipv4_receive_dict[prefix] = attr
# receive flowspec sr mpls_vpn send
if 14 in attr:
if attr[14]['afi_safi'] == [1, 133]:
LOG.info("recieve flowspec send")
Expand Down
3 changes: 3 additions & 0 deletions yabgp/message/attribute/linkstate/prefix/prefix_sid.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from yabgp.tlv import TLV
from ..linkstate import LinkState

# https://datatracker.ietf.org/doc/draft-ietf-idr-bgp-ls-segment-routing-ext/?include_text=1

# 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
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Expand All @@ -32,6 +34,7 @@
# isis
# 0 1 2 3 4 5 6 7
# +-+-+-+-+-+-+-+-+

# |R|N|P|E|V|L| |
# +-+-+-+-+-+-+-+-+

Expand Down
9 changes: 9 additions & 0 deletions yabgp/message/attribute/mpreachnlri.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from yabgp.message.attribute.nlri.ipv6_unicast import IPv6Unicast
from yabgp.message.attribute.nlri.labeled_unicast.ipv4 import IPv4LabeledUnicast
from yabgp.message.attribute.nlri.labeled_unicast.ipv6 import IPv6LabeledUnicast
from yabgp.message.attribute.nlri.ipv4_unicast import IPv4Unicast
from yabgp.message.attribute.nlri.evpn import EVPN
from yabgp.message.attribute.nlri.linkstate import BGPLS

Expand Down Expand Up @@ -80,6 +81,14 @@ def parse(cls, value):

# Address Family IPv4
if afi == afn.AFNUM_INET:
if safi == safn.SAFNUM_UNICAST:
# ipv4 unicast
# parse nexthop
nexthop = str(netaddr.IPAddress(int(binascii.b2a_hex(nexthop_bin), 16)))
# parse nlri
nlri = IPv4Unicast.parse(nlri_bin)
return dict(afi_safi=(afi, safi), nexthop=nexthop, nlri=nlri)

if safi == safn.SAFNUM_LAB_VPNUNICAST:
# MPLS VPN
# parse nexthop
Expand Down
101 changes: 101 additions & 0 deletions yabgp/message/attribute/nlri/ipv4_unicast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# !/usr/bin/env python
# -*- coding:utf-8 -*-
"""
dalian-stc-dev@cisco.com
Copyright 2019 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.

""" IPv4 Unicast """

import struct
import binascii
import logging
import netaddr

from yabgp.message.attribute.nlri import NLRI
from yabgp.common import exception as excep
from yabgp.common import constants as bgp_cons


LOG = logging.getLogger()


class IPv4Unicast(NLRI):

@staticmethod
def parse(nlri_data, addpath=False):
"""
Parses an RFC4271 encoded blob of BGP prefixes into a list
:param data: hex data
:param addpath: support addpath or not
:return: prefix_list
"""
prefixes = []
postfix = nlri_data
while len(postfix) > 0:
# for python2 and python3
if addpath:
path_id = struct.unpack('!I', postfix[0:4])[0]
postfix = postfix[4:]
if isinstance(postfix[0], int):
prefix_len = postfix[0]
else:
prefix_len = ord(postfix[0])
if prefix_len > 32:
LOG.warning('Prefix Length larger than 32')
raise excep.UpdateMessageError(
sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_NETWORK_FIELD,
data=repr(nlri_data)
)
octet_len, remainder = int(prefix_len / 8), prefix_len % 8
if remainder > 0:
# prefix length doesn't fall on octet boundary
octet_len += 1
tmp = postfix[1:octet_len + 1]
# for python2 and python3
if isinstance(postfix[0], int):
prefix_data = [i for i in tmp]
else:
prefix_data = [ord(i) for i in tmp]
# Zero the remaining bits in the last octet if it didn't fall
# on an octet boundary
if remainder > 0:
prefix_data[-1] &= 255 << (8 - remainder)
prefix_data = prefix_data + list(str(0)) * 4
prefix = "%s.%s.%s.%s" % (tuple(prefix_data[0:4])) + '/' + str(prefix_len)
if not addpath:
prefixes.append(prefix)
else:
prefixes.append({'prefix': prefix, 'path_id': path_id})
# Next prefix
postfix = postfix[octet_len + 1:]

return prefixes

@classmethod
def construct(cls, nlri_list):
"""
Construct NLRI from list to hex data
:param nlri_list:
:return:
"""
nlri_hex = b''
for prefix in nlri_list:
prefix = netaddr.IPNetwork(prefix)
nlri_hex += struct.pack('!B', prefix.prefixlen)
nlri_hex += binascii.unhexlify(hex(prefix.ip)[2:])
return nlri_hex

0 comments on commit d32cd5a

Please sign in to comment.