{"id":16709298,"url":"https://github.com/mrlesmithjr/ansible-frr","last_synced_at":"2025-04-09T14:11:20.350Z","repository":{"id":28778727,"uuid":"119301768","full_name":"mrlesmithjr/ansible-frr","owner":"mrlesmithjr","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-06T00:57:57.000Z","size":5510,"stargazers_count":37,"open_issues_count":1,"forks_count":29,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-02T12:11:09.640Z","etag":null,"topics":["ansible","bgp","bgp-configuration","hacktoberfest","ospf"],"latest_commit_sha":null,"homepage":"","language":"Jinja","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrlesmithjr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-28T22:00:06.000Z","updated_at":"2025-02-05T14:10:56.000Z","dependencies_parsed_at":"2023-12-01T01:34:35.948Z","dependency_job_id":"f162cfbb-e7dc-4254-9b98-b47ecf6745b0","html_url":"https://github.com/mrlesmithjr/ansible-frr","commit_stats":{"total_commits":196,"total_committers":19,"mean_commits":10.31578947368421,"dds":0.7602040816326531,"last_synced_commit":"032b54af1cbc15539e7f29e4da3fc06ce6c4b928"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrlesmithjr%2Fansible-frr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrlesmithjr%2Fansible-frr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrlesmithjr%2Fansible-frr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrlesmithjr%2Fansible-frr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrlesmithjr","download_url":"https://codeload.github.com/mrlesmithjr/ansible-frr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054196,"owners_count":21039952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","bgp","bgp-configuration","hacktoberfest","ospf"],"created_at":"2024-10-12T20:04:29.154Z","updated_at":"2025-04-09T14:11:20.327Z","avatar_url":"https://github.com/mrlesmithjr.png","language":"Jinja","funding_links":["https://www.buymeacoffee.com/mrlesmithjr"],"categories":[],"sub_categories":[],"readme":"\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n**Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*\n\n- [ansible-frr](#ansible-frr)\n  - [Build Status](#build-status)\n    - [GitHub Actions](#github-actions)\n    - [Travis CI](#travis-ci)\n  - [Requirements](#requirements)\n  - [Role Variables](#role-variables)\n  - [Dependencies](#dependencies)\n  - [Example Playbook](#example-playbook)\n  - [Route Maps and Prefix Lists](#route-maps-and-prefix-lists)\n    - [Route Maps](#route-maps)\n      - [Configuring Route Maps](#configuring-route-maps)\n    - [General Options](#general-options)\n      - [IP/IPv6 Forwarding](#ipipv6-forwarding)\n    - [Prefix Lists](#prefix-lists)\n      - [Configuring Prefix Lists](#configuring-prefix-lists)\n    - [Access Lists](#access-lists)\n      - [Configuring Access Lists](#configuring-access-lists)\n  - [Bidirectional Forwarding Detection](#bidirectional-forwarding-detection)\n    - [Enable BFD](#enable-bfd)\n    - [Configuring BFD](#configuring-bfd)\n  - [Supported Routing Protocols](#supported-routing-protocols)\n    - [BGP](#bgp)\n      - [Enable BGP](#enable-bgp)\n      - [Configuring BGP](#configuring-bgp)\n      - [Example BGP](#example-bgp)\n    - [OSPF](#ospf)\n      - [Enable OSPF](#enable-ospf)\n      - [Configuring OSPF](#configuring-ospf)\n        - [VRF-aware OSPF](#vrf-aware-ospf)\n    - [STATIC](#static)\n      - [Configuring STATIC routes](#configuring-static-routes)\n  - [Interface Configuration](#interface-configuration)\n    - [Interfaces](#interfaces)\n  - [Upgrade/Downgrade](#upgradedowngrade)\n  - [Quagga configuration](#quagga-configuration)\n  - [License](#license)\n  - [Author Information](#author-information)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n# ansible-frr\n\nAnsible role to install/configure FRR\n\n\u003e NOTE: FRRouting (FRR) is an IP routing protocol suite for Linux and Unix\n\u003e platforms which includes protocol daemons for BFD, BGP, IS-IS, LDP, OSPF, PIM, and RIP.\n\n## Build Status\n\n### GitHub Actions\n\n![Molecule Test](https://github.com/mrlesmithjr/ansible-frr/workflows/Molecule%20Test/badge.svg)\n\n### Travis CI\n\n[![Build Status](https://travis-ci.org/mrlesmithjr/ansible-frr.svg?branch=master)](https://travis-ci.org/mrlesmithjr/ansible-frr)\n\n## Requirements\n\nFor any required Ansible roles, review:\n[requirements.yml](requirements.yml)\n\n## Role Variables\n\n[defaults/main.yml](defaults/main.yml)\n\n## Dependencies\n\n## Example Playbook\n\n[playbook.yml](playbook.yml)\n\n## Route Maps and Prefix Lists\n\n### Route Maps\n\n#### Configuring Route Maps\n\nBelow is an example of Route Maps Configuration:\n\n```yaml\nfrr_route_map:\n  RTBH:\n    permit 10:\n      interface: blackhole\n      prefix_list: Bad_IPs\n      origin: igp\n      community: \"12345:100\"\n      src: 2001:db8::bf03\n  RTBH_IN:\n    deny 10: []\n```\n\n### General Options\n\n#### IP/IPv6 Forwarding\n\nBelow is an example of enabling ip and ipv6 forwading:\n\n```yaml\nfrr_ip_forwarding: true\nfrr_ipv6_forwarding: true\n```\n\nTo enable kernel forwarding, the role sets the sysctl variables `net.ipv4.ip_forward` and `net.ipv6.conf.all.forwarding`. To customize the location of the sysctl configuration, the following variable may be used:\n\n```yaml\nfrr_sysctl_file: /etc/sysctl.d/100-ansible-frr.conf\n```\n\n#### Next-hop tracking via default\nResolve nexthops using the default route;\nuseful if BGP peer is only reachable via default gateway (disabled by default).\n\nTo enable:\n```yaml\nfrr_nht_resolve_default: true\n```\n\n### Prefix Lists\n\n#### Configuring Prefix Lists\n\nBelow is an example of Prefix List Configuration:\n\n```yaml\nfrr_prefix_list:\n  Bad_IPs:\n    05 permit:\n      prefix: 192.168.88.0/24\n      match: ge 32\n    10 permit:\n      prefix: 172.16.0.0/16\n      match: le 32\nfrr_prefix_list_v6:\n  Bad_IPs:\n    05 permit:\n      prefix: 1234:5678::/32\n      match: ge 128\n```\n\n### Access Lists\n\n#### Configuring Access Lists\n\nBelow is an example\n\n```yaml\nfrr_access_list:\n  - \"10 permit 10.10.10.21/32\"\n  - \"10 permit 192.168.0.0/17\"\n  - \"101 permit ip 10.0.0.0 0.0.0.255 any\"\n```\n\n## Bidirectional Forwarding Detection (BFD)\n\n### Enable BFD\n\nTo enable BFD, make sure that `bfdd: true` is configured under:\n\n```yaml\nfrr_daemons:\n  bfdd: true\n  bgpd: false\n  isisd: false\n  ldpd: false\n  nhrpd: false\n  ospf6d: false\n  ospfd: false\n  pimd: false\n  ripd: false\n  ripngd: false\n  zebra: true\n```\n\n### Configuring BFD\n\nBFD configuration is made under BGP neighbor settings. BFD for OSPF is not supported yet.\n\n## Supported Routing Protocols\n\n| Protocol          | Implemented | Notes               |\n| ----------------- | ----------- | ------------------- |\n| [BGP](#bgp)       | X           | Only initial config |\n| [OSPF](#ospf)     | X           | Only initial config |\n| [STATIC](#static) | X           | Only initial config |\n\n### BGP\n\n#### Enable BGP\n\nTo enable BGP routing, make sure that `bgpd: true` is configured under:\n\n```yaml\nfrr_daemons:\n  bfdd: false\n  bgpd: false\n  isisd: false\n  ldpd: false\n  nhrpd: false\n  ospf6d: false\n  ospfd: false\n  pimd: false\n  ripd: false\n  ripngd: false\n  zebra: true\n```\n\n#### Configuring BGP\n\nIn order to configure BGP, define the following based on your requirements:\n\n```yaml\nfrr_bgp:\n  asns:\n    65000:\n      log_neighbor_changes: true\n      no_ebgp_requires_policy: true\n      timers: '3 9'\n      other:\n        - \"bgp bestpath as-path multipath-relax\"\n        - \"no bgp network import-check\"\n      neighbors:\n        group1:\n          asn: 66000\n          is_peer_group: true\n          multihop: 255\n        192.168.250.11:\n          asn: 65000\n          default_originate: false\n          description: node1\n          next_hop_self: true\n          timers_connect: 5\n          v6only: true\n          bfd_peer: true\n          bfd_peer_detect_multiplier: 3\n          bfd_peer_receive_interval: 50\n          bfd_peer_transmit_interval: 50\n          bfd_peer_echo_interval: 50\n          bfd_peer_passive_mode: true\n          bfd_peer_minimum_ttl: 253\n          other:\n            - \"capability dynamic\"\n        192.168.250.12:\n          asn: 65000\n          default_originate: false\n          description: node2\n          next_hop_self: true\n          v4_route_reflector_client: true\n          password: secret\n          bfd_peer: true\n          bfd_peer_transmit_interval: 2000\n          bfd_peer_echo_mode: true\n          other:\n            - \"prefix-list Bad_IPs in\"\n        192.168.250.12:\n          peer_group: group1\n          description: far_away\n      listen_range:\n        192.168.250.0/24: group1\n      networks:\n        - \"{{ frr_router_id }}/32\"\n        - \"{{ hostvars[inventory_hostname]['ansible_enp0s8']['ipv4']['address'] }}/24\"\n      redistribute:\n        - bgp\n        - connected\n        - kernel\n        - ospf\n        - static\n      redistribute_v6:\n        - bgp\n        - connected\n        - kernel\n```\n\n#### Example BGP\n\nBelow is an example of a BGP configuration:\n\n```yaml\nfrr_bgp:\n  asns:\n    65000:\n      log_neighbor_changes: true\n      af_v4:\n        - \"maximum-paths 2\"\n      af_v6:\n        - \"maximum-paths 2\"\n      af_evpn:\n        - \"advertise-all-vni\"\n        - \"rd {{ frr_router_id }}:1\"\n      neighbors:\n        192.168.250.11:\n          asn: 65000\n          default_originate: false\n          description: node1\n          next_hop_self: true\n          af_v4:\n            - \"soft-reconfiguration inbound\"\n        192.168.250.12:\n          asn: 65000\n          default_originate: false\n          description: node2\n          next_hop_self: true\n        \"::1\":\n          asn: 65000\n          default_originate: false\n          description: node1\n          next_hop_self: true\n          af_v6:\n            - \"activate\"\n            - \"soft-reconfiguration inbound\"\n        172.16.250.10:\n          asn: internal\n          timers_connect: 5\n          description: \"L2VPN EVPN neighbor\"\n          af_evpn:\n            - \"activate\"\n          other:\n            - \"capability extended-nexthop\"\n      networks:\n        - \"{{ frr_router_id }}/32\"\n        - \"{{ hostvars[inventory_hostname]['ansible_enp0s8']['ipv4']['address'] }}/24\"\n        - \"{{ hostvars[inventory_hostname]['ansible_enp0s9']['ipv4']['address'] }}/24\"\n        - \"{{ hostvars[inventory_hostname]['ansible_enp0s10']['ipv4']['address'] }}/24\"\n        - \"{{ hostvars[inventory_hostname]['ansible_enp0s16']['ipv4']['address'] }}/24\"\n      networks_v6:\n        - \"1::3/64\"\n```\n\nBelow is an example of a BGP summary based on the above configuration:\n\n```bash\nBGP table version is 13, local router ID is 1.1.1.1\nStatus codes: s suppressed, d damped, h history, * valid, \u003e best, = multipath,\n              i internal, r RIB-failure, S Stale, R Removed\nOrigin codes: i - IGP, e - EGP, ? - incomplete\n\n   Network          Next Hop            Metric LocPrf Weight Path\n*\u003e 1.1.1.1/32       0.0.0.0                  0         32768 i\n*\u003ei2.2.2.2/32       192.168.250.11           0    100      0 i\n*\u003ei3.3.3.3/32       192.168.250.12           0    100      0 i\n*\u003e 192.168.10.0     0.0.0.0                  0         32768 i\n*\u003ei192.168.11.0     192.168.250.11           0    100      0 i\n*\u003ei192.168.12.0     192.168.250.12           0    100      0 i\n*\u003e 192.168.20.0     0.0.0.0                  0         32768 i\n*\u003ei192.168.21.0     192.168.250.11           0    100      0 i\n*\u003ei192.168.22.0     192.168.250.12           0    100      0 i\n*\u003e 192.168.30.0     0.0.0.0                  0         32768 i\n*\u003ei192.168.31.0     192.168.250.11           0    100      0 i\n*\u003ei192.168.32.0     192.168.250.12           0    100      0 i\n* i192.168.250.0    192.168.250.11           0    100      0 i\n* i                 192.168.250.12           0    100      0 i\n*\u003e                  0.0.0.0                  0         32768 i\n\nDisplayed  13 routes and 15 total paths\n```\n\n### OSPF\n\n#### Enable OSPF\n\nTo enable OSPF routing, make sure that `ospfd: true` is configured under:\n\n```yaml\nfrr_daemons:\n  bfdd: false\n  bgpd: false\n  isisd: false\n  ldpd: false\n  nhrpd: false\n  ospf6d: false\n  ospfd: false\n  pimd: false\n  ripd: false\n  ripngd: false\n  zebra: true\n```\n\n#### Configuring OSPF\n\nIn order to configure OSPF, define the following based on your requirements:\n\n```yaml\nfrr_ospf:\n  areas:\n    0:\n      networks:\n        - \"{{ frr_router_id }}/32\"\n    1:\n      networks:\n        - \"{{ hostvars[inventory_hostname]['ansible_enp0s8']['ipv4']['address'] }}/24\"\n      auth: true\n\n    2:\n      networks:\n        - \"{{ hostvars[inventory_hostname]['ansible_enp0s9']['ipv4']['address'] }}/24\"\n      type: nssa\n\n  log_adjacency_changes: true\n  passive_interfaces: # A list of interfaces to set passive\n    - default\n  redistribute: # A list of protocols to redistribute\n    - bgp\n    - connected\n    - kernel\n    - ospf\n    - static\n  distribute_list:\n    - name: 10\n      dir: out\n      protocol: connected\n```\n#### VRF-aware OSPF\n\nEach key under ````frr_ospf_vrf_enabled```` represents VRF name:\n\n```yaml\nfrr_ospf_vrf_enabled:\n  public:\n    redistribute:\n    - bgp\n    - connected\n    passive_interfaces:\n     - lo\n    log_adjacency_changes: true\n    areas:\n      1:\n        networks:\n          - \"{{ hostvars[inventory_hostname]['ansible_ens3']['ipv4']['address'] }}/30\"\n        auth: true\n  mgmt:\n    redistribute:\n      - kernel\n    areas:\n      0:\n        networks:\n          - 172.16.0.0/12\n      2:\n        networks:\n          - 192.168.0.0/16\n        type: nssa\n```\n\n### STATIC\n\n#### Configuring STATIC routes\n\nIn order to configure static routes, define the following based on your requirements:\n\n```yaml\nfrr_static: # A dict. key = destination, value = nexthop\n  10.0.0.0/8: 192.168.1.1\n  1.1.1.1: 192.168.1.1\n  1.1.1.2: blackhole\nfrr_static_v6: # A dict. key = destination, value = nexthop\n  2001:0db8:85a3:8a2e::/64 2001::1\n```\n\n## Interface Configuration\n\n### Interfaces\n\n```yaml\nfrr_interfaces: # A dict. key = iface name, value = iface data\n  lo:\n    ip: 10.0.0.0/32 # ip can be a single value or list\n    ipv6: 2001:0db8:85a3:8a2e::1/64 # ipv6 can be a single value or list\n    description: loopback\n  eth0:\n    ip: # ip can be a single value or list\n      - 10.0.0.0/32\n      - 172.16.0.0/32\n    ipv6: # ipv6 can be a single value or list\n      - 2001:0db8:85a3:8a2e::1/64\n      - 2001:0db8:85a3:8a2e::2/64\n    vrf: management # put interface in 'management' VRF\n    auth:\n      id: 1\n      key: supersecret\n    other:\n      - \"no ipv6 nd suppress-ra\"\n      - \"link-detect\"\n```\n\u003e NOTE: Device should have correct VRF assignment on each vrf-aware interface:\n```bash\nip link set dev ${IFACE} master ${VRF}\n```\n\n\n## Upgrade/Downgrade\n\n\u003e NOTE: FRR is unable to be downgraded from 6.0.2 using this role.\n\nYou can upgrade or downgrade FRR by setting the following variable:\n\n`frr_version: 6.0.2` from `frr_version: 6.0`\n\n## Quagga configuration\n\n\u003e NOTE: Quagga must be installed from the local repos of the OS\n\nYou can configure quagga instead of FRR by using the following variable:\n\n`routing_type: quagga`\n\n\u003e Additional Quagga-specific configurations\n\n```bash\nfrr_bgp:\n  asns:\n    65000:\n      neighbors:\n        swp1:\n          **interface: true**\n```\n\n## License\n\nMIT\n\n## Author Information\n\nLarry Smith Jr.\n\n- [@mrlesmithjr](https://twitter.com/mrlesmithjr)\n- [mrlesmithjr@gmail.com](mailto:mrlesmithjr@gmail.com)\n- [http://everythingshouldbevirtual.com](http://everythingshouldbevirtual.com)\n\n\u003ca href=\"https://www.buymeacoffee.com/mrlesmithjr\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" alt=\"Buy Me A Coffee\" style=\"height: 60px !important;width: 217px !important;\" \u003e\u003c/a\u003e\n\n\u003e NOTE: Repo has been created/updated using [https://github.com/mrlesmithjr/cookiecutter-ansible-role](https://github.com/mrlesmithjr/cookiecutter-ansible-role) as a template.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrlesmithjr%2Fansible-frr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrlesmithjr%2Fansible-frr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrlesmithjr%2Fansible-frr/lists"}