diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index 371f1fe3dd36..72779ac53d52 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -22,6 +22,12 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} +route-map FROM_BGPMON_V4 deny 10 +! +route-map TO_BGPMON_V4 permit 10 +! +{% endif %} router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -153,4 +159,24 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endfor %} {% endif %} {% endblock bgp_peers_with_range %} +{% block bgp_monitors %} +{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} + neighbor BGPMON_V4 peer-group +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} + neighbor BGPMON_V4 update-source {{ prefix | ip }} +{% endif %} +{% endfor %} + neighbor BGPMON_V4 route-map FROM_BGPMON_V4 in + neighbor BGPMON_V4 route-map TO_BGPMON_V4 out + neighbor BGPMON_V4 send-community + neighbor BGPMON_V4 maximum-prefix 1 +{% for neighbor_addr, bgp_session in BGP_MONITORS.items() %} + neighbor {{ neighbor_addr }} remote-as {{ DEVICE_METADATA['localhost']['bgp_asn'] }} + neighbor {{ neighbor_addr }} peer-group BGPMON_V4 + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} + neighbor {{ neighbor_addr }} activate +{% endfor %} +{% endif %} +{% endblock bgp_monitors %} ! diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index bea5f31eeaa3..f64cbefafbd5 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -383,8 +383,11 @@ def parse_cpg(cpg, hname): bgp_session = bgp_sessions[peer] if hostname.lower() == bgp_session['name'].lower(): bgp_session['asn'] = asn + + bgp_monitors = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and bgp_sessions[key]['name'] == 'BGPMonitor' } bgp_sessions = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and int(bgp_sessions[key]['asn']) != 0 } - return bgp_sessions, myasn, bgp_peers_with_range + + return bgp_sessions, myasn, bgp_peers_with_range, bgp_monitors def parse_meta(meta, hname): @@ -516,6 +519,7 @@ def parse_xml(filename, platform=None, port_config_file=None): u_devices = None hwsku = None bgp_sessions = None + bgp_monitors = [] bgp_asn = None intfs = None vlan_intfs = None @@ -559,7 +563,7 @@ def parse_xml(filename, platform=None, port_config_file=None): if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): - (bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, hostname) + (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): @@ -580,6 +584,7 @@ def parse_xml(filename, platform=None, port_config_file=None): 'type': current_device['type'] }} results['BGP_NEIGHBOR'] = bgp_sessions + results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range if mgmt_routes: # TODO: differentiate v4 and v6 diff --git a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf index b65cad324d27..c796ef8c164b 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf @@ -25,6 +25,10 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +route-map FROM_BGPMON_V4 deny 10 +! +route-map TO_BGPMON_V4 permit 10 +! router bgp 65100 bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -114,6 +118,16 @@ router bgp 65100 neighbor fc00::76 route-map TO_BGP_PEER_V6 out maximum-paths 64 exit-address-family + neighbor BGPMON_V4 peer-group + neighbor BGPMON_V4 update-source 10.1.0.32 + neighbor BGPMON_V4 route-map FROM_BGPMON_V4 in + neighbor BGPMON_V4 route-map TO_BGPMON_V4 out + neighbor BGPMON_V4 send-community + neighbor BGPMON_V4 maximum-prefix 1 + neighbor 10.20.30.40 remote-as 65100 + neighbor 10.20.30.40 peer-group BGPMON_V4 + neighbor 10.20.30.40 description BGPMonitor + neighbor 10.20.30.40 activate !! maximum-paths 64 ! diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index e04f692729f0..5ebbaafd9671 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -2,6 +2,15 @@ + + switch-t0 + 10.1.0.32 + BGPMonitor + 10.20.30.40 + 30 + 10 + 3 + false switch-t0 @@ -42,6 +51,21 @@ + + 0 + + BGPMonitor + + + BGPPeer +
10.1.0.32
+ + + +
+
+ +
65100 switch-t0 diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index bb1a4a4a22f6..180895928fbd 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -2,6 +2,15 @@ + + switch-t0 + 10.1.0.32 + BGPMonitor + 10.20.30.40 + 30 + 10 + 3 + false switch-t0 @@ -80,6 +89,21 @@ + + 0 + + BGPMonitor + + + BGPPeer +
10.1.0.32
+ + + +
+
+ +
65100 switch-t0 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index d6544dc063e4..fb85c54cfc90 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -260,3 +260,9 @@ def test_minigraph_vxlan(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VXLAN_TUNNEL"' output = self.run_script(argument) self.assertEqual(output.strip(), "") + + def test_minigraph_bgp_mon(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "BGP_MONITORS"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 71d0c3d7db57..b77f0859584a 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -135,3 +135,9 @@ def test_minigraph_vxlan(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VXLAN_TUNNEL"' output = self.run_script(argument) self.assertEqual(output.strip(), "") + + def test_minigraph_bgp_mon(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "BGP_MONITORS"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{}") +