Connect frr to route reflector

Related-Prod: PRODX-11698
Change-Id: Icf6a61415a8965960c9510666ff6d5341ab3ffde
diff --git a/de/heat-templates/fragments/SrvInstancesBMCephOSD.yaml b/de/heat-templates/fragments/SrvInstancesBMCephOSD.yaml
index f7aba6b..6d40d62 100644
--- a/de/heat-templates/fragments/SrvInstancesBMCephOSD.yaml
+++ b/de/heat-templates/fragments/SrvInstancesBMCephOSD.yaml
@@ -85,6 +85,10 @@
   hardware_metadata:
     description: The content of lab metadata.
     type: string
+  frr_bgp_neighbors:
+    description: Comma separated list of IP of BGP neighbors
+    default: ''
+    type: string
 
 resources:
 
@@ -120,6 +124,7 @@
             $ironic_baremetal_tunnel_cidr: { get_param: ironic_baremetal_tunnel_cidr }
             $ironic_mt_enabled: { get_param: ironic_mt_enabled }
             $tunnel_interface_ip: { get_attr: [tun_server_port, fixed_ips, 0, ip_address] }
+            $frr_bgp_neighbors: { get_param: frr_bgp_neighbors }
 
   inject_files:
     type: "OS::Heat::CloudConfig"
@@ -223,6 +228,9 @@
   server_public_ip:
     description: Floating IP address of server in public network
     value: { get_attr: [server, networks, { get_param: accessible_network}, 0]}
+  server_tun_ip:
+    description: IP address of server in tunnel network
+    value: { get_attr: [ tun_server_port, fixed_ips, 0, ip_address ] }
   wc_data:
     description: Metadata from instance
     value: { get_attr: [wait_condition, data]}
diff --git a/de/heat-templates/fragments/SrvInstancesVMCephOSD.yaml b/de/heat-templates/fragments/SrvInstancesVMCephOSD.yaml
index 5cab539..157cdff 100644
--- a/de/heat-templates/fragments/SrvInstancesVMCephOSD.yaml
+++ b/de/heat-templates/fragments/SrvInstancesVMCephOSD.yaml
@@ -99,6 +99,10 @@
       If number is equal to 0 alloacation of huge pages won't be configured.
     default: '0,0'
     type: string
+  frr_bgp_neighbors:
+    description: Comma separated list of IP of BGP neighbors
+    default: ''
+    type: string
 
 resources:
 
@@ -136,6 +140,7 @@
             $ironic_mt_enabled: { get_param: ironic_mt_enabled }
             $huge_pages: { get_param: huge_pages }
             $tungstenfabric_enabled: { get_param: tungstenfabric_enabled }
+            $frr_bgp_neighbors: { get_param: frr_bgp_neighbors }
 
   inject_files:
     type: "OS::Heat::CloudConfig"
@@ -255,6 +260,9 @@
   server_public_ip:
     description: Floating IP address of server in public network
     value: { get_attr: [ server_floating_ip, floating_ip_address ] }
+  server_tun_ip:
+    description: IP address of server in tunnel network
+    value: { get_attr: [ tun_server_port, fixed_ips, 0, ip_address ] }
   wc_data:
     description: Metadata from instance
     value: { get_attr: [wait_condition, data]}
diff --git a/de/heat-templates/scripts/instance_boot.sh b/de/heat-templates/scripts/instance_boot.sh
index 14d90fd..913858b 100644
--- a/de/heat-templates/scripts/instance_boot.sh
+++ b/de/heat-templates/scripts/instance_boot.sh
@@ -25,6 +25,7 @@
 IRONIC_BAREMETAL_INTERFACE=$(ip route get ${IRONIC_BAREMETAL_NETWORK%/*} | awk '/^broadcast / {print $4}')
 IRONIC_BAREMETAL_TUNNEL_NETWORK=$ironic_baremetal_tunnel_cidr
 TUNNEL_INTERFACE_IP=$tunnel_interface_ip
+FRR_BGP_NEIGHBORS=$frr_bgp_neighbors
 TUNNEL_INTERFACE_NETWORK_NETMASK=$(ip -o addr show |grep -w ${TUNNEL_INTERFACE_IP} | awk '{print $4}' |awk -F '/' '{print $2}')
 TUNNEL_INTERFACE=$(ip -o addr show |grep -w ${TUNNEL_INTERFACE_IP}/${TUNNEL_INTERFACE_NETWORK_NETMASK} | awk '{print $2}')
 NODE_TYPE=$node_type
@@ -92,7 +93,8 @@
 #FRR Options
 FRR_BGP_AS_NUMBER=${FRR_BGP_AS_NUMBER:-64512}
 FRR_ROUTER_ID=${TUNNEL_INTERFACE_IP}
-FRR_BAGP_SOURCE_ADDRESS=${TUNNEL_INTERFACE_IP}
+FRR_BGP_SOURCE_ADDRESS=${TUNNEL_INTERFACE_IP}
+FRR_BGP_NEIGHBORS=${FRR_BGP_NEIGHBORS:-}
 
 function retry {
     local retries=$1
@@ -665,6 +667,48 @@
 
 }
 
+function setup_evpn {
+
+cat << EOF > /etc/netplan/60-evpn.yaml
+network:
+    version: 2
+    ethernets:
+        vxlan20: {}
+    bridges:
+        br20:
+          dhcp4: false
+          interfaces:
+          - vxlan20
+          parameters:
+            stp: false
+          addresses:
+          - 192.168.20.254/24
+EOF
+
+cat << EOF > /etc/systemd/system/evpn-vxlan-tunnel.service
+[Unit]
+Description=EVPN tunnel
+After=network.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=true
+ExecStart=/sbin/ip link add vxlan20 type vxlan id 20 local ${TUNNEL_INTERFACE_IP} nolearning
+ExecStart=/sbin/ip link set vxlan20 up
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+    systemctl enable evpn-vxlan-tunnel.service
+    systemctl start evpn-vxlan-tunnel.service
+
+    netplan --debug apply
+    # NOTE(vsaienko): give some time to apply changes
+    sleep 15
+
+}
+
 function install_frr {
     function _install_frr_packages {
         curl -s https://deb.frrouting.org/frr/keys.asc | sudo apt-key add -
@@ -689,20 +733,34 @@
  coalesce-time 1000
  neighbor fabric peer-group
  neighbor fabric remote-as ${FRR_BGP_AS_NUMBER}
- neighbor fabric update-source ${FRR_BAGP_SOURCE_ADDRESS}
+ neighbor fabric update-source ${FRR_BGP_SOURCE_ADDRESS}
  neighbor fabric capability extended-nexthop
  bgp listen range 10.0.0.0/8 peer-group fabric
+ neighbor rr peer-group
+ neighbor rr update-source ${FRR_BGP_SOURCE_ADDRESS}
+EOF
+
+for neighbor_ip in $(echo $FRR_BGP_NEIGHBORS | tr "," "\n"); do
+    cat << EOF >> /etc/frr/frr.conf
+ neighbor $neighbor_ip peer-group rr
+EOF
+
+done
+    cat << EOF >> /etc/frr/frr.conf
  !
  address-family ipv4 unicast
   neighbor fabric activate
+  neighbor rr activate
  exit-address-family
  !
  address-family ipv4 vpn
   neighbor fabric activate
+  neighbor rr activate
  exit-address-family
  !
  address-family l2vpn evpn
   neighbor fabric activate
+  neighbor rr activate
   advertise-all-vni
   advertise-default-gw
  exit-address-family
@@ -712,6 +770,8 @@
 EOF
 
     systemctl restart frr
+
+    setup_evpn
 }
 
 case "$NODE_TYPE" in
diff --git a/de/heat-templates/top.yaml b/de/heat-templates/top.yaml
index d80307a..8d4a3d0 100644
--- a/de/heat-templates/top.yaml
+++ b/de/heat-templates/top.yaml
@@ -718,6 +718,7 @@
           tun_network: { get_attr: [tun_network, tun_network_id] }
           tun_subnet_id: { get_attr: [tun_network, tun_subnet_id] }
           hardware_metadata: { get_param: hardware_metadata}
+          frr_bgp_neighbors: { list_join: [',', {get_attr: [workers, server_tun_ip]}] }
 
   spares:  # spares for osds/cmps
     type: OS::Heat::ResourceGroup