├── .coveragerc ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .mailmap ├── .testr.conf ├── Dockerfile ├── HACKING.rst ├── LICENSE ├── README-zh.rst ├── README.rst ├── bin └── yabgpd ├── doc ├── Makefile ├── make.bat ├── requirements.txt └── source │ ├── _static │ └── .placeholder │ ├── api │ └── v1.rst │ ├── conf.py │ ├── extension.rst │ ├── feature.rst │ ├── index.rst │ ├── install.rst │ ├── msg_format.rst │ ├── reference.rst │ ├── restapi.rst │ ├── tools.rst │ └── tutorial.rst ├── etc └── yabgp │ └── yabgp.ini.sample ├── example └── custom_bgpd.py ├── redhat ├── python-yabgp.spec └── yabgp.service ├── requirements.txt ├── run_test.py ├── setup.cfg ├── setup.py ├── test-requirements.txt ├── tools ├── Yabgp.postman_collection.json ├── evpn_import.py ├── hijack.py ├── hijack_change_as.py ├── hijack_ipv6.py ├── hijack_local_preference.py ├── rabbit_mongo.sh ├── route_injector └── route_ipv6_injector.py ├── tox.ini └── yabgp ├── __init__.py ├── agent ├── __init__.py └── cmd.py ├── api ├── __init__.py ├── app.py ├── code.py ├── config.py ├── utils.py └── v1.py ├── common ├── __init__.py ├── afn.py ├── constants.py ├── exception.py ├── flag.py ├── safn.py └── tlv.py ├── config.py ├── core ├── __init__.py ├── factory.py ├── fsm.py ├── protocol.py └── timer.py ├── handler ├── __init__.py └── default_handler.py ├── hooks.py ├── log.py ├── message ├── __init__.py ├── attribute │ ├── __init__.py │ ├── aggregator.py │ ├── aspath.py │ ├── atomicaggregate.py │ ├── clusterlist.py │ ├── community.py │ ├── extcommunity.py │ ├── largecommunity.py │ ├── linkstate │ │ ├── __init__.py │ │ ├── link │ │ │ ├── __init__.py │ │ │ ├── adj_seg_id.py │ │ │ ├── admingroup.py │ │ │ ├── extend_admin_group.py │ │ │ ├── igp_metric.py │ │ │ ├── lan_adj_sid.py │ │ │ ├── link_identifiers.py │ │ │ ├── link_msd.py │ │ │ ├── link_name.py │ │ │ ├── max_bw.py │ │ │ ├── max_rsv_bw.py │ │ │ ├── min_max_link_delay.py │ │ │ ├── mplsmask.py │ │ │ ├── opa_link_attr.py │ │ │ ├── peer_adj_sid.py │ │ │ ├── peer_node_sid.py │ │ │ ├── peer_set_sid.py │ │ │ ├── protection_type.py │ │ │ ├── remote_router_id.py │ │ │ ├── srlg.py │ │ │ ├── srv6_end_x_sid.py │ │ │ ├── srv6_lan_end_x_sid.py │ │ │ ├── srv6_sid.py │ │ │ ├── te_metric.py │ │ │ ├── unidirect_avail_bw.py │ │ │ ├── unidirect_bw_util.py │ │ │ ├── unidirect_delay_var.py │ │ │ ├── unidirect_link_delay.py │ │ │ ├── unidirect_packet_loss.py │ │ │ ├── unidirect_residual_bw.py │ │ │ └── unsrv_bw.py │ │ ├── linkstate.py │ │ ├── node │ │ │ ├── __init__.py │ │ │ ├── isisarea.py │ │ │ ├── local_router_id.py │ │ │ ├── name.py │ │ │ ├── node_msd.py │ │ │ ├── nodeflags.py │ │ │ ├── opa_node_attr.py │ │ │ ├── sid_or_label.py │ │ │ ├── sr_algorithm.py │ │ │ ├── sr_capabilities.py │ │ │ ├── srlb.py │ │ │ └── srv6_capabilities.py │ │ ├── prefix │ │ │ ├── __init__.py │ │ │ ├── ext_igp_route_tag_list.py │ │ │ ├── igp_route_tag_list.py │ │ │ ├── igpflags.py │ │ │ ├── ospf_forward_addr.py │ │ │ ├── prefix_igp_attr.py │ │ │ ├── prefix_metric.py │ │ │ ├── prefix_sid.py │ │ │ ├── src_router_id.py │ │ │ └── srv6_locator.py │ │ └── srv6_sid │ │ │ ├── __init__.py │ │ │ ├── srv6_bgp_peer_node_sid.py │ │ │ └── srv6_endpoint_behavior.py │ ├── localpref.py │ ├── med.py │ ├── mpreachnlri.py │ ├── mpunreachnlri.py │ ├── nexthop.py │ ├── nlri │ │ ├── __init__.py │ │ ├── evpn.py │ │ ├── ipv4_flowspec.py │ │ ├── ipv4_mpls_vpn.py │ │ ├── ipv4_srte.py │ │ ├── ipv4_unicast.py │ │ ├── ipv6_flowspec.py │ │ ├── ipv6_mpls_vpn.py │ │ ├── ipv6_unicast.py │ │ ├── labeled_unicast │ │ │ ├── __init__.py │ │ │ ├── ipv4.py │ │ │ └── ipv6.py │ │ ├── linkstate.py │ │ └── mpls_vpn.py │ ├── origin.py │ ├── originatorid.py │ ├── pmsitunnel.py │ ├── sr │ │ ├── __init__.py │ │ ├── bgpprefixsid.py │ │ └── srv6 │ │ │ ├── __init__.py │ │ │ ├── l3service.py │ │ │ ├── sidinformation.py │ │ │ └── sidstructure.py │ └── tunnelencaps.py ├── keepalive.py ├── notification.py ├── open.py ├── route_refresh.py └── update.py ├── net └── __init__.py ├── tests ├── __init__.py └── unit │ ├── __init__.py │ ├── api │ ├── __init__.py │ ├── test_app.py │ └── test_v1.py │ ├── core │ ├── __init__.py │ └── test_protocol.py │ └── message │ ├── __init__.py │ ├── attribute │ ├── __init__.py │ ├── linkstate │ │ ├── __init__.py │ │ ├── link │ │ │ ├── __init__.py │ │ │ └── test_srv6_end_x_sid.py │ │ ├── node │ │ │ ├── __init__.py │ │ │ ├── test_node_msd.py │ │ │ └── test_srv6_capabilities.py │ │ ├── prefix │ │ │ ├── __init__.py │ │ │ └── test_srv6_locator.py │ │ ├── srv6_sid │ │ │ ├── __init__.py │ │ │ └── test_srv6_endpoint_behavior.py │ │ └── test_linkstate.py │ ├── nlri │ │ ├── __init__.py │ │ ├── labeled_unicast │ │ │ ├── __init__.py │ │ │ ├── test_ipv4_labeled_unicast.py │ │ │ └── test_ipv6_labeled_unicast.py │ │ ├── test_bgpls.py │ │ ├── test_blgls_epe.py │ │ ├── test_evpn.py │ │ ├── test_ipv4_flowspec.py │ │ ├── test_ipv4_mpls_vpn.py │ │ ├── test_ipv4_srte.py │ │ ├── test_ipv6_mpls_vpn.py │ │ ├── test_ipv6_unicast.py │ │ ├── test_linkdelay.py │ │ ├── test_linkstate_prefix_sid.py │ │ ├── test_mpls_vpn.py │ │ └── test_nlri.py │ ├── sr │ │ ├── __init__.py │ │ └── test_bgpprefixsid.py │ ├── test_aggregator.py │ ├── test_aspath.py │ ├── test_atomicaggregate.py │ ├── test_clusterlist.py │ ├── test_community.py │ ├── test_extcommunity.py │ ├── test_large_community.py │ ├── test_localpref.py │ ├── test_med.py │ ├── test_mpreachnlri.py │ ├── test_mpunreachnlri.py │ ├── test_nexthop.py │ ├── test_origin.py │ ├── test_originatorid.py │ ├── test_pmsitunnel.py │ └── test_tunnelencaps.py │ ├── test_keepalive.py │ ├── test_notification.py │ ├── test_open.py │ ├── test_route_refresh.py │ └── test_update.py └── tlv.py /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | source = yabgp 4 | omit = yabgp/tests/* 5 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: CI 5 | 6 | on: 7 | push: 8 | branches: [ "master" ] 9 | pull_request: 10 | branches: [ "master" ] 11 | 12 | jobs: 13 | tests: 14 | 15 | name: Tests 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources 21 | os: [ ubuntu-20.04, macos-latest, windows-latest ] 22 | python-version: [ "3.6", "3.x" ] 23 | exclude: 24 | - python-version: "3.x" 25 | 26 | steps: 27 | - uses: actions/checkout@v3 28 | 29 | - name: Set up Python ${{ matrix.python-version }} 30 | uses: actions/setup-python@v3 31 | with: 32 | python-version: ${{ matrix.python-version }} 33 | 34 | - name: Display Python version 35 | run: python -c "import sys; print(sys.version)" 36 | 37 | - name: Install tox and other dependencies 38 | run: | 39 | python -m pip install --upgrade pip setuptools wheel 40 | python -m pip install tox 41 | python -m pip install -r requirements.txt 42 | python -m pip install -r test-requirements.txt 43 | 44 | - name: Run tox 45 | run: tox -e pep8 -c tox.ini 46 | 47 | - name: Run unittest 48 | run: python run_test.py 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | cover/ 46 | .testrepository 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | .idea/ 61 | etc/yabgp/yabgp.ini 62 | 63 | # Vagrantfile 64 | .vagrant/ 65 | 66 | AUTHORS 67 | build-stamp 68 | ChangeLog 69 | covhtml/ 70 | doc/build 71 | *.DS_Store 72 | .vscode/settings.json 73 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Format is: 2 | # 3 | # 4 | Peng Xiao -------------------------------------------------------------------------------- /.testr.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_LOG_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./yabgp/tests/unit} $LISTOPT $IDOPTION 3 | test_id_option=--load-list $IDFILE 4 | test_list_option=--list -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7.14-alpine 2 | 3 | LABEL maintainer="Peng Xiao " 4 | 5 | RUN apk add --no-cache gcc musl-dev g++ 6 | 7 | ADD . /yabgp 8 | 9 | WORKDIR /yabgp 10 | 11 | RUN pip install -r requirements.txt && python setup.py install 12 | 13 | EXPOSE 8801 14 | 15 | VOLUME ["~/data"] 16 | 17 | ENTRYPOINT ["/usr/local/bin/yabgpd"] 18 | 19 | CMD [] 20 | -------------------------------------------------------------------------------- /HACKING.rst: -------------------------------------------------------------------------------- 1 | Hacking Guide 2 | ============= 3 | 4 | 5 | Code style 6 | ---------- 7 | 8 | Step 1: Read http://www.python.org/dev/peps/pep-0008/ 9 | 10 | Step 2: Read http://www.python.org/dev/peps/pep-0008/ again 11 | 12 | Step 3: Read on 13 | 14 | 15 | Running Tests 16 | ------------- 17 | 18 | Run tox 19 | 20 | .. code:: bash 21 | 22 | $ cd yabgp 23 | $ tox 24 | 25 | Building Docs 26 | ------------- 27 | 28 | Run tox 29 | 30 | .. code:: bash 31 | 32 | $ cd yabgp 33 | $ tox 34 | -------------------------------------------------------------------------------- /README-zh.rst: -------------------------------------------------------------------------------- 1 | YABGP 2 | ===== 3 | 4 | yabgp是什么? 5 | ~~~~~~~~~~~~~~ 6 | 7 | YABGP是另一种BGP协议的Python实现。它可以和各种路由器(包括Cisco/华为/Juniper的真实设备和一些模拟路由器比如GNS3)建立BGP连接, 8 | 接收解析BGP messages以供将来分析。 9 | 10 | 支持通过RESTful API发送BGP messages(route refresh/update)到其对等体。YABGP不能自主地发送任何BGP update messages, 11 | 它只是一个代理,一个控制器可以控制多个代理。 12 | 13 | 我们严格遵循RFCs文档的约定开发此项目。 14 | 15 | 此软件可应用于Linux/Unix,Mac OS和windows系统。 16 | 17 | 功能 18 | ~~~~~~~~ 19 | 20 | - 它可以通过IPv4地址以主动模式(作为TCP客户端)建立BGP会话连接。 21 | 22 | - 支持TCP的MD5认证(只有IPv4并且不支持windows系统) 23 | 24 | - BGP capabilities支持:4字节的ASN,Route Refresh(Cisco Route Refresh),添加发送/接收路径; 25 | 26 | - 地址族支持: 27 | 28 | - IPv4/IPv6 Unicast 29 | 30 | - IPv4/IPv6 Labeled Unicast 31 | 32 | - IPv4 Flowspec(有限支持) 33 | 34 | - IPv4 SR Policy(draft-previdi-idr-segment-routing-te-policy-07) 35 | 36 | - IPv4/IPv6 MPLSVPN 37 | 38 | - EVPN (部分支持) 39 | 40 | - 解析所有BGP messages为json格式并写入本地文件(可配置); 41 | 42 | - 支持通过基本的RESTFUL API获取对等体运行信息或者发送BGP messages。 43 | 44 | 快速开始 45 | ~~~~~~~~~~~ 46 | 47 | 我们推荐在python的虚拟环境中运行``yabgp``,可以通过源码或者pip工具安装 48 | 49 | 源码安装: 50 | 51 | .. code:: bash 52 | 53 | $ virtualenv yabgp-virl 54 | $ source yabgp-virl/bin/activate 55 | $ git clone https://github.com/smartbgp/yabgp 56 | $ cd yabgp 57 | $ pip install -r requirements.txt 58 | $ cd bin 59 | $ python yabgpd -h 60 | 61 | pip安装: 62 | 63 | .. code:: bash 64 | 65 | $ virtualenv yabgp-virl 66 | $ source yabgp-virl/bin/activate 67 | $ pip install yabgp 68 | $ which yabgpd 69 | /home/yabgp/yabgp-virl/bin/yabgpd 70 | $ yabgpd -h 71 | 72 | 例如: 73 | 74 | .. code:: bash 75 | 76 | $ yabgpd --bgp-local_addr=1.1.1.1 --bgp-local_as=65001 --bgp-remote_addr=1.1.1.2 --bgp-remote_as=65001 --bgp-afi_safi=ipv4 77 | 78 | 文档 79 | ~~~~~~~~~~~~~ 80 | 81 | 更多信息请参考 http://yabgp.readthedocs.org 82 | 83 | 相关项目 84 | ~~~~~~~~~~~~~~~~ 85 | 86 | 路由监控能够向YABGP自动报警。https://github.com/nerdalize/routewatch 87 | 88 | 基于YABGP的一个BGP update生成器。https://github.com/trungdtbk/bgp-update-gen 89 | 90 | 支持 91 | ~~~~~~~ 92 | 93 | 加入Slack,欢迎问题与建议,我们一起讨论。http://smartbgp.slack.com/ 94 | 95 | 可以发送email到xiaoquwl@gmail.com,或者在GitHub上提issue。 96 | 97 | 贡献 98 | ~~~~~~~~~~ 99 | 100 | 在这里创建GitHub Pull Request。https://github.com/smartbgp/yabgp/pulls 101 | 102 | 更多信息请阅读HACKING.rst文件。 103 | 104 | 感谢 105 | ~~~~~~ 106 | 107 | 核心文件比如fsm,protocol我们从https://github.com/wikimedia/PyBal/blob/master/pybal/bgp.py 参考了一部分代码, 108 | 109 | message解析,我们参照了这里的代码https://github.com/Exa-Networks/exabgp 110 | -------------------------------------------------------------------------------- /bin/yabgpd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | # Copyright 2015 Cisco Systems, Inc. 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | """ BGP daemon """ 20 | 21 | import os 22 | import sys 23 | 24 | possible_topdir = os.path.normpath(os.path.join(os.path.abspath(__file__), 25 | os.pardir, 26 | os.pardir)) 27 | 28 | if os.path.exists(os.path.join(possible_topdir, 29 | 'yabgp', 30 | '__init__.py')): 31 | # use the module in current work dir if applicable 32 | sys.path.insert(0, possible_topdir) 33 | else: 34 | # seems has no effect 35 | # possible_topdir = '/' 36 | pass 37 | 38 | from yabgp.agent.cmd import main 39 | 40 | if __name__ == '__main__': 41 | sys.exit(main()) 42 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx 2 | sphinx_rtd_theme 3 | pbr==2.0.0 4 | oslo.config==2.1.0 5 | Twisted==20.3.0 6 | Flask==1.0 7 | Flask-HTTPAuth==2.5.0 8 | netaddr>=0.7.12 9 | future>=0.16.0 10 | py-radix==0.10.0 -------------------------------------------------------------------------------- /doc/source/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/doc/source/_static/.placeholder -------------------------------------------------------------------------------- /doc/source/feature.rst: -------------------------------------------------------------------------------- 1 | Features 2 | ======== 3 | 4 | - It can establish BGP session based on IPv4 address (TCP Layer) in 5 | active mode(as TCP client); 6 | 7 | - Support TCP MD5 authentication(IPv4 and does not support Windows 8 | now); 9 | 10 | - BGP capabilities support: 4 Bytes ASN, Route Refresh(Cisco Route Refresh), Add Path send/receive; 11 | 12 | - Address family support: 13 | 14 | - IPv4/IPv6 unicast 15 | 16 | - IPv4 Flowspec(limited) 17 | 18 | - IPv4 sr-policy(limited) 19 | 20 | - IPv4/IPv6 MPLSVPN 21 | 22 | - EVPN (partially supported) 23 | 24 | - Decode all BGP messages to json format and write them into files in local disk(configurable); 25 | 26 | - Support basic RESTFUL API for getting running information and sending BGP messages. 27 | 28 | - Platform support: Linux/Unix(recommended), Mac OS and Windows. 29 | 30 | .. note:: 31 | 32 | yabgp is a light weight BGP agent used for connecting network devices. It only can be 33 | TCP client in one BGP peering connection and can't send any update messages by itself(send through REST API). 34 | We recommend that each yabgp process connect only one BGP neighbor, so each process is independent with each other, 35 | we can start many yabgp processes within the same machine or in different machines. There can be a central controller 36 | which can controll all yabgp processes through REST API to send BGP update messages. -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. yabgp documentation master file, created by 2 | sphinx-quickstart on Fri May 15 10:18:44 2015. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | YABGP Project 7 | ============= 8 | 9 | YABGP is a yet another Python implementation for BGP Protocol. It can be used to establish BGP connections with all kinds 10 | of routers (include real Cisco/HuaWei/Juniper routers and some router 11 | simulators like GNS3) and receive/parse BGP messages for 12 | future analysis. 13 | 14 | Support sending BGP messages(route refresh/update) to the peer through RESTful API. YABGP can't send any BGP update messages 15 | by itself, it's just a agent, so there can be many agents and they can be controlled by a contoller. 16 | 17 | 18 | Table of Contents 19 | ================= 20 | 21 | .. toctree:: 22 | :maxdepth: 2 23 | 24 | feature 25 | install 26 | tutorial 27 | msg_format 28 | restapi 29 | extension 30 | tools 31 | reference 32 | 33 | Support 34 | ======= 35 | 36 | There are many jobs need to do in future. 37 | We are working hardly on that. So any of your ideas is welcome. 38 | 39 | Please use GitHub issue system or submit pull request. 40 | 41 | 42 | Indices and tables 43 | ================== 44 | 45 | * :ref:`genindex` 46 | * :ref:`modindex` 47 | * :ref:`search` 48 | -------------------------------------------------------------------------------- /doc/source/install.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | We recommend run ``yabgp`` through python virtual-env from source 5 | code or pip install 6 | 7 | From source code 8 | ~~~~~~~~~~~~~~~~ 9 | 10 | Use yabgp from source code: 11 | 12 | .. code:: bash 13 | 14 | $ virtualenv yabgp-virl 15 | $ source yabgp-virl/bin/activate 16 | $ git clone https://github.com/smartbgp/yabgp 17 | $ cd yabgp 18 | $ pip install -r requirements.txt 19 | $ cd bin 20 | $ python yabgpd -h 21 | 22 | From pip 23 | ~~~~~~~~ 24 | 25 | Use pip install 26 | 27 | .. code:: bash 28 | 29 | $ virtualenv yabgp-virl 30 | $ source yabgp-virl/bin/activate 31 | $ pip install yabgp 32 | $ which yabgpd 33 | /home/yabgp/yabgp-virl/bin/yabgpd 34 | $ yabgpd -h 35 | 36 | .. note:: 37 | 38 | For ``virtualenv``, you can install it from pip. And make sure you have installed ``python-dev`` based on 39 | your operation system, for example Ubuntu, you can install it from ``apt-get install python-dev``. 40 | otherwise, you may get error when install requirement from requirements.txt -------------------------------------------------------------------------------- /doc/source/restapi.rst: -------------------------------------------------------------------------------- 1 | RESTFUL API 2 | =========== 3 | 4 | yabgp provides various endpoints that can be used to interact with the data and routers. Web API uses JSON format. 5 | 6 | 7 | REST API has basic http auth, through usename and password. The usename and password configured in configuration file and they have default values. 8 | 9 | .. code:: bash 10 | 11 | [rest] 12 | # Address to bind the API server to. 13 | # bind_host = 0.0.0.0 14 | 15 | # Port the bind the API server to. 16 | # bind_port = 8801 17 | 18 | # username and password for api server 19 | # username = admin 20 | # password = admin 21 | 22 | .. toctree:: 23 | :maxdepth: 2 24 | 25 | api/v1 -------------------------------------------------------------------------------- /doc/source/tools.rst: -------------------------------------------------------------------------------- 1 | Tools 2 | ====== 3 | 4 | Here are some tools can be used for yabgp. 5 | 6 | Route Injector 7 | ~~~~~~~~~~~~~~~ 8 | 9 | Tools location: https://github.com/smartbgp/yabgp/blob/master/tools/route_injector 10 | 11 | This tool can be used to send bgp update messages to yabgp process. For example, you start a yabgp process: 12 | 13 | .. code-block:: bash 14 | 15 | $ python yabgp/bin/yabgpd --bgp-local_as=100 --bgp-local_addr=127.0.0.1 \ 16 | --bgp-remote_addr=2.2.2.2 --bgp-remote_as=100 17 | 18 | If you have some BGP messages come from some other yabgp process, like: 19 | 20 | .. code-block:: bash 21 | 22 | $ pwd 23 | /home/yabgp/data/bgp/1.1.1.1/msg 24 | $ ls 25 | 1450668274.82.msg 1450668593.59.msg 26 | 27 | We want to send all the BGP message received from peer ``1.1.1.1`` to ``2.2.2.2``. We can use route injector like this: 28 | 29 | .. code-block:: bash 30 | 31 | $ python route_injector --rest-host=127.0.0.1 --rest-port=8801 \ 32 | --message-json=/home/yabgp/data/bgp/1.1.1.1/msg/1450668274.82.msg \ 33 | --peerip=2.2.2.2 34 | Percent: [######################################## ] 81.05% 35 | 36 | Then, route-injector will read bgp message file and try to send all bgp messages to peer ``2.2.2.2`` through REST API. When finised: 37 | 38 | .. code-block:: bash 39 | 40 | Percent: [##################################################] 100.00% 41 | Total messages: 128444. 42 | Success send out: 15109 43 | Failed send out: 113335 44 | 45 | Postman Collection 46 | ~~~~~~~~~~~~~~~~~~ 47 | 48 | Located in ``/yabgp/tools/Yabgp.postman_collection.json``. You can import this collection into POSTMAN(http://www.getpostman.com/) 49 | and there are some REST API request examples. 50 | -------------------------------------------------------------------------------- /doc/source/tutorial.rst: -------------------------------------------------------------------------------- 1 | Tutorial 2 | ======== 3 | 4 | Basic Usage 5 | ~~~~~~~~~~~ 6 | 7 | We can use ``yabgpd`` help. 8 | 9 | .. code:: bash 10 | 11 | $ yabgpd -h 12 | 13 | The simple way to start a yabgp agent is (There are four mandatory parameters): 14 | 15 | .. code:: bash 16 | 17 | $ yabgpd --bgp-local_addr=10.75.44.11 --bgp-local_as=23650 \ 18 | --bgp-remote_addr=10.124.1.245 --bgp-remote_as=23650 19 | 20 | The default address family will be IPv4 unicast. If you need support other address family, you can use something like: 21 | 22 | ``` 23 | $ yabgpd --bgp-local_addr=10.75.44.122 --bgp-local_as=100 --bgp-remote_addr=10.75.195.199 --bgp-remote_as=100 --bgp-afi_safi=ipv4_srte,flowspec,ipv4,bgpls 24 | ``` 25 | 26 | that session will suport: IPv4 Unicast, IPv4 Flowspec, IPv4 SR TE and BGP linkstate. 27 | 28 | Configuration 29 | ~~~~~~~~~~~~~ 30 | 31 | The configuration sample can be found at https://github.com/smartbgp/yabgp/blob/master/etc/yabgp/yabgp.ini.sample 32 | 33 | Advanced Usage 34 | ~~~~~~~~~~~~~~ 35 | 36 | If you change the default setting (like change the ``write_dir``), please start the ``yabgp`` use the configuration file: 37 | 38 | .. code:: bash 39 | 40 | $ cp etc/yabgp/yabgp.ini.sample etc/yabgp/yabgp.ini 41 | $ yabgpd --bgp-local_addr=10.75.44.11 --bgp-local_as=23650 --bgp-remote_addr=10.124.1.245 \ 42 | --bgp-remote_as=23650 --bgp-md5=cisco --config-file=../etc/yabgp/yabgp.ini 43 | 44 | Logging and Debug 45 | ~~~~~~~~~~~~~~~~~ 46 | 47 | The default setting is loggint to console, if you want to write log files and no console output, please use: 48 | 49 | .. code:: bash 50 | 51 | $ yabgpd --bgp-local_addr=10.75.44.11 --bgp-local_as=23650 --bgp-remote_addr=10.124.1.245 \ 52 | --bgp-remote_as=23650 --bgp-md5=cisco --nouse-stderr --log-file=test.log 53 | 54 | If you want to change the log level to debug, use `--verbose` option. 55 | 56 | .. code:: bash 57 | 58 | $ yabgpd --bgp-local_addr=10.75.44.11 --bgp-local_as=23650 --bgp-remote_addr=10.124.1.245 \ 59 | --bgp-remote_as=23650 --bgp-md5=cisco --verbose 60 | -------------------------------------------------------------------------------- /example/custom_bgpd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from __future__ import print_function 4 | import sys 5 | 6 | from flask import Blueprint 7 | import flask 8 | 9 | from yabgp.agent import prepare_service 10 | from yabgp.handler import BaseHandler 11 | 12 | 13 | class APIHandler(object): 14 | 15 | blueprint = Blueprint('demo', __name__) 16 | url_prefix = '/v1' 17 | 18 | 19 | @APIHandler.blueprint.route('/rib') 20 | def root(): 21 | """ 22 | v1 api root. Get the api status. 23 | """ 24 | intro = { 25 | 'rib': [] 26 | } 27 | return flask.jsonify(intro) 28 | 29 | 30 | class CliHandler(BaseHandler): 31 | """demo handler implementation 32 | """ 33 | 34 | def __init__(self): 35 | super(CliHandler, self).__init__() 36 | 37 | def init(self): 38 | pass 39 | 40 | def on_update_error(self, peer, timestamp, msg): 41 | print('[-] UPDATE ERROR,', msg) 42 | 43 | def route_refresh_received(self, peer, msg, msg_type): 44 | print('[+] ROUTE_REFRESH received,', msg) 45 | 46 | def keepalive_received(self, peer, timestamp): 47 | print('[+] KEEPALIVE received') 48 | 49 | def open_received(self, peer, timestamp, result): 50 | print('[+] OPEN received,', result) 51 | 52 | def update_received(self, peer, timestamp, msg): 53 | print('[+] UPDATE received,', msg) 54 | 55 | def notification_received(self, peer, msg): 56 | print('[-] NOTIFICATION received,', msg) 57 | 58 | def on_connection_lost(self, peer): 59 | print('[-] CONNECTION lost') 60 | 61 | def on_connection_failed(self, peer, msg): 62 | print('[-] CONNECTION failed,', msg) 63 | 64 | def on_established(self, peer, msg): 65 | print('[-] ESTABLISHED,', msg) 66 | 67 | 68 | def main(): 69 | try: 70 | cli_handler = CliHandler() 71 | prepare_service(handler=cli_handler, api_hander=APIHandler()) 72 | except Exception as e: 73 | print(e) 74 | 75 | 76 | if __name__ == '__main__': 77 | sys.exit(main()) 78 | -------------------------------------------------------------------------------- /redhat/python-yabgp.spec: -------------------------------------------------------------------------------- 1 | %{!?__python2: %global __python2 /usr/bin/python2} 2 | %{!?python2_sitelib: %global python2_sitelib %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")} 3 | 4 | Name: python-yabgp 5 | Version: 0.1.4 6 | Release: 0%{?dist} 7 | Summary: Yet Another BGP (Border Gateway Protocol) Python Implementation 8 | 9 | Group: Development/Libraries 10 | License: APLv2 11 | URL: http://yabgp.readthedocs.org/en/latest/ 12 | Source0: https://github.com/smartbgp/yabgp/archive/v%{version}.tar.gz 13 | Source1: yabgp.service 14 | BuildArch: noarch 15 | Provides: yabgp-libs 16 | 17 | BuildRequires: python-setuptools 18 | Requires: python2 >= 2.6 19 | #Requires: python-pbr >= 0.5.21, python-pymongo >= 3.0.3, python-netaddr >= 0.7.12, python-flask >= 0.10.1, python-pika >= 0.9.14, python-flask-httpauth >= 2.5.0, python-twisted >= 15.0.0, python-oslo-config >= 1.6.0 20 | 21 | %description 22 | YABGP python module 23 | 24 | %package -n yabgp 25 | Summary: Yet Another BGP (Border Gateway Protocol) 26 | Group: Applications/Internet 27 | BuildRequires: systemd-units 28 | Requires: systemd, yabgp-libs == %{version} 29 | 30 | %description -n yabgp 31 | YABGP is a yet another Python implementation for BGP Protocol. It can be used 32 | to establish BGP connections with all kinds of routers (include real 33 | Cisco/HuaWei/Juniper routers and some router simulators like GNS3) and 34 | receive/parse BGP messages for future analysis. 35 | 36 | %prep 37 | %autosetup -n yabgp-%{version} 38 | 39 | %build 40 | %{__python2} setup.py build 41 | 42 | %install 43 | %{__python2} setup.py install -O1 --root ${RPM_BUILD_ROOT} 44 | 45 | # fix file locations 46 | mv ${RPM_BUILD_ROOT}/usr/bin ${RPM_BUILD_ROOT}%{_sbindir} 47 | mv ${RPM_BUILD_ROOT}/usr/etc ${RPM_BUILD_ROOT}/%{_sysconfdir} 48 | 49 | install -d %{buildroot}/%{_unitdir} 50 | install %{SOURCE1} %{buildroot}/%{_unitdir}/ 51 | 52 | %post -n yabgp 53 | %systemd_post yabgp.service 54 | 55 | %preun -n yabgp 56 | %systemd_preun yabgp.service 57 | 58 | %postun -n yabgp 59 | %systemd_postun_with_restart yabgp.service 60 | 61 | %files 62 | %defattr(-,root,root,-) 63 | %{python2_sitelib}/* 64 | %doc LICENSE README.rst requirements.txt 65 | 66 | %files -n yabgp 67 | %defattr(-,root,root,-) 68 | %attr(755, root, root) %{_sbindir}/yabgpd 69 | %dir %{_sysconfdir}/yabgp 70 | %attr(744, root, root) %{_sysconfdir}/yabgp/* 71 | %{_unitdir}/yabgp.service 72 | %doc LICENSE README.rst 73 | 74 | %changelog 75 | -------------------------------------------------------------------------------- /redhat/yabgp.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=YABGP 3 | After=network.target 4 | 5 | [Service] 6 | ConditionPathExists=/etc/yabgp/yabgp.ini 7 | ExecStart=/usr/sbin/yabgp /etc/yabgp/yabgp.ini 8 | ExecReload=/bin/kill -USR1 $MAINPID 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pbr==2.0.0 2 | oslo.config==2.1.0 3 | Twisted==20.3.0 4 | Flask==1.0 5 | Flask-HTTPAuth==2.5.0 6 | netaddr==0.8.0 7 | future>=0.16.0 8 | py-radix==0.10.0 9 | simplejson==3.17.0 10 | -------------------------------------------------------------------------------- /run_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import unittest 17 | 18 | 19 | def test(): 20 | "test load and run" 21 | tests = unittest.TestLoader().discover('.', pattern='test*.py') 22 | result = unittest.TextTestRunner(verbosity=2).run(tests) 23 | if not result.wasSuccessful(): 24 | raise ValueError('unittest failed') 25 | 26 | 27 | if __name__ == '__main__': 28 | test() 29 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = yabgp 3 | summary = Yet Another Border Gateway Protocol Python Implementation 4 | license = Apache License 2.0 5 | author = SmartBGP project team 6 | author-email = xiaoquwl@gmail.com 7 | home-page = http://smartbgp.github.io/ 8 | description-file = README.rst 9 | platform = any 10 | classifier = 11 | Development Status :: 5 - Production/Stable 12 | Environment :: Console 13 | License :: OSI Approved :: Apache Software License 14 | Topic :: System :: Networking 15 | Natural Language :: English 16 | Programming Language :: Python 17 | Programming Language :: Python :: 2.7 18 | Programming Language :: Python :: 3.4 19 | Programming Language :: Python :: 3.5 20 | Operating System :: Unix 21 | keywords = 22 | BGP 23 | SDN 24 | 25 | [build_sphinx] 26 | all_files = 1 27 | build-dir = doc/build 28 | source-dir = doc/source 29 | 30 | [global] 31 | setup-hooks = 32 | yabgp.hooks.setup_hook 33 | 34 | [files] 35 | packages = 36 | yabgp 37 | data_files = 38 | etc/yabgp/ = 39 | etc/yabgp/yabgp.ini.sample 40 | [entry_points] 41 | console_scripts = 42 | yabgpd = yabgp.agent.cmd:main 43 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import setuptools 17 | 18 | import yabgp.hooks 19 | 20 | yabgp.hooks.save_orig() 21 | 22 | setuptools.setup( 23 | name='yabgp', 24 | setup_requires=['pbr'], 25 | pbr=True) 26 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | nose==1.3.6 2 | flake8==2.4.0 3 | six>=1.10.0 4 | coverage 5 | testrepository>=0.0.13 6 | testtools>=0.9.26 7 | -------------------------------------------------------------------------------- /tools/rabbit_mongo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2015 Cisco Systems, Inc. 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | 18 | echo "Please makesure you have installed docker and can run as no-root user" 19 | echo "if yes, please press Enter..." 20 | read 21 | 22 | # try to stop running containers 23 | docker kill `docker ps | grep mongo | awk '{print $1}'` 24 | docker kill `docker ps | grep rabbit | awk '{print $1}'` 25 | 26 | # clean containers 27 | docker rm `docker ps -a | awk '{print $1}'` 28 | 29 | 30 | # for rabbitmq 31 | echo "Starting rabbitmq..." 32 | docker run -d -p 5672:5672 -p 15672:15672 -e RABBITMQ_PASS="admin" tutum/rabbitmq 33 | 34 | # for mongodb 35 | echo "starting mongodb replica set" 36 | 37 | cd ~ 38 | for ((i=1; i<4; i++)); do 39 | if ! [ -d data/mongo/node$i ]; then 40 | mkdir -p data/mongo/node$i 41 | fi 42 | done 43 | 44 | SCRIPTPATH=`pwd -P` 45 | 46 | docker run -p 27017:27017 -p 27018:27018 -p 27019:27019 -d \ 47 | -v /host/primary:$SCRIPTPATH/data/mongo/node1 -v /host/secondary:$SCRIPTPATH/data/mongo/node2 \ 48 | tattsun/mongodb-replset 49 | 50 | sleep 30 51 | 52 | echo "init mongodb replca set" 53 | 54 | mongo admin --eval "rs.initiate()" 55 | 56 | mongo_host_id=`docker ps | grep mongo | awk '{print $1}'` 57 | 58 | mongo admin --eval "rs.add(\"$mongo_host_id:27018\")" 59 | 60 | mongo admin --eval "rs.add(\"$mongo_host_id:27019\")" 61 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | # Tox (http://tox.testrun.org/) is a tool for running tests 2 | # in multiple virtualenvs. This configuration file will run the 3 | # test suite on all supported python versions. To use it, "pip install tox" 4 | # and then run "tox" from this directory. 5 | 6 | [tox] 7 | # List the environment that will be run by default 8 | minversion = 1.6 9 | envlist = py27,py36,docs,pep8 10 | skipsdist = True 11 | 12 | [testenv] 13 | setenv = VIRTUAL_ENV={envdir} 14 | LANG=en_US.UTF-8 15 | LANGUAGE=en_US:en 16 | LC_ALL=C 17 | deps = -r{toxinidir}/requirements.txt 18 | -r{toxinidir}/test-requirements.txt 19 | 20 | [testenv:py27] 21 | commands = coverage erase 22 | coverage run run_test.py 23 | coverage report -m 24 | [testenv:py36] 25 | commands = coverage erase 26 | coverage run run_test.py 27 | coverage report -m 28 | 29 | [testenv:docs] 30 | deps= 31 | sphinx==1.5.5 32 | sphinx_rtd_theme 33 | sphinxcontrib-httpdomain==1.1.7 34 | -r{toxinidir}/requirements.txt 35 | commands = sphinx-build -W -b html doc/source doc/build 36 | 37 | [testenv:pep8] 38 | sitepackages = False 39 | commands = 40 | flake8 {posargs} 41 | 42 | [flake8] 43 | # E712 is ignored on purpose, since it is normal to use 'column == true' 44 | # in sqlalchemy. 45 | # H803 skipped on purpose per list discussion. 46 | # E125 is deliberately excluded. See https://github.com/jcrocholl/pep8/issues/126 47 | # The rest of the ignores are TODOs 48 | # New from hacking 0.9: E129, E131, E265, E713, H407, H405, H904 49 | # Stricter in hacking 0.9: F402 50 | # E251 Skipped due to https://github.com/jcrocholl/pep8/issues/301 51 | 52 | max-line-length=120 53 | exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools 54 | -------------------------------------------------------------------------------- /yabgp/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """version information""" 17 | 18 | version_info = (0, 8, 3) 19 | version = '.'.join(map(str, version_info)) 20 | -------------------------------------------------------------------------------- /yabgp/agent/cmd.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """start service""" 17 | 18 | from __future__ import print_function 19 | from yabgp.agent import prepare_service 20 | 21 | 22 | def main(): 23 | try: 24 | prepare_service() 25 | except Exception as e: 26 | print(e) 27 | -------------------------------------------------------------------------------- /yabgp/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/api/__init__.py -------------------------------------------------------------------------------- /yabgp/api/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """Set up the API server application instance 17 | """ 18 | 19 | import flask 20 | 21 | from yabgp.api import v1 22 | from yabgp.api import config 23 | from oslo_config import cfg 24 | 25 | app = flask.Flask('yabgp.api') 26 | app.config['SECRET_KEY'] = 'cisco123' 27 | app.register_blueprint(v1.blueprint, url_prefix='/v1') 28 | 29 | cfg.CONF.register_cli_opts(config.rest_server_ops, group='rest') 30 | cfg.CONF.register_opts(config.keep_alive_ops, group='keep_alive') 31 | 32 | 33 | @app.route('/') 34 | def index(): 35 | """API Root. Get the API version information. 36 | 37 | **Example request**: 38 | 39 | .. sourcecode:: http 40 | 41 | GET / HTTP/1.1 42 | Host: example.com 43 | Accept: application/json, text/javascript 44 | 45 | **Example response**: 46 | 47 | .. sourcecode:: http 48 | 49 | HTTP/1.1 200 OK 50 | Vary: Accept 51 | Content-Type: text/json 52 | { 53 | "versions": { 54 | "values": [ 55 | { 56 | "id": "v1", 57 | "links": "http://10.75.44.11:8801//v1", 58 | "status": "stable" 59 | } 60 | ] 61 | } 62 | } 63 | 64 | :status 200: the api can work. 65 | """ 66 | base_url = flask.request.base_url 67 | available = [ 68 | {'tag': 'v1'}] 69 | collected = [version_descriptor(base_url, v['tag']) for v in available] 70 | versions = {'versions': {'values': collected}} 71 | return flask.jsonify(versions) 72 | 73 | 74 | def version_descriptor(base_url, version): 75 | url = version_url(base_url, version) 76 | return { 77 | 'id': version, 78 | 'links': url, 79 | 'status': 'stable' 80 | } 81 | 82 | 83 | def version_url(base_url, version_number): 84 | return '%s/%s' % (base_url, version_number) 85 | -------------------------------------------------------------------------------- /yabgp/api/code.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """API error code 17 | """ 18 | -------------------------------------------------------------------------------- /yabgp/api/config.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from oslo_config import cfg 17 | 18 | 19 | CONF = cfg.CONF 20 | 21 | rest_server_ops = [ 22 | cfg.StrOpt('bind_host', 23 | default='0.0.0.0', 24 | help='Address to bind the API server to'), 25 | cfg.IntOpt('bind_port', 26 | default=8801, 27 | help='Port the bind the API server to'), 28 | cfg.StrOpt('username', 29 | default='admin', 30 | help='Username for api server'), 31 | cfg.StrOpt('password', 32 | default='admin', 33 | help='Password for api server', 34 | secret=True) 35 | ] 36 | 37 | 38 | keep_alive_ops = [ 39 | cfg.IntOpt( 40 | 'last_time', 41 | default=0, 42 | help='Last time which controller called API to check probe stat' 43 | ) 44 | ] 45 | -------------------------------------------------------------------------------- /yabgp/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/common/__init__.py -------------------------------------------------------------------------------- /yabgp/common/afn.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ 17 | Address family numbers, from 18 | http://www.iana.org/assignments/address-family-numbers 19 | """ 20 | 21 | AFNUM_RESERVED = 0 # Reserved 22 | AFNUM_INET = 1 # IP (IP version 4) 23 | AFNUM_INET6 = 2 # IP6 (IP version 6) 24 | AFNUM_NSAP = 3 # NSAP 25 | AFNUM_HDLC = 4 # HDLC (8-bit multidrop) 26 | AFNUM_BBN1822 = 5 # BBN 1822 27 | AFNUM_802 = 6 # 802 (includes all 802 media plus Ethernet "canonical format") 28 | AFNUM_E163 = 7 # E.163 29 | AFNUM_E164 = 8 # E.164 (SMDS, Frame Relay, ATM) 30 | AFNUM_F69 = 9 # F.69 (Telex) 31 | AFNUM_X121 = 10 # X.121 (X.25, Frame Relay) 32 | AFNUM_IPX = 11 # IPX 33 | AFNUM_ATALK = 12 # Appletalk 34 | AFNUM_DECNET = 13 # Decnet IV 35 | AFNUM_BANYAN = 14 # Banyan Vines 36 | AFNUM_E164NSAP = 15 # E.164 with NSAP format subaddress 37 | AFNUM_DNS = 16 # DNS (Domain Name System) 38 | AFNUM_DISTNAME = 17 # Distinguished Name 39 | AFNUM_AS_NUMBER = 18 # AS Number 40 | AFNUM_XTP_IP4 = 19 # XTP over IP version 4 41 | AFNUM_XTP_IP6 = 20 # XTP over IP version 6 42 | AFNUM_XTP = 21 # XTP native mode XTP 43 | AFNUM_FC_WWPN = 22 # Fibre Channel World-Wide Port Name 44 | AFNUM_FC_WWNN = 23 # Fibre Channel World-Wide Node Name 45 | AFNUM_GWID = 24 # GWID 46 | # draft-kompella-ppvpn-l2vpn 47 | AFNUM_L2VPN = 25 48 | AFNUM_L2VPN_OLD = 196 49 | AFNUM_EIGRP_COMMON = 16384 # EIGRP Common Service Family 50 | AFNUM_EIGRP_IPV4 = 16385 # EIGRP IPv4 Service Family 51 | AFNUM_EIGRP_IPV6 = 16386 # EIGRP IPv6 Service Family 52 | AFNUM_LCAF = 16387 # LISP Canonical Address Format 53 | AFNUM_BGPLS = 16388 # rfc7752 54 | -------------------------------------------------------------------------------- /yabgp/common/flag.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | 17 | class ByteFlag(int): 18 | 19 | FLAGS = [''] 20 | 21 | def dict(self): 22 | bit_list = [] 23 | for i in range(8): 24 | bit_list.append((self >> i) & 1) 25 | bit_list.reverse() 26 | return dict(zip(self.FLAGS, bit_list[:len(self.FLAGS)])) 27 | -------------------------------------------------------------------------------- /yabgp/common/safn.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """RFC 2858 subsequent address family numbers""" 17 | 18 | SAFNUM_UNICAST = 1 19 | SAFNUM_MULCAST = 2 20 | SAFNUM_UNIMULC = 3 21 | SAFNUM_MPLS_LABEL = 4 # rfc3107 22 | SAFNUM_MCAST_VPN = 5 # draft-ietf-l3vpn-2547bis-mcast-bgp-08.txt 23 | SAFNUM_ENCAPSULATION = 7 # rfc5512 24 | SAFNUM_TUNNEL = 64 # draft-nalawade-kapoor-tunnel-safi-02.txt 25 | SAFNUM_VPLS = 65 26 | SAFNUM_MDT = 66 # rfc6037 27 | SAFNUM_EVPN = 70 # RFC 7432 28 | SAFNUM_BGPLS = 71 29 | SAFNUM_SRTE = 73 30 | SAFNUM_LAB_VPNUNICAST = 128 # Draft-rosen-rfc2547bis-03 31 | SAFNUM_LAB_VPNMULCAST = 129 32 | SAFNUM_LAB_VPNUNIMULC = 130 33 | SAFNUM_ROUTE_TARGET = 132 # RFC 4684 Constrained Route Distribution for BGP/MPLS IP VPN 34 | SAFNUM_FSPEC_RULE = 133 # RFC 5575 BGP flow spec SAFI 35 | SAFNUM_FSPEC_VPN_RULE = 134 # RFC 5575 BGP flow spec SAFI VPN 36 | -------------------------------------------------------------------------------- /yabgp/common/tlv.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | 19 | class TLV(object): 20 | """TLV basic class 21 | """ 22 | TYPE = -1 23 | TYPE_STR = "UNKNOWN" 24 | 25 | def __init__(self, value): 26 | self.value = value 27 | 28 | def __str__(self): 29 | return '%s: %s' % (self.TYPE_STR, self.value) 30 | 31 | @classmethod 32 | def parse(cls, value, typecode=-1): 33 | return cls(value={'type': typecode, 'value': binascii.b2a_hex(value)}) 34 | 35 | def dict(self): 36 | return {self.TYPE_STR: self.value} 37 | -------------------------------------------------------------------------------- /yabgp/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/core/__init__.py -------------------------------------------------------------------------------- /yabgp/core/timer.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2007 by Mark Bergsma 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | """ BGP Timer""" 16 | 17 | # Twisted modules 18 | from twisted.internet import reactor, error 19 | 20 | 21 | class BGPTimer(object): 22 | """ 23 | Timer class with a slightly different Timer interface than the 24 | Twisted DelayedCall interface 25 | """ 26 | 27 | def __init__(self, call_able, name): 28 | 29 | self.name = name 30 | self.status = False 31 | self.delayed_call = None 32 | self.callable = call_able 33 | 34 | def cancel(self): 35 | 36 | """Cancels the timer if it was running, does nothing otherwise""" 37 | 38 | try: 39 | self.delayed_call.cancel() 40 | self.status = False 41 | except (AttributeError, error.AlreadyCalled, error.AlreadyCancelled): 42 | pass 43 | 44 | def reset(self, seconds_fromnow): 45 | """Resets an already running timer, or starts it if it wasn't running. 46 | 47 | :param seconds_fromnow : restart timer 48 | """ 49 | 50 | try: 51 | self.status = True 52 | self.delayed_call.reset(seconds_fromnow) 53 | except (AttributeError, error.AlreadyCalled, error.AlreadyCancelled): 54 | self.delayed_call = reactor.callLater(seconds_fromnow, self.callable) 55 | 56 | def active(self): 57 | """Returns True if the timer was running, False otherwise.""" 58 | 59 | try: 60 | self.status = True 61 | return self.delayed_call.active() 62 | except AttributeError: 63 | return False 64 | -------------------------------------------------------------------------------- /yabgp/handler/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | import abc 4 | import logging 5 | from queue import Queue 6 | 7 | 8 | LOG = logging.getLogger(__name__) 9 | 10 | 11 | class BaseHandler(object): 12 | __metaclass__ = abc.ABCMeta 13 | 14 | def __init__(self): 15 | """ 16 | internal message queue: 17 | push message in custom handler 18 | pop message when keep alive received 19 | """ 20 | self.inter_mq = Queue() 21 | pass 22 | 23 | @abc.abstractmethod 24 | def init(self): 25 | raise NotImplemented 26 | 27 | @abc.abstractmethod 28 | def on_update_error(self, peer, timestamp, msg): 29 | raise NotImplemented 30 | 31 | @abc.abstractmethod 32 | def update_received(self, peer, timestamp, msg): 33 | raise NotImplemented 34 | 35 | @abc.abstractmethod 36 | def keepalive_received(self, peer, timestamp): 37 | raise NotImplemented 38 | 39 | @abc.abstractmethod 40 | def open_received(self, peer, timestamp, result): 41 | raise NotImplemented 42 | 43 | @abc.abstractmethod 44 | def send_open(self, peer, timestamp, result): 45 | raise NotImplemented 46 | 47 | @abc.abstractmethod 48 | def route_refresh_received(self, peer, msg, msg_type): 49 | raise NotImplemented 50 | 51 | @abc.abstractmethod 52 | def notification_received(self, peer, msg): 53 | raise NotImplemented 54 | 55 | @abc.abstractmethod 56 | def on_connection_lost(self, peer): 57 | raise NotImplemented 58 | 59 | @abc.abstractmethod 60 | def on_connection_failed(self, peer, msg): 61 | raise NotImplemented 62 | 63 | @abc.abstractmethod 64 | def on_established(self, peer, msg): 65 | raise NotImplemented 66 | -------------------------------------------------------------------------------- /yabgp/message/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/message/__init__.py -------------------------------------------------------------------------------- /yabgp/message/attribute/atomicaggregate.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.message.attribute import Attribute 19 | from yabgp.message.attribute import AttributeID 20 | from yabgp.message.attribute import AttributeFlag 21 | from yabgp.common import constants as bgp_cons 22 | from yabgp.common import exception as excep 23 | 24 | 25 | class AtomicAggregate(Attribute): 26 | """ 27 | ATOMIC_AGGREGATE is a well-known discretionary attribute of length 0. 28 | """ 29 | 30 | ID = AttributeID.ATOMIC_AGGREGATE 31 | FLAG = AttributeFlag.TRANSITIVE 32 | 33 | @classmethod 34 | def parse(cls, value): 35 | 36 | """ 37 | parse bgp ATOMIC_AGGREGATE attribute 38 | :param value: 39 | """ 40 | if not value: 41 | # return value 42 | # return str(value, encoding="utf-8") 43 | return bytes.decode(value) 44 | else: 45 | raise excep.UpdateMessageError( 46 | sub_error=bgp_cons.ERR_MSG_UPDATE_OPTIONAL_ATTR, 47 | data=value) 48 | 49 | @classmethod 50 | def construct(cls, value): 51 | """construct a ATOMIC_AGGREGATE path attribute 52 | :param value: 53 | """ 54 | 55 | if value: 56 | raise excep.UpdateMessageError( 57 | sub_error=bgp_cons.ERR_MSG_UPDATE_OPTIONAL_ATTR, 58 | data='') 59 | else: 60 | value = 0 61 | return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ 62 | + struct.pack('!B', value) 63 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/admingroup.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class AdminGroup(TLV): 24 | """ 25 | admin group 26 | """ 27 | TYPE = 1088 28 | TYPE_STR = 'admin_group' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | 33 | return cls(value=int(binascii.b2a_hex(data), 16)) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/extend_admin_group.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Type | Length | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # // Extended Administrative Groups (variable) // 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | 28 | 29 | @LinkState.register() 30 | class ExtendedAdminGroup(TLV): 31 | """ 32 | extended administrative groups 33 | """ 34 | TYPE = 1173 35 | TYPE_STR = 'extended_admin_group' 36 | 37 | @classmethod 38 | def unpack(cls, data): 39 | return cls(value=binascii.b2a_hex(data).decode('utf-8')) 40 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/igp_metric.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | import binascii 18 | 19 | from yabgp.tlv import TLV 20 | from ..linkstate import LinkState 21 | 22 | 23 | @LinkState.register() 24 | class IGPMetric(TLV): 25 | """ 26 | IGP Metric 27 | """ 28 | TYPE = 1095 29 | TYPE_STR = 'igp_metric' 30 | 31 | @classmethod 32 | def unpack(cls, data): 33 | if len(data) == 2: 34 | return cls(value=struct.unpack('!H', data)[0]) 35 | elif len(data) == 1: 36 | return cls(value=ord(data[0:1])) 37 | elif len(data) == 3: 38 | return cls(value=int(binascii.b2a_hex(data), 16)) 39 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/link_identifiers.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Link Local Identifier | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # | Link Remote Identifier | 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | 28 | 29 | @LinkState.register() 30 | class LinkIdentifiers(TLV): 31 | """ 32 | link local/remote identifiers 33 | """ 34 | TYPE = 258 # RFC 7752 35 | TYPE_STR = 'link_identifiers' 36 | 37 | @classmethod 38 | def unpack(cls, data): 39 | local_identifier = struct.unpack('!I', data[:4])[0] 40 | remote_identifier = struct.unpack('!I', data[4:])[0] 41 | 42 | return cls(value={'local_identifier': local_identifier, 'remote_identifier': remote_identifier}) 43 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/link_msd.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register(_type=1110) 23 | @LinkState.register(_type=267) 24 | class LinkMSD(TLV): 25 | """ 26 | link msd 27 | """ 28 | # TYPE = 1110 # https://tools.ietf.org/html/draft-tantsura-idr-bgp-ls-segment-routing-msd-05#section-4 29 | TYPE_STR = 'link_msd' 30 | 31 | @classmethod 32 | def unpack(cls, data): 33 | _type, value = struct.unpack('!BB', data) 34 | return cls(value={"type": _type, "value": value}) 35 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/link_name.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class LinkName(TLV): 24 | """ 25 | link name 26 | """ 27 | TYPE = 1098 28 | TYPE_STR = 'link_name' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | 33 | return cls(value=binascii.b2a_uu(data)) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/max_bw.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class MaxBandwidth(TLV): 24 | """ 25 | max bandwidth 26 | """ 27 | TYPE = 1089 28 | TYPE_STR = 'max_bandwidth' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | 33 | return cls(value=struct.unpack('!f', data)[0]) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/max_rsv_bw.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class MaxResvBandwidth(TLV): 24 | """ 25 | max reserved bandwidth 26 | """ 27 | TYPE = 1090 28 | TYPE_STR = 'max_rsv_bandwidth' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | 33 | return cls(value=struct.unpack('!f', data)[0]) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/min_max_link_delay.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register(_type=1115) 23 | class MinMaxUnidirectLinkDelay(TLV): 24 | """ 25 | Min/Max Unidirectional Link Delay 26 | """ 27 | # TYPE = 1115 # https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-10#section-3.2 28 | TYPE_STR = 'min_max_unidirect_link_delay' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | min_value = int(binascii.b2a_hex(data[:4]), 16) 33 | max_value = int(binascii.b2a_hex(data[4:]), 16) 34 | return cls(value={ 35 | "min_link_delay": min_value, 36 | "max_link_delay": max_value, 37 | }) 38 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/mplsmask.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.message.attribute.linkstate.linkstate import LinkState 17 | from yabgp.tlv import TLV 18 | 19 | # https://tools.ietf.org/html/rfc7752#section-3.3.2.2 20 | # 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 21 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 22 | # | Type | Length | 23 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 24 | # |L|R| Reserved | 25 | # +-+-+-+-+-+-+-+-+ 26 | 27 | # +------------+------------------------------------------+-----------+ 28 | # | Bit | Description | Reference | 29 | # +------------+------------------------------------------+-----------+ 30 | # | 'L' | Label Distribution Protocol (LDP) | [RFC5036] | 31 | # | 'R' | Extension to RSVP for LSP Tunnels | [RFC3209] | 32 | # | | (RSVP-TE) | | 33 | # | 'Reserved' | Reserved for future use | | 34 | # +------------+------------------------------------------+-----------+ 35 | 36 | 37 | @LinkState.register() 38 | class MplsMask(TLV): 39 | 40 | TYPE = 1094 # https://tools.ietf.org/html/rfc7752#section-3.3.2.2 41 | TYPE_STR = "mpls_mask" 42 | 43 | @classmethod 44 | def unpack(cls, value): 45 | """ 46 | """ 47 | value = ord(value[0:1]) 48 | L = value >> 7 49 | R = (value << 1) % 256 >> 7 50 | return cls(value={'L': L, 'R': R}) 51 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/opa_link_attr.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | from yabgp.message.attribute.linkstate.linkstate import LinkState 18 | from yabgp.tlv import TLV 19 | 20 | # https://tools.ietf.org/html/rfc7752#section-3.3.2.6 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Type | Length | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # // Opaque link attributes (variable) // 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | 28 | 29 | @LinkState.register() 30 | class OpaLinkAttr(TLV): 31 | 32 | TYPE = 1097 # https://tools.ietf.org/html/rfc7752#section-3.3.2.6 33 | TYPE_STR = "opa_link_attr" 34 | 35 | @classmethod 36 | def unpack(cls, value): 37 | """ 38 | """ 39 | return cls(value=struct.unpack("!%ds" % len(value), value)[0]) 40 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/peer_adj_sid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | # 0 1 2 3 23 | # 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 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # | Type | Length | 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | # | Flags | Weight | Reserved | 28 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29 | # | SID/Label/Index (variable) | 30 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 31 | 32 | # 0 1 2 3 4 5 6 7 33 | # +-+-+-+-+-+-+-+-+ 34 | # |V|L|B|P| | 35 | # +-+-+-+-+-+-+-+-+ 36 | 37 | 38 | @LinkState.register() 39 | class PeerAdjSID(TLV): 40 | """ 41 | Peer Adjacency Segment Identifier (Peer-Adj-SID) 42 | """ 43 | TYPE = 1102 44 | TYPE_STR = 'peer_adj_sid' 45 | 46 | @classmethod 47 | def unpack(cls, data): 48 | flags = ord(data[0:1]) 49 | flag = {} 50 | flag['V'] = flags >> 7 51 | flag['L'] = (flags << 1) % 256 >> 7 52 | flag['B'] = (flags << 2) % 256 >> 7 53 | flag['P'] = (flags << 3) % 256 >> 7 54 | weight = ord(data[1:2]) 55 | return cls(value={"flags": flag, "weight": weight, "value": int(binascii.b2a_hex(data[4:]), 16)}) 56 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/peer_node_sid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | # 0 1 2 3 23 | # 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 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # | Type | Length | 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | # | Flags | Weight | Reserved | 28 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29 | # | SID/Label/Index (variable) | 30 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 31 | 32 | # 0 1 2 3 4 5 6 7 33 | # +-+-+-+-+-+-+-+-+ 34 | # |V|L|B|P| | 35 | # +-+-+-+-+-+-+-+-+ 36 | 37 | 38 | @LinkState.register() 39 | class PeerNodeSID(TLV): 40 | """ 41 | Peer Node Segment Identifier (Peer-Node-SID) 42 | """ 43 | TYPE = 1101 44 | TYPE_STR = 'peer_node_sid' 45 | 46 | @classmethod 47 | def unpack(cls, data): 48 | flags = ord(data[0:1]) 49 | flag = {} 50 | flag['V'] = flags >> 7 51 | flag['L'] = (flags << 1) % 256 >> 7 52 | flag['B'] = (flags << 2) % 256 >> 7 53 | flag['P'] = (flags << 3) % 256 >> 7 54 | weight = ord(data[1:2]) 55 | return cls(value={"flags": flag, "weight": weight, "value": int(binascii.b2a_hex(data[4:]), 16)}) 56 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/peer_set_sid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | # 0 1 2 3 23 | # 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 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # | Type | Length | 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | # | Flags | Weight | Reserved | 28 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29 | # | SID/Label/Index (variable) | 30 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 31 | 32 | # 0 1 2 3 4 5 6 7 33 | # +-+-+-+-+-+-+-+-+ 34 | # |V|L|B|P| | 35 | # +-+-+-+-+-+-+-+-+ 36 | 37 | 38 | @LinkState.register() 39 | class PeerSetSID(TLV): 40 | """ 41 | Peer Set Segment Identifier (Peer-Set-SID) 42 | """ 43 | TYPE = 1103 44 | TYPE_STR = 'peer_set_sid' 45 | 46 | @classmethod 47 | def unpack(cls, data): 48 | flags = ord(data[0:1]) 49 | flag = {} 50 | flag['V'] = flags >> 7 51 | flag['L'] = (flags << 1) % 256 >> 7 52 | flag['B'] = (flags << 2) % 256 >> 7 53 | flag['P'] = (flags << 3) % 256 >> 7 54 | weight = ord(data[1:2]) 55 | return cls(value={"flags": flag, "weight": weight, "value": int(binascii.b2a_hex(data[4:]), 16)}) 56 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/protection_type.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.message.attribute.linkstate.linkstate import LinkState 17 | from yabgp.tlv import TLV 18 | 19 | # https://tools.ietf.org/html/rfc5307#section-1.2 20 | # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 21 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 22 | # |Protection Cap | Reserved | 23 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 24 | 25 | # 0x01 Extra Traffic 26 | # 0x02 Unprotected 27 | # 0x04 Shared 28 | # 0x08 Dedicated 1:1 29 | # 0x10 Dedicated 1+1 30 | # 0x20 Enhanced 31 | # 0x40 Reserved 32 | # 0x80 Reserved 33 | 34 | 35 | @LinkState.register() 36 | class ProtectionType(TLV): 37 | 38 | TYPE = 1093 # https://tools.ietf.org/html/rfc5307#section-1.2 39 | TYPE_STR = "protection_type" 40 | 41 | @classmethod 42 | def unpack(cls, value): 43 | """ 44 | """ 45 | value = ord(value[0]) 46 | if value == 0x01: 47 | return cls(value='Extra Traffic') 48 | if value == 0x02: 49 | return cls(value='Unprotected') 50 | if value == 0x04: 51 | return cls(value='Shared') 52 | if value == 0x08: 53 | return cls(value='Dedicated 1:1') 54 | if value == 0x10: 55 | return cls(value='Dedicated 1+1') 56 | if value == 0x20: 57 | return cls(value='Enhanced') 58 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/remote_router_id.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.tlv import TLV 17 | from yabgp.net import IPAddress 18 | from ..linkstate import LinkState 19 | 20 | 21 | @LinkState.register(_type=1030) 22 | @LinkState.register(_type=1031) 23 | class RemoteRouterID(TLV): 24 | """ 25 | remote ipv4 or ipv6 router id 26 | """ 27 | TYPE_STR = 'remote_router_id' 28 | 29 | @classmethod 30 | def unpack(cls, data): 31 | 32 | router_id = IPAddress.unpack(data) 33 | return cls(value=router_id) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/srlg.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | from yabgp.message.attribute.linkstate.linkstate import LinkState 18 | from yabgp.tlv import TLV 19 | 20 | # https://tools.ietf.org/html/rfc7752#section-3.3.2.5 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Type | Length | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # | Shared Risk Link Group Value | 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | # // ............ // 28 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29 | # | Shared Risk Link Group Value | 30 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 31 | 32 | 33 | @LinkState.register() 34 | class SRLGList(TLV): 35 | 36 | TYPE = 1096 # https://tools.ietf.org/html/rfc7752#section-3.3.2.5 37 | TYPE_STR = "shared_risk_link_group" 38 | 39 | @classmethod 40 | def unpack(cls, value): 41 | """ 42 | """ 43 | results = [] 44 | while value: 45 | results.append(struct.unpack('!L', value[:4])[0]) 46 | value = value[4:] 47 | return cls(value=results) 48 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/srv6_sid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.tlv import TLV 17 | from ..linkstate import LinkState 18 | 19 | 20 | @LinkState.register() 21 | class SRv6SID(TLV): 22 | """ 23 | SRv6 SID Structure 24 | """ 25 | TYPE = 1252 # https://datatracker.ietf.org/doc/html/draft-ietf-idr-bgpls-srv6-ext-09#section-8 26 | TYPE_STR = 'srv6_sid' 27 | 28 | @classmethod 29 | def unpack(cls, data): 30 | # Note: "data" is "sub_tlvs_value", does not contains "sub_tlvs_type_code" & "sub_tlvs_length" 31 | return cls(value={ 32 | 'locator_block_length': ord(data[:1]), 33 | 'locator_node_length': ord(data[1:2]), 34 | 'function_length': ord(data[2:3]), 35 | 'argument_length': ord(data[3:4]) 36 | }) 37 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/te_metric.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class TeMetric(TLV): 24 | """ 25 | TE metric 26 | """ 27 | TYPE = 1092 28 | TYPE_STR = 'te_metric' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | 33 | return cls(value=struct.unpack('!L', data)[0]) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/unidirect_avail_bw.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register(_type=1119) 23 | class UnidirectAvailBw(TLV): 24 | """ 25 | Unidirectional Delay Variation 26 | """ 27 | # TYPE = 1116 # https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-10#section-3.6 28 | TYPE_STR = 'unidirect_avail_bw' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | value = int(binascii.b2a_hex(data), 16) 33 | return cls(value=value) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/unidirect_bw_util.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register(_type=1120) 23 | class UnidirectBwUtil(TLV): 24 | """ 25 | Unidirectional Delay Variation 26 | """ 27 | # TYPE = 1116 # https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-10#section-3.7 28 | TYPE_STR = 'unidirect_bw_util' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | value = int(binascii.b2a_hex(data), 16) 33 | return cls(value=value) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/unidirect_delay_var.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register(_type=1116) 23 | class UnidirectDelayVar(TLV): 24 | """ 25 | Unidirectional Delay Variation 26 | """ 27 | # TYPE = 1116 # https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-10#section-3.3 28 | TYPE_STR = 'unidirect_delay_var' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | value = int(binascii.b2a_hex(data), 16) 33 | return cls(value=value) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/unidirect_link_delay.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register(_type=1114) 23 | class UnidirectLinkDelay(TLV): 24 | """ 25 | link msd 26 | """ 27 | # TYPE = 1114 # https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-10#section-3.1 28 | TYPE_STR = 'unidirect_link_delay' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | value = int(binascii.b2a_hex(data), 16) 33 | return cls(value=value) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/unidirect_packet_loss.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register(_type=1117) 23 | class UnidirectPacketLoss(TLV): 24 | """ 25 | Unidirectional Delay Variation 26 | """ 27 | # TYPE = 1116 # https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-10#section-3.4 28 | TYPE_STR = 'unidirect_packet_loss' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | value = int(binascii.b2a_hex(data), 16) 33 | return cls(value=value) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/unidirect_residual_bw.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register(_type=1118) 23 | class UnidirectResidualBw(TLV): 24 | """ 25 | Unidirectional Delay Variation 26 | """ 27 | # TYPE = 1116 # https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-10#section-3.5 28 | TYPE_STR = 'unidirect_residual_bw' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | value = int(binascii.b2a_hex(data), 16) 33 | return cls(value=value) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/link/unsrv_bw.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class UnrsvBandwidth(TLV): 24 | """ 25 | un reserved bandwidth 26 | """ 27 | TYPE = 1091 28 | TYPE_STR = 'unrsv_bandwidth' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | 33 | value = [p for p in struct.unpack('!ffffffff', data)] 34 | return cls(value=value) 35 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/__init__.py: -------------------------------------------------------------------------------- 1 | # 3.3.1. Node Attribute TLVs 2 | 3 | # Node attribute TLVs are the TLVs that may be encoded in the BGP-LS 4 | # attribute with a Node NLRI. The following Node Attribute TLVs are 5 | # defined: 6 | 7 | # +-------------+----------------------+----------+-------------------+ 8 | # | TLV Code | Description | Length | Reference | 9 | # | Point | | | (RFC/Section) | 10 | # +-------------+----------------------+----------+-------------------+ 11 | # | 263 | Multi-Topology | variable | Section 3.2.1.5 | 12 | # | | Identifier | | | 13 | # | 1024 | Node Flag Bits | 1 | Section 3.3.1.1 | 14 | # | 1025 | Opaque Node | variable | Section 3.3.1.5 | 15 | # | | Attribute | | | 16 | # | 1026 | Node Name | variable | Section 3.3.1.3 | 17 | # | 1027 | IS-IS Area | variable | Section 3.3.1.2 | 18 | # | | Identifier | | | 19 | # | 1028 | IPv4 Router-ID of | 4 | [RFC5305]/4.3 | 20 | # | | Local Node | | | 21 | # | 1029 | IPv6 Router-ID of | 16 | [RFC6119]/4.1 | 22 | # | | Local Node | | | 23 | # +-------------+----------------------+----------+-------------------+ 24 | 25 | # +----------------+-----------------+----------+---------------+ 26 | # | TLV Code Point | Description | Length | Section | 27 | # +----------------+-----------------+----------+---------------+ 28 | # | 1034 | SR Capabilities | variable | Section 2.1.1 | 29 | # | 1035 | SR Algorithm | variable | Section 2.1.2 | 30 | # | 1036 | SR Local Block | variable | Section 2.1.3 | 31 | # | 1037 | SRMS Preference | variable | Section 2.1.4 | 32 | # | 1038 | SRv6 Capabilities | 4 | Section 3.1 | 33 | # +----------------+-----------------+----------+---------------+ 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/isisarea.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class ISISArea(TLV): 24 | """ 25 | isis area id 26 | """ 27 | TYPE = 1027 28 | TYPE_STR = 'isis_area_id' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | return cls(value=binascii.b2a_hex(data).decode('utf-8')) 33 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/local_router_id.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.net import IPAddress 17 | from yabgp.tlv import TLV 18 | from ..linkstate import LinkState 19 | 20 | 21 | @LinkState.register(_type=1028) 22 | class LocalRouterID(TLV): 23 | """ 24 | local ipv4 router id 25 | """ 26 | TYPE_STR = 'local_router_id' 27 | 28 | @classmethod 29 | def unpack(cls, data): 30 | router_id = IPAddress.unpack(data) 31 | return cls(value=router_id) 32 | 33 | 34 | @LinkState.register(_type=1029) 35 | class LocalRouterIDIPv6(TLV): 36 | """ 37 | local ipv6 router id 38 | """ 39 | TYPE_STR = 'local_router_id_ipv6' 40 | 41 | @classmethod 42 | def unpack(cls, data): 43 | router_id = IPAddress.unpack(data) 44 | return cls(value=router_id) 45 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/name.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.tlv import TLV 17 | from ..linkstate import LinkState 18 | 19 | 20 | @LinkState.register() 21 | class NodeName(TLV): 22 | """ 23 | node name 24 | """ 25 | TYPE = 1026 26 | TYPE_STR = 'node_name' 27 | 28 | @classmethod 29 | def unpack(cls, data): 30 | 31 | return cls(value=data.decode('ascii')) 32 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/node_msd.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register(_type=1050) 23 | class NodeMSD_1050(TLV): 24 | """ 25 | node msd, type 1050 26 | https://tools.ietf.org/html/draft-tantsura-idr-bgp-ls-segment-routing-msd-05#section-3 27 | """ 28 | 29 | TYPE_STR = 'node_msd' 30 | 31 | @classmethod 32 | def unpack(cls, data): 33 | _type, value = struct.unpack('!BB', data) 34 | return cls(value={"type": _type, "value": value}) 35 | 36 | 37 | @LinkState.register(_type=266) 38 | class NodeMSD_266(TLV): 39 | """ 40 | node msd, type 266 41 | https://tools.ietf.org/html/draft-tantsura-idr-bgp-ls-segment-routing-msd-05#section-3 42 | Node MSD TLV: https://datatracker.ietf.org/doc/html/rfc8814#section-3 43 | IGP MSD-Types: https://www.iana.org/assignments/igp-parameters/igp-parameters.xhtml 44 | """ 45 | 46 | TYPE_STR = 'node_msd' 47 | 48 | @classmethod 49 | def unpack(cls, data): 50 | 51 | lst = [] 52 | for i in range(0, len(data), 2): 53 | # byte_type, byte_value = data[i], data[i+1] 54 | type, value = struct.unpack("!BB", data[i:i+2]) 55 | lst.append({"type": type, "value": value}) 56 | return cls(value=lst) 57 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/nodeflags.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.message.attribute.linkstate.linkstate import LinkState 17 | from yabgp.tlv import TLV 18 | 19 | # https://tools.ietf.org/html/rfc7752#section-3.3.1.1 20 | # 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 21 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 22 | # | Type | Length | 23 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 24 | # |O|T|E|B|R|V| Rsvd| 25 | # +-+-+-+-+-+-+-+-+-+ 26 | # 27 | # +-----------------+-------------------------+------------+ 28 | # | Bit | Description | Reference | 29 | # +-----------------+-------------------------+------------+ 30 | # | 'O' | Overload Bit | [ISO10589] | 31 | # | 'T' | Attached Bit | [ISO10589] | 32 | # | 'E' | External Bit | [RFC2328] | 33 | # | 'B' | ABR Bit | [RFC2328] | 34 | # | 'R' | Router Bit | [RFC5340] | 35 | # | 'V' | V6 Bit | [RFC5340] | 36 | # | Reserved (Rsvd) | Reserved for future use | | 37 | # +-----------------+-------------------------+------------+ 38 | 39 | 40 | @LinkState.register() 41 | class NodeFlags(TLV): 42 | 43 | TYPE = 1024 # https://tools.ietf.org/html/rfc7752#section-3.3.1.1 44 | TYPE_STR = "node_flags" 45 | 46 | @classmethod 47 | def unpack(cls, value): 48 | """ 49 | """ 50 | valueByte = ord(value[0:1]) 51 | O = valueByte >> 7 52 | T = (valueByte << 1) % 256 >> 7 53 | E = (valueByte << 2) % 256 >> 7 54 | B = (valueByte << 3) % 256 >> 7 55 | R = (valueByte << 4) % 256 >> 7 56 | V = (valueByte << 5) % 256 >> 7 57 | return cls(value={"O": O, "T": T, "E": E, "B": B, "R": R, "V": V}) 58 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/opa_node_attr.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | from yabgp.message.attribute.linkstate.linkstate import LinkState 18 | from yabgp.tlv import TLV 19 | 20 | # https://tools.ietf.org/html/rfc7752#section-3.3.1.5 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Type | Length | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # // Opaque node attributes (variable) // 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | 28 | 29 | @LinkState.register() 30 | class OpaNodeAttr(TLV): 31 | 32 | TYPE = 1025 # https://tools.ietf.org/html/rfc7752#section-3.3.1.5 33 | TYPE_STR = "opa_node_attr" 34 | 35 | @classmethod 36 | def unpack(cls, value): 37 | """ 38 | """ 39 | return cls(value=struct.unpack("!%ds" % len(value), value)[0]) 40 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/sid_or_label.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | from yabgp.message.attribute.linkstate.linkstate import LinkState 18 | from yabgp.tlv import TLV 19 | 20 | # https://tools.ietf.org/html/draft-ietf-idr-bgp-ls-segment-routing-ext-03#section-2.1.1 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Type | Length | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # | SID/Label (variable) | 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | # If length is set to 3, then the 20 rightmost bits represent a label. 28 | # If length is set to 4, then the value represents a 32 bit SID. 29 | 30 | 31 | @LinkState.register() 32 | class SIDorLabel(TLV): 33 | 34 | TYPE = 1161 # https://tools.ietf.org/html/draft-ietf-idr-bgp-ls-segment-routing-ext-03#section-2.1.1 35 | TYPE_STR = "sid_or_label" 36 | 37 | @classmethod 38 | def unpack(cls, value): 39 | """ 40 | """ 41 | length = len(value) 42 | if length == 3: 43 | return cls(value={"type": "sid", "value": (struct.unpack('!I', b"\x00" + value)[0] << 12) >> 12}) 44 | elif length == 4: 45 | return cls(value={"type": "label", "value": struct.unpack('!I', value)[0]}) 46 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/sr_algorithm.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Type | Length | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # | Algorithm 1 | Algorithm... | Algorithm N | | 26 | # +- -+ 27 | # | | 28 | # + + 29 | 30 | 31 | @LinkState.register() 32 | class SRAlgorithm(TLV): 33 | """ 34 | sr algorithm 35 | """ 36 | TYPE = 1035 # https://tools.ietf.org/html/draft-ietf-idr-bgp-ls-segment-routing-ext-03#section-2.1.3 37 | TYPE_STR = 'sr_algorithm' 38 | 39 | @classmethod 40 | def unpack(cls, data): 41 | if type(data) is str: 42 | results = [struct.unpack('!B', value)[0] for value in data] 43 | else: 44 | results = list(data) 45 | return cls(value=results) 46 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/node/srv6_capabilities.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class SRv6Capabilities(TLV): 24 | """ 25 | SRv6 Capabilities TLV 26 | """ 27 | TYPE = 1038 # https://datatracker.ietf.org/doc/html/draft-ietf-idr-bgpls-srv6-ext-14#section-3.1 28 | TYPE_STR = 'srv6_capabilities' 29 | 30 | @classmethod 31 | def unpack(cls, data, bgpls_pro_id): 32 | """ 33 | 34 | :param data: 35 | :param bgpls_pro_id: 36 | :return: 37 | """ 38 | flags = struct.unpack('!H', data[:2])[0] 39 | flag = {} 40 | if bgpls_pro_id in (1, 2): 41 | # https://datatracker.ietf.org/doc/html/rfc9352#name-srv6-capabilities-sub-tlv 42 | flag['O'] = (flags << 1) % 256 >> 15 43 | elif bgpls_pro_id in (3, 6): 44 | # https://datatracker.ietf.org/doc/html/draft-ietf-lsr-ospfv3-srv6-extensions-09#section-2 45 | flag['O'] = (flags << 1) % 256 >> 15 46 | else: 47 | flag = flags 48 | # reserved = struct.unpack('!H', data[2:4])[0] 49 | 50 | return cls(value={ 51 | 'flags': flag 52 | }) 53 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/prefix/__init__.py: -------------------------------------------------------------------------------- 1 | # +---------------+----------------------+----------+-----------------+ 2 | # | TLV Code | Description | Length | Reference | 3 | # | Point | | | | 4 | # +---------------+----------------------+----------+-----------------+ 5 | # | 1152 | IGP Flags | 1 | Section 3.3.3.1 | 6 | # | 1153 | IGP Route Tag | 4*n | [RFC5130] | 7 | # | 1154 | IGP Extended Route | 8*n | [RFC5130] | 8 | # | | Tag | | | 9 | # | 1155 | Prefix Metric | 4 | [RFC5305] | 10 | # | 1156 | OSPF Forwarding | 4 | [RFC2328] | 11 | # | | Address | | | 12 | # | 1157 | Opaque Prefix | variable | Section 3.3.3.6 | 13 | # | | Attribute | | | 14 | # | 1162 | SRv6 Locator | variable | Section 5.1 | 15 | # +---------------+----------------------+----------+-----------------+ 16 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/prefix/ext_igp_route_tag_list.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | from yabgp.message.attribute.linkstate.linkstate import LinkState 18 | from yabgp.tlv import TLV 19 | 20 | # https://tools.ietf.org/html/rfc7752#section-3.3.3.3 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Type | Length | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # // Extended Route Tag (one or more) // 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | 28 | 29 | @LinkState.register() 30 | class ExtIGPRouteTagList(TLV): 31 | 32 | TYPE = 1154 # https://tools.ietf.org/html/rfc7752#section-3.3.3.3 33 | TYPE_STR = "ext_igp_route_tag_list" 34 | 35 | @classmethod 36 | def unpack(cls, value): 37 | """ 38 | """ 39 | results = [] 40 | while value: 41 | results.append(struct.unpack('!Q', value[:8])[0]) 42 | value = value[8:] 43 | return cls(value=results) 44 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/prefix/igp_route_tag_list.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | from yabgp.message.attribute.linkstate.linkstate import LinkState 18 | from yabgp.tlv import TLV 19 | 20 | # https://tools.ietf.org/html/rfc7752#section-3.3.3.2 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Type | Length | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # // Route Tags (one or more) // 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | 28 | 29 | @LinkState.register() 30 | class IGPRouteTagList(TLV): 31 | 32 | TYPE = 1153 # https://tools.ietf.org/html/rfc7752#section-3.3.3.2 33 | TYPE_STR = "igp_route_tag_list" 34 | 35 | @classmethod 36 | def unpack(cls, value): 37 | """ 38 | """ 39 | results = [] 40 | while value: 41 | results.append(struct.unpack('!I', value[:4])[0]) 42 | value = value[4:] 43 | return cls(value=results) 44 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/prefix/igpflags.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.message.attribute.linkstate.linkstate import LinkState 17 | from yabgp.tlv import TLV 18 | 19 | # https://tools.ietf.org/html/rfc7752#section-3.3.3.1 20 | # 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 21 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 22 | # | Type | Length | 23 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 24 | # |D|N|L|P| Resvd.| 25 | # +-+-+-+-+-+-+-+-+ 26 | 27 | # +----------+---------------------------+-----------+ 28 | # | Bit | Description | Reference | 29 | # +----------+---------------------------+-----------+ 30 | # | 'D' | IS-IS Up/Down Bit | [RFC5305] | 31 | # | 'N' | OSPF "no unicast" Bit | [RFC5340] | 32 | # | 'L' | OSPF "local address" Bit | [RFC5340] | 33 | # | 'P' | OSPF "propagate NSSA" Bit | [RFC5340] | 34 | # | Reserved | Reserved for future use. | | 35 | # +----------+---------------------------+-----------+ 36 | 37 | 38 | @LinkState.register() 39 | class IGPFlags(TLV): 40 | 41 | TYPE = 1152 # https://tools.ietf.org/html/rfc7752#section-3.3.3.1 42 | TYPE_STR = "igp_flags" 43 | 44 | @classmethod 45 | def unpack(cls, value): 46 | """ 47 | """ 48 | value = ord(value[0:1]) 49 | D = value >> 7 50 | N = (value << 1) % 256 >> 7 51 | L = (value << 2) % 256 >> 7 52 | P = (value << 3) % 256 >> 7 53 | return cls(value={'D': D, 'N': N, 'L': L, 'P': P}) 54 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/prefix/ospf_forward_addr.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.message.attribute.linkstate.linkstate import LinkState 19 | from yabgp.common.tlv import TLV 20 | 21 | import netaddr 22 | 23 | 24 | @LinkState.register() 25 | class OspfForwardingAddr(TLV): 26 | 27 | TYPE = 1156 28 | TYPE_STR = "ospf_forwarding_address" 29 | 30 | @classmethod 31 | def parse(cls, value): 32 | """ 33 | """ 34 | return cls(value=str(netaddr.IPAddress(int(binascii.b2a_hex(value), 16)))) 35 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/prefix/prefix_igp_attr.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | # 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 22 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | # | Type | Length | 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # // Flags (variable) // 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | 28 | 29 | @LinkState.register() 30 | class PrefixIGPAttr(TLV): 31 | """ 32 | prefix igp attr 33 | """ 34 | TYPE = 1170 35 | TYPE_STR = 'prefix_igp_attr' 36 | 37 | @classmethod 38 | def unpack(cls, data): 39 | return cls(value=int(binascii.b2a_hex(data), 16)) 40 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/prefix/prefix_metric.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class PrefixMetric(TLV): 24 | """ 25 | prefix metric 26 | """ 27 | TYPE = 1155 28 | TYPE_STR = 'prefix_metric' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | 33 | return cls(value=struct.unpack('!L', data)[0]) 34 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/prefix/src_router_id.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | import binascii 19 | import netaddr 20 | 21 | from yabgp.tlv import TLV 22 | from ..linkstate import LinkState 23 | 24 | 25 | # 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 26 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | # | Type | Length | 28 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29 | # // IPv4/IPv6 Address (Router-ID) // 30 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 31 | 32 | 33 | @LinkState.register() 34 | class SrcRouterID(TLV): 35 | """ 36 | source router id 37 | """ 38 | TYPE = 1171 39 | TYPE_STR = 'source_router_id' 40 | 41 | @classmethod 42 | def unpack(cls, data): 43 | if len(data) == 4: 44 | return cls(value=str(netaddr.IPAddress(struct.unpack('!I', data)[0]))) 45 | elif len(data) == 16: 46 | return cls(value=str(netaddr.IPAddress(int(binascii.b2a_hex(data), 16)))) 47 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/prefix/srv6_locator.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | import binascii 19 | 20 | from yabgp.tlv import TLV 21 | from ..linkstate import LinkState 22 | 23 | 24 | @LinkState.register() 25 | class SRv6Locator(TLV): 26 | """ 27 | SRv6 Locator TLV 28 | """ 29 | TYPE = 1162 # https://datatracker.ietf.org/doc/html/draft-ietf-idr-bgpls-srv6-ext-14#section-5.1 30 | TYPE_STR = 'srv6_locator' 31 | 32 | @classmethod 33 | def unpack(cls, data, bgpls_pro_id): 34 | """ 35 | 36 | :param data: 37 | :param bgpls_pro_id: 38 | :return: 39 | """ 40 | flags = ord(data[:1]) 41 | flag = {} 42 | if bgpls_pro_id in (1, 2): # IS-IS 43 | # https://datatracker.ietf.org/doc/html/rfc9352#section-7.1 44 | flag['D'] = flags >> 7 45 | else: 46 | flag = flags # TODO (OSPFv3 SRv6) 47 | algorithm = ord(data[1:2]) 48 | # reserved = struct.unpack('!H', data[2:4])[0] 49 | metric = struct.unpack('!I', data[4:8])[0] 50 | sub_tlvs_bin_data = data[8:] 51 | 52 | sub_tlvs = [] 53 | while sub_tlvs_bin_data: 54 | sub_tlvs_type_code, sub_tlvs_length = struct.unpack('!HH', sub_tlvs_bin_data[:4]) 55 | sub_tlvs_value = sub_tlvs_bin_data[4: 4 + sub_tlvs_length] 56 | 57 | if sub_tlvs_type_code in LinkState.registered_tlvs: 58 | # Note: "sub_tlvs_value" does not contains "sub_tlvs_type_code" & "sub_tlvs_length" 59 | sub_tlvs.append(LinkState.registered_tlvs[sub_tlvs_type_code].unpack(sub_tlvs_value).dict()) 60 | else: 61 | sub_tlvs.append({ 62 | 'type': sub_tlvs_type_code, 63 | 'value': str(binascii.b2a_hex(sub_tlvs_value)) 64 | }) 65 | sub_tlvs_bin_data = sub_tlvs_bin_data[4 + sub_tlvs_length:] 66 | 67 | return cls(value={ 68 | 'flags': flag, 69 | 'algorithm': algorithm, 70 | # 'reserved': reserved, 71 | 'metric': metric, 72 | 'sub_tlvs': sub_tlvs 73 | }) 74 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/srv6_sid/__init__.py: -------------------------------------------------------------------------------- 1 | # +---------------+------------------------+----------+-----------------+ 2 | # | TLV Code | Description | Length | Reference | 3 | # | Point | | | | 4 | # +---------------+------------------------+----------+-----------------+ 5 | # | 1250 | SRv6 Endpoint Behavior | 4 | Section 7.1 | 6 | # | 1251 | SRv6 BGP Peer Node SID | 12 | Section 7.2 | 7 | # +---------------+------------------------+----------+-----------------+ 8 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/srv6_sid/srv6_bgp_peer_node_sid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class SRv6BGPPeerNodeSID(TLV): 24 | """ 25 | SRv6 BGP Peer Node SID 26 | """ 27 | TYPE = 1251 # https://datatracker.ietf.org/doc/html/draft-ietf-idr-bgpls-srv6-ext-14#section-7.2 28 | TYPE_STR = 'srv6_bgp_peer_node_sid' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | """ 33 | 34 | :param data: 35 | :return: 36 | """ 37 | flags = ord(data[0:1]) 38 | flag = {} 39 | flag['B'] = flags >> 7 40 | flag['S'] = (flags << 1) % 256 >> 7 41 | flag['P'] = (flags << 2) % 256 >> 7 42 | weight = ord(data[1:2]) 43 | # reserved = struct.unpack('!H', data[2:4])[0] 44 | peer_as_number = '.'.join([str(each) for each in struct.unpack('!HH', data[4:8])]) 45 | peer_bgp_identifier = struct.unpack('!I', data[8:12])[0] 46 | 47 | return cls(value={ 48 | 'flags': flag, 49 | 'weight': weight, 50 | # 'reserved': reserved, 51 | 'peer_as_number': peer_as_number, 52 | 'peer_bgp_identifier': peer_bgp_identifier 53 | }) 54 | -------------------------------------------------------------------------------- /yabgp/message/attribute/linkstate/srv6_sid/srv6_endpoint_behavior.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.tlv import TLV 19 | from ..linkstate import LinkState 20 | 21 | 22 | @LinkState.register() 23 | class SRv6EndpointBehavior(TLV): 24 | """ 25 | SRv6 Endpoint Behavior 26 | """ 27 | TYPE = 1250 # https://datatracker.ietf.org/doc/html/draft-ietf-idr-bgpls-srv6-ext-14#section-7.1 28 | TYPE_STR = 'srv6_endpoint_behavior' 29 | 30 | @classmethod 31 | def unpack(cls, data): 32 | """ 33 | 34 | :param data: 35 | :return: 36 | """ 37 | endpoint_behavior = struct.unpack('!H', data[0:2])[0] 38 | flags = ord(data[2:3]) 39 | algorithm = ord(data[3:4]) 40 | 41 | return cls(value={ 42 | 'endpoint_behavior': endpoint_behavior, 43 | 'flags': flags, 44 | 'algorithm': algorithm 45 | }) 46 | -------------------------------------------------------------------------------- /yabgp/message/attribute/localpref.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.message.attribute import Attribute 19 | from yabgp.message.attribute import AttributeID 20 | from yabgp.message.attribute import AttributeFlag 21 | from yabgp.common import constants as bgp_cons 22 | from yabgp.common import exception as excep 23 | 24 | 25 | class LocalPreference(Attribute): 26 | """LOCAL_PREF is a well-known attribute that is a four-octet 27 | unsigned integer. A BGP speaker uses it to inform its other 28 | internal peers of the advertising speaker's degree of 29 | preference for an advertised route. 30 | """ 31 | 32 | ID = AttributeID.LOCAL_PREF 33 | FLAG = AttributeFlag.TRANSITIVE 34 | MULTIPLE = False 35 | 36 | @classmethod 37 | def parse(cls, value): 38 | 39 | """ 40 | parse bgp local preference attribute 41 | :param value: raw binary value 42 | """ 43 | try: 44 | return struct.unpack('!I', value)[0] 45 | except: 46 | raise excep.UpdateMessageError( 47 | sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, 48 | data=value) 49 | 50 | @classmethod 51 | def construct(cls, value): 52 | """ 53 | encode bgp local preference attribute 54 | :param value: interger value 55 | """ 56 | try: 57 | return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ 58 | + struct.pack('!B', 4) + struct.pack('!I', value) 59 | except Exception: 60 | raise excep.UpdateMessageError( 61 | sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, 62 | data='') 63 | -------------------------------------------------------------------------------- /yabgp/message/attribute/med.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | from yabgp.message.attribute import Attribute 19 | from yabgp.message.attribute import AttributeID 20 | from yabgp.message.attribute import AttributeFlag 21 | from yabgp.common import constants as bgp_cons 22 | from yabgp.common import exception as excep 23 | 24 | 25 | class MED(Attribute): 26 | """ 27 | This is an optional non-transitive attribute that is a 28 | four-octet unsigned integer. The value of this attribute 29 | MAY be used by a BGP speaker's Decision Process to 30 | discriminate among multiple entry points to a neighboring 31 | autonomous system. 32 | """ 33 | 34 | ID = AttributeID.MULTI_EXIT_DISC 35 | FLAG = AttributeFlag.OPTIONAL 36 | MULTIPLE = False 37 | 38 | @classmethod 39 | def parse(cls, value): 40 | """ 41 | parse BGP med attributes 42 | :param value: raw binary value 43 | """ 44 | try: 45 | return struct.unpack('!I', value)[0] 46 | except: 47 | raise excep.UpdateMessageError( 48 | sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, 49 | data=value) 50 | 51 | @classmethod 52 | def construct(cls, value): 53 | """ 54 | encode BGP med attributes 55 | :param value: 56 | """ 57 | try: 58 | return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ 59 | + struct.pack('!B', 4) + struct.pack('!I', value) 60 | except Exception: 61 | raise excep.UpdateMessageError( 62 | sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, 63 | data='') 64 | -------------------------------------------------------------------------------- /yabgp/message/attribute/nlri/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from __future__ import division 17 | import struct 18 | import binascii 19 | 20 | import netaddr 21 | 22 | 23 | class NLRI(object): 24 | 25 | @classmethod 26 | def parse(cls, *args): 27 | 28 | raise NotImplementedError 29 | 30 | @classmethod 31 | def construct(cls, *args): 32 | raise NotImplementedError 33 | 34 | @staticmethod 35 | def construct_prefix_v4(masklen, prefix_str): 36 | ip_hex = struct.pack('!I', netaddr.IPNetwork(prefix_str).value) 37 | if 16 < masklen <= 24: 38 | ip_hex = ip_hex[0:3] 39 | elif 8 < masklen <= 16: 40 | ip_hex = ip_hex[0:2] 41 | elif masklen <= 8: 42 | ip_hex = ip_hex[0:1] 43 | return ip_hex 44 | 45 | @staticmethod 46 | def construct_prefix_v6(prefix): 47 | mask = int(prefix.split('/')[1]) 48 | prefix_hex = binascii.unhexlify(hex(netaddr.IPNetwork(prefix).ip)[2:]) 49 | offset = mask // 8 50 | offset_re = mask % 8 51 | if offset == 0: 52 | return prefix_hex[0: 1] 53 | return prefix_hex[0: offset + offset_re] 54 | 55 | @classmethod 56 | def parse_mpls_label_stack(cls, data): 57 | labels = [] 58 | while len(data) >= 3: 59 | label = struct.unpack('!L', b'\00'+data[:3])[0] 60 | data = data[3:] 61 | labels.append(label >> 4) 62 | if label & 0x001: 63 | break 64 | return labels 65 | 66 | @classmethod 67 | def construct_mpls_label_stack(cls, labels): 68 | data = b'' 69 | last_label = labels[-1] 70 | for label in labels[:-1]: 71 | data += struct.pack('!L', label << 4)[1:] 72 | if last_label != 0: 73 | data += struct.pack('!L', (last_label << 4 | 1))[1:] 74 | else: 75 | data += b'\x00\x00\x00' 76 | return data 77 | -------------------------------------------------------------------------------- /yabgp/message/attribute/nlri/ipv4_mpls_vpn.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | # Copyright 2015 Cisco Systems, Inc. 3 | # All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from yabgp.message.attribute.nlri.mpls_vpn import MPLSVPN 18 | from yabgp.common.afn import AFNUM_INET 19 | from yabgp.common.safn import SAFNUM_LAB_VPNUNICAST 20 | 21 | 22 | class IPv4MPLSVPN(MPLSVPN): 23 | 24 | """ 25 | IPv4 MPLS VPN NLRI 26 | """ 27 | AFI = AFNUM_INET 28 | SAFI = SAFNUM_LAB_VPNUNICAST 29 | 30 | @classmethod 31 | def parse(cls, value, iswithdraw=False, addpath=False): 32 | return super(IPv4MPLSVPN, cls).parse(value, iswithdraw=iswithdraw, addpath=addpath) 33 | 34 | @classmethod 35 | def construct(cls, value, iswithdraw=False): 36 | return super(IPv4MPLSVPN, cls).construct(value, iswithdraw=iswithdraw) 37 | -------------------------------------------------------------------------------- /yabgp/message/attribute/nlri/ipv4_srte.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """IPv4 SR TE Policy NLRI 17 | """ 18 | import struct 19 | import netaddr 20 | 21 | from yabgp.message.attribute.nlri import NLRI 22 | 23 | 24 | class IPv4SRTE(NLRI): 25 | """ 26 | """ 27 | # +------------------+ 28 | # | NLRI Length | 1 octet 29 | # +------------------+ 30 | # | Distinguisher | 4 octets 31 | # +------------------+ 32 | # | Policy Color | 4 octets 33 | # +------------------+ 34 | # | Endpoint | 4 or 16 octets 35 | # +------------------+ 36 | @classmethod 37 | def construct(cls, data): 38 | """ Construct NLRI """ 39 | nlri_tmp = b'' + struct.pack('!I', data['distinguisher']) + \ 40 | struct.pack('!I', data['color']) + \ 41 | netaddr.IPAddress(data['endpoint']).packed 42 | return struct.pack('!B', len(nlri_tmp) * 8) + nlri_tmp 43 | -------------------------------------------------------------------------------- /yabgp/message/attribute/nlri/ipv6_mpls_vpn.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.message.attribute.nlri.mpls_vpn import MPLSVPN 17 | from yabgp.common.afn import AFNUM_INET6 18 | from yabgp.common.safn import SAFNUM_LAB_VPNUNICAST 19 | 20 | 21 | class IPv6MPLSVPN(MPLSVPN): 22 | """ 23 | IPv6 MPLS VPN NLRI 24 | """ 25 | AFI = AFNUM_INET6 26 | SAFI = SAFNUM_LAB_VPNUNICAST 27 | 28 | @classmethod 29 | def parse(cls, value, iswithdraw=False, addpath=False): 30 | return super(IPv6MPLSVPN, cls).parse(value, iswithdraw=iswithdraw, addpath=addpath) 31 | 32 | @classmethod 33 | def construct(cls, value, iswithdraw=False): 34 | return super(IPv6MPLSVPN, cls).construct(value, iswithdraw=iswithdraw) 35 | -------------------------------------------------------------------------------- /yabgp/message/attribute/nlri/labeled_unicast/ipv4.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.message.attribute.nlri.labeled_unicast import LabeledUnicast 17 | from yabgp.common.afn import AFNUM_INET 18 | 19 | 20 | class IPv4LabeledUnicast(LabeledUnicast): 21 | 22 | AFI = AFNUM_INET 23 | -------------------------------------------------------------------------------- /yabgp/message/attribute/nlri/labeled_unicast/ipv6.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.message.attribute.nlri.labeled_unicast import LabeledUnicast 17 | from yabgp.common.afn import AFNUM_INET6 18 | 19 | 20 | class IPv6LabeledUnicast(LabeledUnicast): 21 | 22 | AFI = AFNUM_INET6 23 | -------------------------------------------------------------------------------- /yabgp/message/attribute/originatorid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | import struct 18 | 19 | import netaddr 20 | 21 | from yabgp.message.attribute import Attribute 22 | from yabgp.message.attribute import AttributeFlag 23 | from yabgp.message.attribute import AttributeID 24 | from yabgp.common import exception as excep 25 | from yabgp.common import constants as bgp_cons 26 | 27 | 28 | class OriginatorID(Attribute): 29 | """ 30 | ORIGINATOR_ID is a new optional, non-transitive BGP attribute of Type 31 | code 9. This attribute is 4 bytes long and it will be created by an 32 | RR in reflecting a route. This attribute will carry the BGP 33 | Identifier of the originator of the route in the local AS. A BGP 34 | speaker SHOULD NOT create an ORIGINATOR_ID attribute if one already 35 | exists. A router that recognizes the ORIGINATOR_ID attribute SHOULD 36 | ignore a route received with its BGP Identifier as the ORIGINATOR_ID. 37 | (RFC 4456 Page 6) 38 | """ 39 | 40 | ID = AttributeID.ORIGINATOR_ID 41 | FLAG = AttributeFlag.OPTIONAL 42 | 43 | @classmethod 44 | def parse(cls, value): 45 | 46 | """ 47 | Parse originator id 48 | :param value: 49 | """ 50 | if len(value) != 4: 51 | raise excep.UpdateMessageError( 52 | sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, 53 | data=value) 54 | return str(netaddr.IPAddress(int(binascii.b2a_hex(value[0:4]), 16))) 55 | 56 | @classmethod 57 | def construct(cls, value): 58 | 59 | """ 60 | construct a ORIGINATOR_ID path attribute 61 | :param value: ipv4 format string 62 | """ 63 | try: 64 | return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) \ 65 | + struct.pack('!B', 4) + netaddr.IPAddress(value).packed 66 | except Exception: 67 | raise excep.UpdateMessageError( 68 | sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, 69 | data=value) 70 | -------------------------------------------------------------------------------- /yabgp/message/attribute/sr/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from .bgpprefixsid import BGPPrefixSID # noqa 17 | from .srv6.l3service import SRv6L3Service # noqa 18 | from .srv6.sidinformation import SRv6SIDInformation # noqa 19 | from .srv6.sidstructure import SRv6SIDStructure # noqa 20 | -------------------------------------------------------------------------------- /yabgp/message/attribute/sr/bgpprefixsid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import struct 17 | 18 | import binascii 19 | 20 | from yabgp.message.attribute import Attribute, AttributeFlag, AttributeID 21 | 22 | 23 | class BGPPrefixSID(Attribute): 24 | """ 25 | BGP Prefix SID 26 | 27 | Original: https://datatracker.ietf.org/doc/html/rfc8669#section-3 28 | Extend: https://datatracker.ietf.org/doc/html/rfc9252#section-2 29 | """ 30 | 31 | ID = AttributeID.BGP_PREFIX_SID 32 | FLAG = AttributeFlag.OPTIONAL + AttributeFlag.TRANSITIVE 33 | 34 | registered_tlvs = dict() 35 | 36 | def __init__(self, value, hex_value=None): 37 | self.value = value 38 | self.hex_value = hex_value 39 | 40 | @classmethod 41 | def register(cls, _type=None): 42 | """ 43 | 44 | :param _type: 45 | :return: 46 | """ 47 | 48 | def decorator(klass): 49 | """ 50 | 51 | :param klass: 52 | :return: 53 | """ 54 | _id = klass.TYPE if _type is None else _type 55 | if _id in cls.registered_tlvs: 56 | raise RuntimeError('Duplicated attribute type') 57 | cls.registered_tlvs[_id] = klass 58 | return klass 59 | 60 | return decorator 61 | 62 | @classmethod 63 | def unpack(cls, data): 64 | """ 65 | 66 | :param data: 67 | :return: 68 | """ 69 | tlvs = [] 70 | while data: 71 | type_code = data[0] # Note: Type = 1 octet 72 | length = struct.unpack('!H', data[1:3])[0] # Note: Length = 2 octet 73 | value = data[3: 3 + length] 74 | 75 | if type_code in cls.registered_tlvs: 76 | tlvs.append(cls.registered_tlvs[type_code].unpack(value)) 77 | else: 78 | tlvs.append({ 79 | 'type': type_code, 80 | 'value': str(binascii.b2a_hex(value)) 81 | }) 82 | data = data[3 + length:] 83 | return tlvs 84 | -------------------------------------------------------------------------------- /yabgp/message/attribute/sr/srv6/__init__.py: -------------------------------------------------------------------------------- 1 | # +---------------+---------------------------------+----------+-----------------+ 2 | # | TLV Code | Description | Length | Reference | 3 | # | Point | | | | 4 | # +---------------+---------------------------------+----------+-----------------+ 5 | # | 5 | SRv6 L3 Service TLV | variable | Section 2 | 6 | # | 1 | SRv6 SID Information Sub-TLV | variable | Section 3.1 | 7 | # | 1 | SRv6 SID Structure Sub-Sub-TLV | 6 | Section 3.2.1 | 8 | # +---------------+---------------------------------+----------+-----------------+ 9 | -------------------------------------------------------------------------------- /yabgp/message/attribute/sr/srv6/sidstructure.py: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from yabgp.tlv import TLV 17 | from .sidinformation import SRv6SIDInformation 18 | 19 | 20 | # 3.2.1. SRv6 SID Structure Sub-Sub-TLV 21 | # 22 | # 0 1 2 3 23 | # 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 24 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | # | SRv6 Service | SRv6 Service | Locator Block | 26 | # | Data Sub-Sub | Data Sub-Sub-TLV | Length | 27 | # | -TLV Type=1 | Length | | 28 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29 | # | Locator Node | Function | Argument | Transposition | 30 | # | Length | Length | Length | Length | 31 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 32 | # | Transposition | 33 | # | Offset | 34 | # +-+-+-+-+-+-+-+-+ 35 | # 36 | # Figure 5: SRv6 SID Structure Sub-Sub-TLV 37 | 38 | 39 | @SRv6SIDInformation.register() 40 | class SRv6SIDStructure(TLV): 41 | """ 42 | SRv6 SID Structure 43 | """ 44 | TYPE = 1 # https://datatracker.ietf.org/doc/html/rfc9252.html#section-3.2.1 45 | TYPE_STR = 'srv6_sid_structure' 46 | 47 | @classmethod 48 | def unpack(cls, data): 49 | """ 50 | 51 | :param data: 52 | :return: 53 | """ 54 | locator_block_length = data[0] 55 | locator_node_length = data[1] 56 | function_length = data[2] 57 | argument_length = data[3] 58 | transposition_length = data[4] 59 | transposition_offset = data[5] 60 | value = { 61 | 'locator_block_length': locator_block_length, 62 | 'locator_node_length': locator_node_length, 63 | 'function_length': function_length, 64 | 'argument_length': argument_length, 65 | 'transposition_length': transposition_length, 66 | 'transposition_offset': transposition_offset 67 | } 68 | return {cls.TYPE_STR: value} 69 | -------------------------------------------------------------------------------- /yabgp/message/keepalive.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ BGP KeepAlive message""" 17 | 18 | import struct 19 | 20 | from yabgp.common.exception import MessageHeaderError 21 | from yabgp.common.constants import ERR_MSG_HDR_BAD_MSG_LEN 22 | 23 | 24 | class KeepAlive(object): 25 | 26 | """ 27 | KEEPALIVE messages are exchanged between peers often 28 | enough not to cause the Hold Timer to expire 29 | """ 30 | MSG_KEEPALIVE = 4 31 | 32 | @staticmethod 33 | def parse(msg): 34 | """ 35 | Parse keepalive message 36 | 37 | :param msg: input raw binary message data 38 | """ 39 | if len(msg) != 0: 40 | raise MessageHeaderError( 41 | sub_error=ERR_MSG_HDR_BAD_MSG_LEN, 42 | data='') 43 | 44 | @staticmethod 45 | def construct_header(): 46 | 47 | """Prepends the mandatory header to a constructed BGP message 48 | """ 49 | # 16-octet 2-octet 1-octet 50 | # ---------------+--------+---------+------+ 51 | # Maker | Length | Type | msg | 52 | # ---------------+--------+---------+------+ 53 | return b'\xff'*16 + struct.pack('!HB', 19, 4) 54 | 55 | def construct(self): 56 | """ 57 | Construct a keepalive message 58 | """ 59 | return self.construct_header() 60 | -------------------------------------------------------------------------------- /yabgp/message/notification.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """BGP Notification Message""" 17 | 18 | import struct 19 | 20 | 21 | class Notification(object): 22 | 23 | """ 24 | notification 25 | """ 26 | MSG_NOTIFICATION = 3 27 | 28 | @staticmethod 29 | def parse(message): 30 | """ 31 | parse notification message 32 | 33 | :param message: input raw binary message data 34 | """ 35 | error, suberror = struct.unpack('!BB', message[:2]) 36 | data = message[2:] 37 | return error, suberror, data 38 | 39 | def construct_header(self, message): 40 | 41 | """Prepends the mandatory header to a constructed BGP message 42 | 43 | :param message: 44 | """ 45 | # 16-octet 2-octet 1-octet 46 | # ---------------+--------+---------+------+ 47 | # Maker | Length | Type | msg | 48 | # ---------------+--------+---------+------+ 49 | return b'\xff'*16 + struct.pack('!HB', len(message) + 19, self.MSG_NOTIFICATION) + message 50 | 51 | def construct(self, error, suberror=0, data=b''): 52 | 53 | """Constructs a BGP Notification message 54 | 55 | :param error: 56 | :param suberror: 57 | :param data: 58 | """ 59 | 60 | msg = struct.pack('!BB', error, suberror) + data 61 | return self.construct_header(msg) 62 | -------------------------------------------------------------------------------- /yabgp/net/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import socket 17 | 18 | 19 | class IPAddress(object): 20 | 21 | @staticmethod 22 | def unpack(data): 23 | return socket.inet_ntop(socket.AF_INET if len(data) == 4 else socket.AF_INET6, data) 24 | 25 | @staticmethod 26 | def pack(data): 27 | return socket.inet_pton(socket.AF_INET if len(data.split('.')) == 4 else socket.AF_INET6, data) 28 | 29 | 30 | class IPNetwork(object): 31 | pass 32 | -------------------------------------------------------------------------------- /yabgp/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/api/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/api/test_app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """Test app""" 17 | 18 | import unittest 19 | from yabgp.api.app import app 20 | 21 | 22 | class FlaskrTestCase(unittest.TestCase): 23 | 24 | def setUp(self): 25 | # prepare some peers 26 | self.app = app.test_client() 27 | 28 | def tearDown(self): 29 | """""" 30 | pass 31 | 32 | def test_show_bgp_summary(self): 33 | result = self.app.get('/') 34 | self.assertTrue(result) 35 | 36 | if __name__ == '__main__': 37 | unittest.main() 38 | -------------------------------------------------------------------------------- /yabgp/tests/unit/api/test_v1.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """Test v1 api""" 17 | 18 | import unittest 19 | from yabgp.api.app import app 20 | 21 | 22 | class FlaskrTestCase(unittest.TestCase): 23 | 24 | def setUp(self): 25 | # prepare some peers 26 | self.app = app.test_client() 27 | 28 | def tearDown(self): 29 | """""" 30 | pass 31 | 32 | def test_v1_root(self): 33 | result = self.app.get('/v1') 34 | self.assertTrue(result) 35 | 36 | def test_v1_peers(self): 37 | self.assertTrue(self.app.get('/v1/peers')) 38 | 39 | def test_v1_peer(self): 40 | self.assertTrue(self.app.get('/v1/peer')) 41 | 42 | if __name__ == '__main__': 43 | unittest.main() 44 | -------------------------------------------------------------------------------- /yabgp/tests/unit/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/core/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/core/test_protocol.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """Test BGP protocol 17 | """ 18 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/attribute/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/attribute/linkstate/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/link/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/attribute/linkstate/link/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/link/test_srv6_end_x_sid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test SRv6 End.X SID """ 17 | 18 | import unittest 19 | 20 | from yabgp.message.attribute.linkstate.link.srv6_end_x_sid import SRv6EndXSID 21 | 22 | 23 | class TestSRv6EndXSID(unittest.TestCase): 24 | 25 | def test_unpack(self): 26 | data_bin = b'\x04\x52' \ 27 | b'\x00\x1e' \ 28 | b'\x00\x39' \ 29 | b'\x00' \ 30 | b'\x00' \ 31 | b'\x00' \ 32 | b'\x00' \ 33 | b'\xa0\x01\x00\x00\x00\x05\xe0\x02\x00\x00\x00\x00\x00\x00\x00\x00' \ 34 | b'\x04\xe4' \ 35 | b'\x00\x04' \ 36 | b'\x20\x10\x10\x00' 37 | 38 | data_dict = { 39 | 'type': 'srv6_end_x_sid', 40 | 'value': { 41 | 'endpoint_behavior': 57, 42 | 'flags': { 43 | 'B': 0, 44 | 'S': 0, 45 | 'P': 0 46 | }, 47 | 'algorithm': 0, 48 | 'weight': 0, 49 | 'sid': 'a001:0:5:e002::', 50 | 'sub_tlvs': [ 51 | { 52 | 'type': 'srv6_sid', 53 | 'value': { 54 | 'locator_block_length': 32, 55 | 'locator_node_length': 16, 56 | 'function_length': 16, 57 | 'argument_length': 0 58 | } 59 | } 60 | ] 61 | } 62 | } 63 | # The total of the locator block, locator node, function, and argument lengths MUST be less than or equal to 128 64 | 65 | # Note: data_bin[4:] means does not contain "type_code" & "length" 66 | self.assertEqual(data_dict, SRv6EndXSID.unpack(data_bin[4:]).dict()) 67 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/node/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/attribute/linkstate/node/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/node/test_node_msd.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from yabgp.message.attribute.linkstate.node.node_msd import NodeMSD_266 3 | 4 | 5 | class TestNodeMSD(unittest.TestCase): 6 | 7 | def test_unpack_for_type266(self): 8 | ''' 9 | Node MSD TLV: https://datatracker.ietf.org/doc/html/rfc8814#section-3 10 | IGP MSD-Types: https://www.iana.org/assignments/igp-parameters/igp-parameters.xhtml 11 | ''' 12 | data_bin = b'\x29\x03\x2a\x03\x2b\x03\x2c\x03\x2d\x04' 13 | expected_results = {"type": "node_msd", 14 | "value": [{'type': 41, 'value': 3}, 15 | {'type': 42, 'value': 3}, 16 | {'type': 43, 'value': 3}, 17 | {'type': 44, 'value': 3}, 18 | {'type': 45, 'value': 4}]} 19 | 20 | actual_results = NodeMSD_266.unpack(data=data_bin).dict() 21 | 22 | self.assertEqual(expected_results, actual_results) 23 | 24 | 25 | if __name__ == "__main__": 26 | unittest.main() 27 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/node/test_srv6_capabilities.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test SRv6 Capabilities TLV """ 17 | 18 | import unittest 19 | 20 | from yabgp.message.attribute.linkstate.node.srv6_capabilities import SRv6Capabilities 21 | 22 | 23 | class TestSRv6Capabilities(unittest.TestCase): 24 | 25 | def test_unpack(self): 26 | data_bin = b'\x00' \ 27 | b'\x00' \ 28 | b'\x00' \ 29 | b'\x00' 30 | 31 | data_dict = { 32 | 'type': 'srv6_capabilities', 33 | 'value': { 34 | 'flags': { 35 | 'O': 0 36 | } 37 | }} 38 | for bgpls_pro_id in (1, 2, 3, 6): 39 | self.assertEqual(data_dict, SRv6Capabilities.unpack(data=data_bin, bgpls_pro_id=bgpls_pro_id).dict()) 40 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/prefix/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/attribute/linkstate/prefix/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/prefix/test_srv6_locator.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test SRv6 Locator TLV """ 17 | 18 | import unittest 19 | 20 | from yabgp.message.attribute.linkstate.prefix.srv6_locator import SRv6Locator 21 | 22 | 23 | class TestSRv6Locator(unittest.TestCase): 24 | 25 | def test_unpack(self): 26 | data_bin = b'\x00' \ 27 | b'\x00' \ 28 | b'\x00\x04' \ 29 | b'\x00\x00\x00\x00' 30 | 31 | data_dict = { 32 | 'type': 'srv6_locator', 33 | 'value': { 34 | 'flags': { 35 | 'D': 0 36 | }, 37 | 'algorithm': 0, 38 | 'metric': 0, 39 | 'sub_tlvs': [] 40 | } 41 | } 42 | self.assertEqual(data_dict, SRv6Locator.unpack(data=data_bin, bgpls_pro_id=1).dict()) 43 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/srv6_sid/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/attribute/linkstate/srv6_sid/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/linkstate/srv6_sid/test_srv6_endpoint_behavior.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test SRv6 Endpoint Behavior TLV """ 17 | 18 | import unittest 19 | 20 | from yabgp.message.attribute.linkstate.srv6_sid.srv6_endpoint_behavior import SRv6EndpointBehavior 21 | 22 | 23 | class TestSRv6EndpointBehavior(unittest.TestCase): 24 | 25 | def test_unpack(self): 26 | data_bin = b'\x00\x30' \ 27 | b'\x00' \ 28 | b'\x00' 29 | 30 | data_dict = { 31 | 'type': 'srv6_endpoint_behavior', 32 | 'value': { 33 | 'endpoint_behavior': 48, 34 | 'flags': 0, 35 | 'algorithm': 0 36 | } 37 | } 38 | self.assertEqual(data_dict, SRv6EndpointBehavior.unpack(data=data_bin).dict()) 39 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/nlri/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/attribute/nlri/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/nlri/labeled_unicast/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/attribute/nlri/labeled_unicast/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/nlri/labeled_unicast/test_ipv6_labeled_unicast.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import unittest 17 | 18 | from yabgp.message.attribute.nlri.labeled_unicast.ipv6 import IPv6LabeledUnicast 19 | 20 | 21 | class TestIPv6LabeledUnicast(unittest.TestCase): 22 | 23 | def test_construct(self): 24 | nlri_list = [ 25 | {'label': [91], 'prefix': '2001:2121::1/128'}, 26 | {'label': [92], 'prefix': '2001:2121:1::/64'}, 27 | {'label': [93], 'prefix': '2001:4837:1821::2/127'}] 28 | nlri_hex = b'\x98\x00\x05\xb1\x20\x01\x21\x21\x00\x00\x00\x00\x00\x00\x00' \ 29 | b'\x00\x00\x00\x00\x01\x58\x00\x05\xc1\x20\x01\x21\x21\x00\x01' \ 30 | b'\x00\x00\x97\x00\x05\xd1\x20\x01\x48\x37\x18\x21\x00\x00\x00' \ 31 | b'\x00\x00\x00\x00\x00\x00\x02' 32 | 33 | self.assertEqual(nlri_hex, IPv6LabeledUnicast.construct(nlri_list)) 34 | 35 | def test_parse(self): 36 | nlri_list = [ 37 | {'label': [91], 'prefix': '2001:2121::1/128'}, 38 | {'label': [92], 'prefix': '2001:2121:1::/64'}, 39 | {'label': [93], 'prefix': '2001:4837:1821::2/127'}] 40 | nlri_hex = b'\x98\x00\x05\xb1\x20\x01\x21\x21\x00\x00\x00\x00\x00\x00\x00' \ 41 | b'\x00\x00\x00\x00\x01\x58\x00\x05\xc1\x20\x01\x21\x21\x00\x01' \ 42 | b'\x00\x00\x97\x00\x05\xd1\x20\x01\x48\x37\x18\x21\x00\x00\x00' \ 43 | b'\x00\x00\x00\x00\x00\x00\x02' 44 | 45 | self.assertEqual(nlri_list, IPv6LabeledUnicast.parse(nlri_hex)) 46 | 47 | def test_parse_enable_add_path(self): 48 | nlri_list = [ 49 | {'path_id': 3, 'label': [2], 'prefix': '5::5/128'} 50 | ] 51 | nlri_hex = b'\x00\x00\x00\x03\x98\x00\x00\x21\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05' 52 | self.assertEqual(nlri_list, IPv6LabeledUnicast.parse(nlri_hex, addpath=True)) 53 | 54 | 55 | if __name__ == '__main__': 56 | unittest.main() 57 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/nlri/test_blgls_epe.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http:\\www.apache.org\licenses\LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import unittest 17 | 18 | from yabgp.message.attribute.nlri.linkstate import BGPLS 19 | 20 | 21 | class TestBGPLSEPE(unittest.TestCase): 22 | 23 | def test_parse(self): 24 | self.maxDiff = None 25 | data_bin = b"\x00\x02\x00\x51\x07\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" \ 26 | b"\x18\x02\x00\x00\x04\x00\x00\x00\xc8\x02\x01\x00\x04\x00\x00\x00" \ 27 | b"\x00\x02\x05\x00\x04\x00\x00\x00" \ 28 | b"\xc8\x01\x01\x00\x18\x02\x00\x00\x04\x00\x00\x01\x2c\x02\x01\x00" \ 29 | b"\x04\x00\x00\x00\x00\x02\x05\x00" \ 30 | b"\x04\x00\x00\x01\x2c\x01\x03\x00\x04\xc0\xa8\x04\x03\x01\x04\x00" \ 31 | b"\x04\xc0\xa8\x04\x04" 32 | data_dict = [ 33 | { 34 | 'type': 'link', 35 | 'protocol_id': 7, 36 | 'instances_id': 0, 37 | 'descriptors': [ 38 | { 39 | 'type': 'local_node', 40 | 'value': { 41 | 'as_num': 200, 42 | 'bgpls_id': '0.0.0.0', 43 | # 'bgp_router_id': '3.3.3.3', 44 | 'member_as_num': 200}}, 45 | { 46 | 'type': 'remote_node', 47 | 'value': { 48 | 'as_num': 300, 49 | 'bgpls_id': '0.0.0.0', 50 | # 'bgp_router_id': '4.4.4.4', 51 | 'member_as_num': 300}}, 52 | { 53 | 'type': 'link_local_ipv4', 54 | 'value': '192.168.4.3'}, 55 | { 56 | 'type': 'link_remote_ipv4', 57 | 'value': '192.168.4.4'}, 58 | ] 59 | } 60 | ] 61 | self.assertEqual(data_dict, BGPLS.parse(data_bin)) 62 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/nlri/test_ipv4_mpls_vpn.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test IPv4 MPLS VPN NLRI """ 17 | 18 | import unittest 19 | 20 | from yabgp.message.attribute.nlri.ipv4_mpls_vpn import IPv4MPLSVPN 21 | 22 | 23 | class TestIPv4MPLSVPN(unittest.TestCase): 24 | 25 | def test_parse(self): 26 | nlri_hex = b'\x78\x00\x01\x91\x00\x00\x00\x64\x00\x00\x00\x64\xaa\x00\x00\x00' 27 | self.assertEqual( 28 | [{'label': [25], 'rd': '100:100', 'prefix': '170.0.0.0/32'}], IPv4MPLSVPN.parse(nlri_hex)) 29 | 30 | def test_parse_1(self): 31 | nlri_hex = b'\x00\x00\x00\x64\x78\x00\x01\x91\x00\x00\x00\x64\x00\x00\x00\x64\xaa\x00\x00\x00' 32 | self.assertEqual( 33 | [{'path_id': 100, 'label': [25], 'rd': '100:100', 'prefix': '170.0.0.0/32'}], 34 | IPv4MPLSVPN.parse(nlri_hex, addpath=True)) 35 | 36 | def test_construct_1(self): 37 | nlri_hex = b'\x76\x00\x01\x41\x00\x00\xfd\xea\x00\x00\x00\x01\x17\x00\x00\x00' 38 | nlri_list = [{'label': [20], 'rd': '65002:1', 'prefix': '23.0.0.0/30'}] 39 | self.assertEqual(nlri_list, IPv4MPLSVPN.parse(nlri_hex)) 40 | self.assertEqual(nlri_hex, IPv4MPLSVPN.construct(nlri_list), ) 41 | 42 | def test_construct_2(self): 43 | nlri_hex = b'\x78\x00\x01\x91\x00\x00\x00\x64\x00\x00\x00\x64\xaa\x00\x00\x00' 44 | nlri_list = [{'label': [25], 'rd': '100:100', 'prefix': '170.0.0.0/32'}] 45 | self.assertEqual(nlri_hex, IPv4MPLSVPN.construct(nlri_list)) 46 | 47 | def test_construct_multi(self): 48 | nlri_list = [ 49 | {'label': [25], 'rd': '100:100', 'prefix': '170.0.0.0/32'}, 50 | {'label': [20], 'rd': '65002:1', 'prefix': '23.0.0.0/30'} 51 | ] 52 | self.assertEqual(nlri_list, IPv4MPLSVPN.parse(IPv4MPLSVPN.construct(nlri_list))) 53 | 54 | if __name__ == '__main__': 55 | unittest.main() 56 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/nlri/test_ipv4_srte.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import unittest 17 | 18 | from yabgp.message.attribute.nlri.ipv4_srte import IPv4SRTE 19 | 20 | 21 | class TestIPv4SRTE(unittest.TestCase): 22 | 23 | def test_construct(self): 24 | nlri_bin = b'\x60\x00\x00\x00\x00\x00\x00\x00\x0a\xc0\xa8\x05\x07' 25 | nlri = {"distinguisher": 0, "color": 10, "endpoint": "192.168.5.7"} 26 | self.assertEqual(nlri_bin, IPv4SRTE.construct(nlri)) 27 | 28 | if __name__ == '__main__': 29 | unittest.main() 30 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/nlri/test_linkstate_prefix_sid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test Link State attribute""" 17 | 18 | import unittest 19 | from yabgp.message.attribute.linkstate.linkstate import LinkState 20 | 21 | 22 | class TestLinkStatePrefixSID(unittest.TestCase): 23 | 24 | def test_prefix_sid_flags_ospf(self): 25 | self.maxDiff = None 26 | data_bin = b'\x04\x86\x00\x07\xb4\x00\x00\x00\x00\x61\xa9' 27 | 28 | data_dict = {29: [{ 29 | 'type': 'prefix_sid', 30 | 'value': { 31 | 'sid': 25001, 32 | 'flags': { 33 | 'NP': 0, 34 | 'M': 1, 35 | 'E': 1, 36 | 'V': 0, 37 | 'L': 1 38 | }, 39 | 'algorithm': 0 40 | } 41 | }]} 42 | self.assertEqual(data_dict, LinkState.unpack(data_bin, 3).dict()) 43 | 44 | def test_prefix_id_flags_isis(self): 45 | self.maxDiff = None 46 | data_bin = b'\x04\x86\x00\x07\xb4\x00\x00\x00\x00\x61\xa9' 47 | 48 | data_dict = {29: [{ 49 | 'type': 'prefix_sid', 50 | 'value': { 51 | 'sid': 25001, 52 | 'flags': { 53 | 'R': 1, 54 | 'N': 0, 55 | 'P': 1, 56 | 'E': 1, 57 | 'V': 0, 58 | 'L': 1 59 | }, 60 | 'algorithm': 0 61 | } 62 | }]} 63 | self.assertEqual(data_dict, LinkState.unpack(data_bin, 1).dict()) 64 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/nlri/test_mpls_vpn.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test MPLS VPN """ 17 | 18 | import unittest 19 | 20 | from yabgp.message.attribute.nlri.mpls_vpn import MPLSVPN 21 | 22 | 23 | class TestMPLSVPN(unittest.TestCase): 24 | 25 | def test_parse_mpls_label_stack(self): 26 | label_bin = b'\x00\x01\x41' 27 | self.assertEqual([20], MPLSVPN.parse_mpls_label_stack(label_bin)) 28 | label_bin = b'\x00\x01\x10\x00\x01\x31' 29 | self.assertEqual([17, 19], MPLSVPN.parse_mpls_label_stack(label_bin)) 30 | label_bin = b'\x80\x00\x00' 31 | self.assertEqual([524288], MPLSVPN.parse_mpls_label_stack(label_bin)) 32 | 33 | def test_construct_mpls_label_stack(self): 34 | label_bin = b'\x00\x01\x41' 35 | self.assertEqual(label_bin, MPLSVPN.construct_mpls_label_stack(labels=[20])) 36 | 37 | def test_parse_and_construct_rd_type0(self): 38 | # for rd type 0 39 | rd_bin = b'\x00\x00\xfd\xea\x00\x00\x00\x01' 40 | rd_parsed = '65002:1' 41 | self.assertEqual(rd_parsed, MPLSVPN.parse_rd(rd_bin)) 42 | self.assertEqual(rd_bin, MPLSVPN.construct_rd(rd_parsed)) 43 | 44 | def test_parse_and_construct_rd_type1(self): 45 | 46 | rd_bin = b'\x00\x01\xac\x11\x00\x03\x00\x02' 47 | rd_parsed = '172.17.0.3:2' 48 | self.assertEqual(rd_parsed, MPLSVPN.parse_rd(rd_bin)) 49 | self.assertEqual(rd_bin, MPLSVPN.construct_rd(rd_parsed)) 50 | 51 | def test_parse_and_construct_rd_type2(self): 52 | rd_bin = b'\x00\x02\x00\x01\x00\x00\x00\x02' 53 | rd_parsed = '65536:2' 54 | self.assertEqual(rd_parsed, MPLSVPN.parse_rd(rd_bin)) 55 | self.assertEqual(rd_bin, MPLSVPN.construct_rd(rd_parsed)) 56 | 57 | if __name__ == '__main__': 58 | unittest.main() 59 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/nlri/test_nlri.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import unittest 17 | 18 | from yabgp.message.attribute.nlri import NLRI 19 | 20 | 21 | class TestNLRI(unittest.TestCase): 22 | 23 | def test_construct_prefix_vpnv6(self): 24 | prefix_hex = b'\x20\x10\x00\x00\x00\x12\x00\04' 25 | prefix_str = '2010:0:12:4::/64' 26 | self.assertEqual(prefix_hex, NLRI.construct_prefix_v6(prefix_str)) 27 | 28 | 29 | if __name__ == '__main__': 30 | unittest.main() 31 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/sr/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartbgp/yabgp/4c04832c13d73b7b0d069a8e1b6a2f317ee738f6/yabgp/tests/unit/message/attribute/sr/__init__.py -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/sr/test_bgpprefixsid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test BGP Prefix SID TLV """ 17 | 18 | import unittest 19 | 20 | from yabgp.message.update import BGPPrefixSID 21 | 22 | 23 | class TestBGPPrefixSID(unittest.TestCase): 24 | 25 | def test_unpack(self): 26 | """ 27 | 28 | :return: 29 | """ 30 | data_bin = b'\xc0\x28\x25' \ 31 | b'\x05\x00\x22\x00' \ 32 | b'\x01\x00\x1e\x00\x20\x05\xbb\x00\x01\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00' \ 33 | b'\x01\x00\x06\x20\x10\x10\x00\x10\x30' 34 | data_list = [{ 35 | 'srv6_l3_service': { 36 | 'srv6_service_sub_tlvs': [{ 37 | 'srv6_sid_information': { 38 | 'srv6_sid_value': '2005:bb00:112::', 39 | 'srv6_service_sid_flags': 0, 40 | 'srv6_endpoint_behavior': 63, 41 | 'srv6_service_data_sub_sub_tlvs': [{ 42 | 'srv6_sid_structure': { 43 | 'locator_block_length': 32, 44 | 'locator_node_length': 16, 45 | 'function_length': 16, 46 | 'argument_length': 0, 47 | 'transposition_length': 16, 48 | 'transposition_offset': 48 49 | } 50 | }] 51 | } 52 | }] 53 | } 54 | }] 55 | self.assertEqual(data_list, BGPPrefixSID.unpack(data=data_bin[3:])) 56 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_aggregator.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test Aggregator attribute """ 17 | 18 | import unittest 19 | 20 | from yabgp.common import exception as excep 21 | from yabgp.common.constants import ERR_MSG_UPDATE_ATTR_LEN 22 | from yabgp.message.attribute.aggregator import Aggregator 23 | 24 | 25 | class TestAggregator(unittest.TestCase): 26 | def test_parse(self): 27 | 28 | # 4 bytes asn 29 | aggregator = Aggregator.parse(value=b'\x00\x00\x70\xd5\x3e\xe7\xff\x79', 30 | asn4=True) 31 | self.assertEqual((28885, '62.231.255.121'), aggregator) 32 | 33 | # 2 bytes asn 34 | aggregator = Aggregator.parse(value=b'\x70\xd5\x3e\xe7\xff\x79', 35 | asn4=False) 36 | self.assertEqual((28885, '62.231.255.121'), aggregator) 37 | 38 | # invalid attr len 39 | self.assertRaises(excep.UpdateMessageError, Aggregator.parse, 40 | b'\x70\xd5\x3e\xe7\xff\x79', 41 | True) 42 | try: 43 | Aggregator.parse(value=b'\x70\xd5\x3e\xe7\xff\x79', 44 | asn4=True) 45 | except excep.UpdateMessageError as e: 46 | self.assertEqual(ERR_MSG_UPDATE_ATTR_LEN, e.sub_error) 47 | 48 | def test_construct(self): 49 | 50 | aggregator = Aggregator.construct(value=(28885, '62.231.255.121')) 51 | self.assertEqual(b'\xc0\x07\x06\x70\xd5\x3e\xe7\xff\x79', aggregator) 52 | 53 | 54 | if __name__ == '__main__': 55 | unittest.main() 56 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_atomicaggregate.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test Atomic Aggregate attribute """ 17 | 18 | import unittest 19 | 20 | from yabgp.common.exception import UpdateMessageError 21 | from yabgp.common.constants import ERR_MSG_UPDATE_OPTIONAL_ATTR 22 | from yabgp.message.attribute.atomicaggregate import AtomicAggregate 23 | 24 | 25 | class TestAtomicAggregate(unittest.TestCase): 26 | 27 | def test_parse(self): 28 | 29 | atomicaggregate = AtomicAggregate.parse(value=b'') 30 | self.assertEqual(atomicaggregate, '') 31 | 32 | # invalid value 33 | self.assertRaises(UpdateMessageError, AtomicAggregate.parse, 34 | b'\x01') 35 | try: 36 | AtomicAggregate.parse(b'\x01') 37 | except UpdateMessageError as e: 38 | self.assertEqual(e.sub_error, ERR_MSG_UPDATE_OPTIONAL_ATTR) 39 | 40 | def test_construct(self): 41 | 42 | atomicaggregate = AtomicAggregate.construct(value=b'') 43 | self.assertEqual(b'\x40\x06\x00', atomicaggregate) 44 | 45 | def test_construct_exception(self): 46 | self.assertRaises(UpdateMessageError, AtomicAggregate.construct, b'\x00') 47 | 48 | if __name__ == '__main__': 49 | unittest.main() 50 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_clusterlist.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test Cluster List attribute """ 17 | 18 | import unittest 19 | 20 | from yabgp.common.constants import ERR_MSG_UPDATE_ATTR_LEN 21 | from yabgp.common import exception as excep 22 | from yabgp.message.attribute.clusterlist import ClusterList 23 | 24 | 25 | class TestClusterList(unittest.TestCase): 26 | 27 | def test_parse(self): 28 | 29 | cluster_list = ClusterList.parse(value=b'\x01\x01\x01\x01\x02\x02\x02\x02\x03\x03\x03\x03') 30 | self.assertEqual(['1.1.1.1', '2.2.2.2', '3.3.3.3'], cluster_list) 31 | 32 | def test_parse_invalid_length(self): 33 | # invalid length 34 | self.assertRaises(excep.UpdateMessageError, ClusterList.parse, 35 | b'\x01\x01\x01\x01\x01\x02\x02\x02\x02\x03\x03\x03\x03') 36 | try: 37 | ClusterList.parse(value=b'\x01\x01\x01\x01\x01\x02\x02\x02\x02\x03\x03\x03\x03') 38 | except excep.UpdateMessageError as e: 39 | self.assertEqual(ERR_MSG_UPDATE_ATTR_LEN, e.sub_error) 40 | 41 | def test_construct(self): 42 | 43 | cluster_list = ClusterList.construct(value=['1.1.1.1', '2.2.2.2', '3.3.3.3']) 44 | self.assertEqual(b'\x80\n\x0c\x01\x01\x01\x01\x02\x02\x02\x02\x03\x03\x03\x03', cluster_list) 45 | 46 | def test_construct_invalid_length(self): 47 | # invalid length 48 | self.assertRaises(excep.UpdateMessageError, ClusterList.construct, 49 | ['a', 2, '3']) 50 | 51 | if __name__ == '__main__': 52 | unittest.main() 53 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_large_community.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test Community attribute """ 17 | 18 | import unittest 19 | 20 | from yabgp.message.attribute.largecommunity import LargeCommunity 21 | 22 | 23 | class TestLargeCommunity(unittest.TestCase): 24 | 25 | def test_parse(self): 26 | 27 | community = LargeCommunity.parse(value=b'\x00\x03\x00\x0d\x00\x00\x00\x03\x00\x00\x00\x05') 28 | self.assertEqual(["196621:3:5"], community) 29 | 30 | def test_construct(self): 31 | 32 | large_community = LargeCommunity.construct(value=['196621:3:5', '196621:4:1']) 33 | self.assertEqual(b'\xe0\x20\x18' 34 | b'\x00\x03\x00\x0d\x00\x00\x00\x03\x00\x00\x00\x05' 35 | b'\x00\x03\x00\x0d\x00\x00\x00\x04\x00\x00\x00\x01', large_community) 36 | 37 | 38 | if __name__ == '__main__': 39 | unittest.main() 40 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_localpref.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """Test LocalPreference attribute 17 | """ 18 | 19 | import unittest 20 | 21 | from yabgp.common.exception import UpdateMessageError 22 | from yabgp.common.constants import ERR_MSG_UPDATE_ATTR_LEN 23 | from yabgp.message.attribute.localpref import LocalPreference 24 | 25 | 26 | class TestLocalPreference(unittest.TestCase): 27 | 28 | def test_parse(self): 29 | 30 | local_pre = LocalPreference.parse(value=b'\x00\x00\x00\xa0') 31 | self.assertEqual(local_pre, 160) 32 | 33 | def test_parse_invalid_length(self): 34 | # invalid length 35 | self.assertRaises(UpdateMessageError, LocalPreference.parse, 36 | b'\x0a\x0a\x0a\x01\x01') 37 | try: 38 | LocalPreference.parse(b'\x0a\x0a\x0a\x01\x01') 39 | except UpdateMessageError as e: 40 | self.assertEqual(e.sub_error, ERR_MSG_UPDATE_ATTR_LEN) 41 | 42 | def test_construct(self): 43 | 44 | local_pre = LocalPreference.construct(value=100) 45 | self.assertEqual(b'\x40\x05\x04\x00\x00\x00\x64', local_pre) 46 | 47 | def test_construct_excetion_attr_len(self): 48 | # invalid med value 49 | self.assertRaises(UpdateMessageError, LocalPreference.construct, 4294967296) 50 | try: 51 | LocalPreference.construct(value=4294967296) 52 | except UpdateMessageError as e: 53 | self.assertEqual(e.sub_error, ERR_MSG_UPDATE_ATTR_LEN) 54 | 55 | if __name__ == '__main__': 56 | unittest.main() 57 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_med.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """Test MED attribute 17 | """ 18 | 19 | import unittest 20 | 21 | from yabgp.common.exception import UpdateMessageError 22 | from yabgp.common.constants import ERR_MSG_UPDATE_ATTR_LEN 23 | from yabgp.message.attribute.med import MED 24 | 25 | 26 | class TestMED(unittest.TestCase): 27 | 28 | def test_parse(self): 29 | 30 | med = MED.parse(value=b'\x00\x00\x00\xa0') 31 | self.assertEqual(med, 160) 32 | 33 | # invalid length 34 | self.assertRaises(UpdateMessageError, MED.parse, 35 | b'\x0a\x0a\x0a\x01\x01') 36 | 37 | def test_parse_exception_attr_len(self): 38 | try: 39 | MED.parse(b'\x0a\x0a\x0a\x01\x01') 40 | except UpdateMessageError as e: 41 | self.assertEqual(e.sub_error, ERR_MSG_UPDATE_ATTR_LEN) 42 | 43 | def test_construct(self): 44 | 45 | med = MED.construct(value=100) 46 | self.assertEqual(med, b'\x80\x04\x04\x00\x00\x00d') 47 | 48 | def test_construct_exception_attr_len(self): 49 | 50 | # invalid med value 51 | self.assertRaises(UpdateMessageError, MED.construct, 4294967296) 52 | try: 53 | MED.construct(value=4294967296) 54 | except UpdateMessageError as e: 55 | self.assertEqual(e.sub_error, ERR_MSG_UPDATE_ATTR_LEN) 56 | 57 | if __name__ == '__main__': 58 | unittest.main() 59 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_nexthop.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """Test Nexthop attribute 17 | """ 18 | 19 | import unittest 20 | 21 | from yabgp.common.exception import UpdateMessageError 22 | from yabgp.common.constants import ERR_MSG_UPDATE_ATTR_LEN 23 | from yabgp.common.constants import ERR_MSG_UPDATE_INVALID_NEXTHOP 24 | from yabgp.message.attribute.nexthop import NextHop 25 | 26 | 27 | class TestNextHop(unittest.TestCase): 28 | 29 | def test_parse(self): 30 | 31 | next_hop = NextHop.parse(value=b'\x0a\x0a\x0a\x01') 32 | self.assertEqual(next_hop, '10.10.10.1') 33 | self.assertEqual(NextHop.parse(value=b'\x00\x00\x00\x00'), '0.0.0.0') 34 | self.assertEqual(NextHop.parse(value=b'\xff\xff\xff\xff'), '255.255.255.255') 35 | 36 | def test_parse_invalid_length(self): 37 | # invalid length 38 | self.assertRaises(UpdateMessageError, NextHop.parse, 39 | b'\x0a\x0a\x0a\x01\x01') 40 | try: 41 | NextHop.parse(b'\x0a\x0a\x0a\x01\x01') 42 | except UpdateMessageError as e: 43 | self.assertEqual(e.sub_error, ERR_MSG_UPDATE_ATTR_LEN) 44 | 45 | def test_construct(self): 46 | 47 | next_hop = NextHop.construct(value='10.10.10.1') 48 | self.assertEqual(next_hop, b'\x40\x03\x04\x0a\x0a\x0a\x01') 49 | self.assertEqual(NextHop.construct('0.0.0.0'), b'\x40\x03\x04\x00\x00\x00\x00') 50 | 51 | def test_construct_invalid_nexthop(self): 52 | # invalid next hop 53 | self.assertRaises(UpdateMessageError, NextHop.construct, '300.1.1') 54 | try: 55 | NextHop.construct(value='300.33.33.33') 56 | except UpdateMessageError as e: 57 | self.assertEqual(e.sub_error, ERR_MSG_UPDATE_INVALID_NEXTHOP) 58 | 59 | def test_construct_with_flags(self): 60 | nexthop = NextHop.construct(value='10.10.10.10') 61 | self.assertEqual(nexthop, b'\x40\x03\x04\x0a\x0a\x0a\x0a') 62 | if __name__ == '__main__': 63 | unittest.main() 64 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_origin.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test Origin attribute""" 17 | 18 | import unittest 19 | 20 | from yabgp.common.exception import UpdateMessageError 21 | from yabgp.common.constants import ERR_MSG_UPDATE_INVALID_ORIGIN 22 | from yabgp.message.attribute.origin import Origin 23 | 24 | 25 | class TestOrigin(unittest.TestCase): 26 | 27 | def test_origin_igp(self): 28 | self.assertEqual(Origin.IGP, Origin.parse(value=b'\x00')) 29 | 30 | def test_origin_egp(self): 31 | self.assertEqual(Origin.EGP, Origin.parse(value=b'\x01')) 32 | 33 | def test_origin_incomplete(self): 34 | self.assertEqual(Origin.INCOMPLETE, Origin.parse(value=b'\x02')) 35 | 36 | def test_invalid_origin(self): 37 | 38 | self.assertRaises(UpdateMessageError, Origin.parse, b'\x03') 39 | try: 40 | Origin.parse(b'\x03') 41 | except UpdateMessageError as e: 42 | self.assertEqual(e.sub_error, ERR_MSG_UPDATE_INVALID_ORIGIN) 43 | 44 | def test_construct(self): 45 | 46 | self.assertEqual(b'\x40\x01\x01\x00', Origin.construct(value=0)) 47 | self.assertEqual(b'\x40\x01\x01\x00', Origin.construct(value=0)) 48 | self.assertEqual(b'\x40\x01\x01\x01', Origin.construct(value=1)) 49 | self.assertEqual(b'\x40\x01\x01\x02', Origin.construct(value=2)) 50 | 51 | self.assertRaises(UpdateMessageError, Origin.construct, 3) 52 | try: 53 | Origin.construct(3) 54 | except UpdateMessageError as e: 55 | self.assertEqual(e.sub_error, ERR_MSG_UPDATE_INVALID_ORIGIN) 56 | 57 | if __name__ == '__main__': 58 | unittest.main() 59 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_originatorid.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """Test Originator ID attribute 17 | """ 18 | 19 | import unittest 20 | 21 | from yabgp.common.constants import ERR_MSG_UPDATE_ATTR_LEN 22 | from yabgp.common import exception as excep 23 | from yabgp.message.attribute.originatorid import OriginatorID 24 | 25 | 26 | class TestOriginatorID(unittest.TestCase): 27 | 28 | def test_parse(self): 29 | 30 | # normal 31 | originator_id = OriginatorID.parse(value=b'\xc0\xa8\x01\x01') 32 | self.assertEqual('192.168.1.1', originator_id) 33 | 34 | # invalid attribute length 35 | self.assertRaises(excep.UpdateMessageError, OriginatorID.parse, 36 | b'\xc0\xa8\x01\x01\x01') 37 | try: 38 | OriginatorID.parse(value=b'\xc0\xa8\x01\x01\x01') 39 | except excep.UpdateMessageError as e: 40 | self.assertEqual(ERR_MSG_UPDATE_ATTR_LEN, e.sub_error) 41 | 42 | def test_construct(self): 43 | 44 | originator_id = OriginatorID.construct(value='192.168.1.1') 45 | self.assertEqual(b'\x80\x09\x04\xc0\xa8\x01\x01', originator_id) 46 | 47 | # invalid value 48 | self.assertRaises(excep.UpdateMessageError, OriginatorID.construct, 49 | b'\xc0\xa8\x01\x01\x01') 50 | try: 51 | OriginatorID.construct(value=b'\xc0\xa8\x01\x01\x01') 52 | except excep.UpdateMessageError as e: 53 | self.assertEqual(ERR_MSG_UPDATE_ATTR_LEN, e.sub_error) 54 | 55 | if __name__ == '__main__': 56 | unittest.main() 57 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/attribute/test_pmsitunnel.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """Test PMSI Tunnel attribute 17 | """ 18 | 19 | import unittest 20 | 21 | from yabgp.message.attribute.pmsitunnel import PMSITunnel 22 | 23 | 24 | class TestPMSITunnel(unittest.TestCase): 25 | 26 | def test_parse(self): 27 | self.maxDiff = None 28 | hex_value = b'\x00\x06\x00\x27\x10\x04\x04\x04\x04' 29 | value_hoped = {'mpls_label': [625], 'tunnel_id': '4.4.4.4', 'tunnel_type': 6, 'leaf_info_required': 0} 30 | self.assertEqual(value_hoped, PMSITunnel.parse(hex_value)) 31 | 32 | def test_construct(self): 33 | self.maxDiff = None 34 | hex_value = b'\x00\x06\x00\x27\x10\x04\x04\x04\x04' 35 | value_hoped = {'mpls_label': [625], 'tunnel_id': '4.4.4.4', 'tunnel_type': 6, 'leaf_info_required': 0} 36 | self.assertEqual(hex_value, PMSITunnel.construct(value_hoped)[3:]) 37 | 38 | if __name__ == '__main__': 39 | unittest.main() 40 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/test_keepalive.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test BGP KeepAlive message""" 17 | 18 | import unittest 19 | 20 | from yabgp.message.keepalive import KeepAlive 21 | from yabgp.common.exception import MessageHeaderError 22 | 23 | 24 | class TestKeepAlive(unittest.TestCase): 25 | 26 | def test_parse(self): 27 | msg_hex = '' 28 | keepalive_msg = KeepAlive().parse(msg_hex) 29 | self.assertEqual(None, keepalive_msg) 30 | 31 | def test_parse_msg_header_error(self): 32 | self.assertRaises(MessageHeaderError, KeepAlive().parse, b'\x00') 33 | 34 | def test_construct(self): 35 | 36 | msg_hex = KeepAlive().construct() 37 | hope_msg = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x13\x04' 38 | self.assertEqual(hope_msg, msg_hex) 39 | 40 | if __name__ == '__main__': 41 | unittest.main() 42 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/test_notification.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test Notification message""" 17 | 18 | import unittest 19 | 20 | 21 | from yabgp.message.notification import Notification 22 | 23 | 24 | class TestNotification(unittest.TestCase): 25 | 26 | def test_parse(self): 27 | msg_hex = b'\x03\x05\x00\x00' 28 | noti_msg = Notification().parse(msg_hex) 29 | self.assertEqual((3, 5, b'\x00\x00'), noti_msg) 30 | 31 | def test_construct(self): 32 | 33 | msg_hex = Notification().construct(error=3, suberror=5, data=b'\x00\x00') 34 | hope_msg = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \ 35 | b'\xff\xff\x00\x17\x03\x03\x05\x00\x00' 36 | self.assertEqual(hope_msg, msg_hex) 37 | 38 | if __name__ == '__main__': 39 | unittest.main() 40 | -------------------------------------------------------------------------------- /yabgp/tests/unit/message/test_route_refresh.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | """ Test Route Refresh message""" 17 | 18 | import unittest 19 | from yabgp.message.route_refresh import RouteRefresh 20 | from yabgp.common.constants import MSG_CISCOROUTEREFRESH 21 | from yabgp.common.constants import MSG_ROUTEREFRESH 22 | 23 | 24 | class TestRouteRefresh(unittest.TestCase): 25 | 26 | def test_parse(self): 27 | 28 | msg_hex = b'\x00\x01\x00\x80' 29 | msg_parsed = RouteRefresh().parse(msg_hex) 30 | msg_hoped = (1, 0, 128) 31 | self.assertEqual(msg_hoped, msg_parsed) 32 | 33 | def test_construct_rfc_route_refresh(self): 34 | 35 | msg = (1, 0, 128) 36 | msg_hex = RouteRefresh(afi=msg[0], res=msg[1], safi=msg[2]).construct(MSG_ROUTEREFRESH) 37 | msg_hoped = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x17\x05\x00\x01\x00\x80' 38 | self.assertEqual(msg_hoped, msg_hex) 39 | 40 | def test_construct_cisco_route_refresh(self): 41 | 42 | msg = (1, 0, 128) 43 | msg_hex = RouteRefresh(afi=msg[0], res=msg[1], safi=msg[2]).construct(MSG_CISCOROUTEREFRESH) 44 | msg_hoped = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x17\x80\x00\x01\x00\x80' 45 | self.assertEqual(msg_hoped, msg_hex) 46 | 47 | if __name__ == '__main__': 48 | unittest.main() 49 | -------------------------------------------------------------------------------- /yabgp/tlv.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2017 Cisco Systems, Inc. 2 | # All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | 18 | 19 | class TLV(object): 20 | """TLV basic class 21 | """ 22 | TYPE = -1 23 | TYPE_STR = "UNKNOWN" 24 | 25 | __slots__ = ['value'] 26 | 27 | def __init__(self, value): 28 | self.value = value 29 | 30 | def __str__(self): 31 | return '%s: %s' % (self.TYPE_STR, self.value) 32 | 33 | @classmethod 34 | def unpack(cls, value): 35 | """unpack binary data 36 | """ 37 | return cls(value=binascii.b2a_hex(value)) 38 | 39 | def dict(self, str_key=True): 40 | """return dict format 41 | """ 42 | if str_key: 43 | return { 44 | 'type': self.TYPE_STR, 45 | 'value': self.value} 46 | return { 47 | 'type': self.TYPE, 48 | 'value': self.value 49 | } 50 | --------------------------------------------------------------------------------