From c0cfe2f0725617829239b1205ea3adc3d7520d33 Mon Sep 17 00:00:00 2001 From: Georgy Kirichenko Date: Wed, 14 Aug 2024 17:04:42 +0300 Subject: [PATCH 01/11] Update release workflow --- .github/workflows/release.yml | 56 +++++------------------------------ 1 file changed, 8 insertions(+), 48 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5a77bd6e..59d50be4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ on: jobs: build-debian-package-jammy: name: build (Ubuntu 22.04) - runs-on: builder + runs-on: ubuntu-latest container: image: yanetplatform/builder-lite steps: @@ -23,35 +23,15 @@ jobs: export YANET_VERSION_REVISION=${{github.run_number}} export YANET_VERSION_HASH=${{github.sha}} export YANET_VERSION_CUSTOM=stable - meson setup --prefix=/target \ - -Dtarget=release \ - -Darch=corei7,broadwell,knl \ - -Dversion_major=$YANET_VERSION_MAJOR \ - -Dversion_minor=$YANET_VERSION_MINOR \ - -Dversion_revision=$YANET_VERSION_REVISION \ - -Dversion_hash=$YANET_VERSION_HASH \ - -Dversion_custom=$YANET_VERSION_CUSTOM \ - build - meson compile -C build - - run: meson install -C build - - run: | - export YANET_VERSION=${{github.ref_name}} - export YANET_VERSION=${YANET_VERSION#v} - cp -r debian /target/DEBIAN - sed -i "s/__VERSION__/${YANET_VERSION}/g" /target/DEBIAN/control - - run: | - export YANET_VERSION=${{github.ref_name}} - export YANET_VERSION=${YANET_VERSION#v} - mkdir /export - dpkg-deb -b "/target" /export/yanet_${YANET_VERSION}_ubuntu22.04.deb + dpkg-buildpackage -b - uses: actions/upload-artifact@v3 with: - name: target_debian - path: /export/yanet*.deb + name: target_debian22.04 + path: /__w/yanet/yanet*.deb build-debian-package-bionic: name: build (Ubuntu 18.04) - runs-on: builder + runs-on: ubuntu-latest container: image: yanetplatform/builder_ubuntu18.04-lite steps: @@ -66,28 +46,8 @@ jobs: export YANET_VERSION_REVISION=${{github.run_number}} export YANET_VERSION_HASH=${{github.sha}} export YANET_VERSION_CUSTOM=stable - meson setup --prefix=/target \ - -Dtarget=release \ - -Darch=corei7,broadwell,knl \ - -Dversion_major=$YANET_VERSION_MAJOR \ - -Dversion_minor=$YANET_VERSION_MINOR \ - -Dversion_revision=$YANET_VERSION_REVISION \ - -Dversion_hash=$YANET_VERSION_HASH \ - -Dversion_custom=$YANET_VERSION_CUSTOM \ - build - meson compile -C build - - run: meson install -C build - - run: | - export YANET_VERSION=${{github.ref_name}} - export YANET_VERSION=${YANET_VERSION#v} - cp -r debian /target/DEBIAN - sed -i "s/__VERSION__/${YANET_VERSION}/g" /target/DEBIAN/control - - run: | - export YANET_VERSION=${{github.ref_name}} - export YANET_VERSION=${YANET_VERSION#v} - mkdir /export - dpkg-deb -b "/target" /export/yanet_${YANET_VERSION}_ubuntu18.04.deb + dpkg-buildpackage -b - uses: actions/upload-artifact@v3 with: - name: target_debian - path: /export/yanet*.deb + name: target_debian18.04 + path: /__w/yanet/yanet*.deb From dd064b6079157ccb930c20d74b5c45f61fd41a8d Mon Sep 17 00:00:00 2001 From: Georgy Kirichenko Date: Thu, 22 Aug 2024 14:26:06 +0300 Subject: [PATCH 02/11] Export image to Dockerhub --- .github/workflows/release.yml | 64 ++++++++++++++--------------------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 59d50be4..90407dd6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,52 +2,38 @@ name: Release on: push: - tags: - - 'v[0-9]+.[0-9]+' + branch: + - 'release/*' jobs: build-debian-package-jammy: - name: build (Ubuntu 22.04) + name: build-image runs-on: ubuntu-latest - container: - image: yanetplatform/builder-lite + permissions: + packages: write + contents: read + id-token: write steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v4 with: submodules: recursive - - run: | - export YANET_VERSION=${{github.ref_name}} - export YANET_VERSION=${YANET_VERSION#v} - export YANET_VERSION_MAJOR=${YANET_VERSION%.*} - export YANET_VERSION_MINOR=${YANET_VERSION#*.} - export YANET_VERSION_REVISION=${{github.run_number}} - export YANET_VERSION_HASH=${{github.sha}} - export YANET_VERSION_CUSTOM=stable - dpkg-buildpackage -b - - uses: actions/upload-artifact@v3 + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 with: - name: target_debian22.04 - path: /__w/yanet/yanet*.deb - - build-debian-package-bionic: - name: build (Ubuntu 18.04) - runs-on: ubuntu-latest - container: - image: yanetplatform/builder_ubuntu18.04-lite - steps: - - uses: actions/checkout@v1 + images: yanetplatform/yanet + - name: Log in to Docker Hub + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a with: - submodules: recursive - - run: | - export YANET_VERSION=${{github.ref_name}} - export YANET_VERSION=${YANET_VERSION#v} - export YANET_VERSION_MAJOR=${YANET_VERSION%.*} - export YANET_VERSION_MINOR=${YANET_VERSION#*.} - export YANET_VERSION_REVISION=${{github.run_number}} - export YANET_VERSION_HASH=${{github.sha}} - export YANET_VERSION_CUSTOM=stable - dpkg-buildpackage -b - - uses: actions/upload-artifact@v3 + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Build and push Docker image + id: push + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 with: - name: target_debian18.04 - path: /__w/yanet/yanet*.deb + context: . + file: ./build/Dockerfile.image + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 8b9ca68369435aeb417995d37a73599ff8b45563 Mon Sep 17 00:00:00 2001 From: Ivan Morozko Date: Fri, 2 Aug 2024 14:49:27 +0300 Subject: [PATCH 03/11] Add pragma once to config.release.h In this header file there was no guard against including it multiple times --- common/config.release.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/config.release.h b/common/config.release.h index e77beb6c..73b7f667 100644 --- a/common/config.release.h +++ b/common/config.release.h @@ -1,3 +1,5 @@ +#pragma once + #define CONFIG_YADECAP_MBUFS_COUNT (48 * 1024) #define CONFIG_YADECAP_MBUF_SIZE (10 * 1024) #define CONFIG_YADECAP_WORKER_PORTS_SIZE (8) From e50920e46907e04c448caec0ed19eceae3b93383 Mon Sep 17 00:00:00 2001 From: Andrey Kiselev Date: Tue, 10 Sep 2024 16:42:04 +0300 Subject: [PATCH 04/11] Append yanet-announcer.py into YANET image --- build/Dockerfile.image | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/build/Dockerfile.image b/build/Dockerfile.image index 72e3c3aa..2380b47a 100644 --- a/build/Dockerfile.image +++ b/build/Dockerfile.image @@ -1,5 +1,5 @@ ARG RELEASE=22.04 -FROM --platform=linux/amd64 ubuntu:${RELEASE} as environment +FROM --platform=linux/amd64 ubuntu:${RELEASE} AS environment RUN apt-get update RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ @@ -28,7 +28,8 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ RUN python3 -m pip install meson==0.61.2 -FROM environment as builder + +FROM environment AS builder ARG YANET_VERSION_MAJOR=0 ARG YANET_VERSION_MINOR=0 @@ -50,6 +51,7 @@ RUN meson setup --prefix=/target \ RUN meson compile -C build + FROM --platform=linux/amd64 ubuntu:${RELEASE} RUN apt-get update @@ -61,8 +63,10 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ libmlx5-1 \ libnuma1 \ libpcap0.8 \ - netbase + netbase \ + python3 COPY --from=builder /opt/yanet/build/controlplane/yanet-controlplane /usr/bin/ COPY --from=builder /opt/yanet/build/dataplane/yanet-dataplane /usr/bin/ COPY --from=builder /opt/yanet/build/cli/yanet-cli /usr/bin/ +COPY --from=builder /opt/yanet/yanet-announcer.py /usr/bin/yanet-announcer From 7c177c7fe855f72cf469a2c35afd056ccbcaeee1 Mon Sep 17 00:00:00 2001 From: Alexander Lopintsev Date: Sat, 7 Sep 2024 20:05:21 +0300 Subject: [PATCH 05/11] Add total counters for ingress and egress packet drops --- cli/telegraf.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cli/telegraf.h b/cli/telegraf.h index ae0e4ee9..401d45ae 100644 --- a/cli/telegraf.h +++ b/cli/telegraf.h @@ -106,10 +106,13 @@ void unsafe() const auto& [memory_groups, memory_objects] = memory_stats; const auto durations = controlplane.controlplane_durations(); + uint64_t total_acl_ingress_dropPackets = 0, total_acl_egress_dropPackets = 0; for (const auto& [coreId, worker] : responseWorkers) { const auto& [iterations, stats, ports_stats] = worker; + total_acl_ingress_dropPackets += stats.acl_ingress_dropPackets; + total_acl_egress_dropPackets += stats.acl_egress_dropPackets; printf("worker,coreId=%u " "iterations=%luu," @@ -174,6 +177,12 @@ void unsafe() stats.logs_drops, stats.logs_packets); + printf("worker,coreId=all " + "acl_ingress_dropPackets=%luu," + "acl_egress_dropPackets=%luu\n", + total_acl_ingress_dropPackets, + total_acl_egress_dropPackets); + for (const auto& [physicalPortName, stats] : ports_stats) { printf("worker,coreId=%u,physicalPortName=%s " From c5d0822ead50ba663eb3aa587d332425a9c94188 Mon Sep 17 00:00:00 2001 From: Georgy Kirichenko Date: Thu, 6 Jun 2024 22:56:00 +0300 Subject: [PATCH 06/11] WIP: bird import proto --- common/icp.h | 4 +- controlplane/libbird.cpp | 609 +++++++++++++++++++++++++++++++++++++++ controlplane/libbird.h | 175 +++++++++++ controlplane/main.cpp | 4 +- controlplane/meson.build | 5 +- controlplane/rib.cpp | 21 ++ controlplane/rib.h | 1 + dataplane/main.cpp | 4 +- dataplane/meson.build | 2 +- logger/main.cpp | 2 +- logger/meson.build | 2 +- meson.build | 4 +- 12 files changed, 820 insertions(+), 13 deletions(-) create mode 100644 controlplane/libbird.cpp create mode 100644 controlplane/libbird.h diff --git a/common/icp.h b/common/icp.h index 3b2b7810..14febcf7 100644 --- a/common/icp.h +++ b/common/icp.h @@ -664,7 +664,9 @@ using eor = std::tuple; ///< table_name -using request = std::vector>; +using action = std::variant; + +using request = std::vector; } namespace rib_summary diff --git a/controlplane/libbird.cpp b/controlplane/libbird.cpp new file mode 100644 index 00000000..79939bb0 --- /dev/null +++ b/controlplane/libbird.cpp @@ -0,0 +1,609 @@ +#include "libbird.h" + +#include +#include "common/type.h" +#include "common/icp.h" +#include "controlplane/rib.h" + +static inline bool +decode_u8(uintptr_t *ppos, uintptr_t end, uint8_t *pvalue) +{ + if (*ppos + sizeof(uint8_t) > end) + return false; + *pvalue = *(uint8_t *)*ppos; + *ppos += sizeof(uint8_t); + return true; +} + +static inline bool +decode_u16(uintptr_t *ppos, uintptr_t end, uint16_t *pvalue) +{ + if (*ppos + sizeof(uint16_t) > end) + return false; + *pvalue = *(uint16_t *)*ppos; + *ppos += sizeof(uint16_t); + return true; +} + +static inline bool +decode_u32(uintptr_t *ppos, uintptr_t end, uint32_t *pvalue) +{ + if (*ppos + sizeof(uint32_t) > end) + return false; + *pvalue = *(uint32_t *)*ppos; + *ppos += sizeof(uint32_t); + return true; +} + +static inline bool +decode_chunk(uintptr_t *ppos, uintptr_t end, uintptr_t *pchunk_end) +{ + uint32_t chunk_size; + if (!decode_u32(ppos, end, &chunk_size)) + return false; + *pchunk_end = *ppos + chunk_size; + return *pchunk_end <= end; +} + +static inline bool +decode_u32_array(uintptr_t *ppos, uintptr_t end, uintptr_t *parray_end) +{ + uint32_t array_count; + if (!decode_u32(ppos, end, &array_count)) + return false; + *parray_end = *ppos + sizeof(uint32_t) * array_count; + return (*parray_end <= end); +} + +static inline bool +decode_ip_addr(uintptr_t *ppos, uintptr_t end, ip_addr *paddr) +{ + if (*ppos + sizeof(ip_addr) > end) + return false; + *paddr = *(ip_addr *)*ppos; + *ppos += sizeof(ip_addr); + return true; +} + +static inline bool +decode_net_addr(uintptr_t *ppos, uintptr_t end, net_addr_union *paddr) +{ + if (*ppos + sizeof(net_addr_union) > end) + return false; + *paddr = *(net_addr_union *)*ppos; + // Some members of net_addr_union are variable length structures so + // check the length attribute. + if (*ppos + paddr->n.length > end) + return false; + if (paddr->n.length <= sizeof(net_addr_union)) { + *ppos += sizeof(net_addr_union); + return true; + } + return false; + /* + * FIXME: this is not supported yet + memcpy( + paddr + 1, (void *)(*ppos + sizeof(net_addr_union)), + paddr->n.length - sizeof(net_addr_union) + ); + *ppos += paddr->n.length; + return true; + */ +} + +static inline bool +decode_u16_array(uintptr_t *ppos, uintptr_t end, std::vector *values) +{ + size_t attr_end; + if (!decode_chunk(ppos, end, &attr_end)) { + return false; + } + + while (*ppos < attr_end) { + uint16_t value; + if (!decode_u16(ppos, attr_end, &value)) { + return false; + } + + values->emplace_back(value); + } + + return true; +} + +static inline bool +decode_u32_array(uintptr_t *ppos, uintptr_t end, std::vector *values) +{ + size_t attr_end; + if (!decode_chunk(ppos, end, &attr_end)) { + return false; + } + + while (*ppos < attr_end) { + uint32_t value; + if (!decode_u32(ppos, attr_end, &value)) { + return false; + } + + values->emplace_back(value); + } + + return true; +} + +static inline bool +decode_as_path(uintptr_t *ppos, uintptr_t end, std::vector *as_path) +{ + size_t attr_end; + if (!decode_chunk(ppos, end, &attr_end)) { + return false; + } + + while (*ppos < attr_end) { + uint8_t segment_type; + if (!decode_u8(ppos, attr_end, &segment_type)) { + return false; + } + + if (segment_type != 2 && segment_type != 3) { + return false; + } + + uint8_t segment_len; + if (!decode_u8(ppos, attr_end, &segment_len)) { + return false; + } + + for (uint16_t idx = 0; idx < segment_len; ++idx) { + uint32_t as; + if (!decode_u32(ppos, attr_end, &as)) { + return false; + } + as = ntohl(as); + as_path->emplace_back(as); + } + } + + return true; +} + +static inline bool +ipa_is_ip4(ip_addr addr) +{ + return addr.addr[0] == 0 && addr.addr[1] == 0 && addr.addr[2] == 0xffff; +} + +static inline common::ipv4_address_t +ipa_to_address_4(ip_addr addr) +{ + return common::ipv4_address_t(addr.addr[3]); +} + +static inline common::ipv6_address_t +ipa_to_address_6(ip_addr addr) +{ + addr.addr[0] = ntohl(addr.addr[0]); + addr.addr[1] = ntohl(addr.addr[1]); + addr.addr[2] = ntohl(addr.addr[2]); + addr.addr[3] = ntohl(addr.addr[3]); + return common::ipv6_address_t((uint8_t *)&addr); +} + +static inline common::ip_address_t +ipa_to_address(ip_addr addr) +{ + if (ipa_is_ip4(addr)) + return common::ip_address_t(ipa_to_address_4(addr)); + return common::ip_address_t(ipa_to_address_6(addr)); +} + +static inline bool +recover_prefix_info(net_addr_union *paddr, common::ip_prefix_t *prefix, + common::ip_address_t *vpnDST, uint32_t *vpnRD) +{ + + switch (paddr->n.type) { + case NET_IP4: { + *prefix = common::ip_prefix_t(common::ipv4_address_t(paddr->ip4.prefix), paddr->ip4.pxlen); + break; + } + + case NET_IP6: { + *prefix = common::ip_prefix_t(ipa_to_address_6(paddr->ip6.prefix), paddr->ip6.pxlen); + break; + } + + case NET_VPN4: { + if ((paddr->vpn4.rd >> 48) != 1) { + return false; + } + + *prefix = common::ip_prefix_t(common::ipv4_address_t(paddr->vpn4.prefix), paddr->vpn4.pxlen); + *vpnDST = common::ip_address_t(common::ipv4_address_t(paddr->vpn4.rd >> 16)); + *vpnRD = paddr->vpn4.rd & 0xffff; + break; + } + + case NET_VPN6: { + if ((paddr->vpn6.rd >> 48) != 1) { + return false; + } + + *prefix = common::ip_prefix_t(ipa_to_address_6(paddr->vpn6.prefix), paddr->vpn6.pxlen); + *vpnDST = common::ip_address_t(common::ipv4_address_t(paddr->vpn4.rd >> 16)); + *vpnRD = paddr->vpn6.rd & 0xffff; + + break; + } + + default: + return false; + } + + return true; +} + +static inline bool +recover_next_hop(uintptr_t *ppos, uintptr_t end, common::ip_address_t *next_hop) +{ + if (end - *ppos != sizeof(ip_addr) && + end - *ppos != 2 * sizeof(ip_addr)) { + return false; + } + + if (end - *ppos == sizeof(ip_addr)) { + ip_addr nh_addr; + if (!decode_ip_addr(ppos, end, &nh_addr)) { + return false; + } + *next_hop = ipa_to_address(nh_addr); + return true; + } + + ip_addr nh_addr1; + ip_addr nh_addr2; + if (!decode_ip_addr(ppos, end, &nh_addr1) || + !decode_ip_addr(ppos, end, &nh_addr2)) { + return false; + } + + if (nh_addr2.addr[0] == 0 && nh_addr2.addr[1] == 0 && + nh_addr2.addr[2] == 0 && nh_addr2.addr[3] == 0) { + *next_hop = ipa_to_address(nh_addr1); + } else { + *next_hop = ipa_to_address(nh_addr2); + } + + return true; +} + +static bool +parse_route_update(uintptr_t *ppos, uintptr_t end, const char *vrf, + common::icp::rib_update::action *paction) +{ + common::ip_address_t peer_address; + std::string attribute_origin; + std::string path_information; + std::vector attribute_aspath; + std::set attribute_communities; + std::set attribute_large_communities; + std::vector labels; + + uint32_t attribute_local_preference = 0; + uint32_t attribute_med = 0; + + common::ip_address_t next_hop; + common::ip_prefix_t prefix; + common::ip_address_t vpnDST; + uint32_t vpnRD = 0; + + /* Decode route prefix. */ + net_addr_union addr; + if (!decode_net_addr(ppos, end, &addr)) + return false; + + if (!recover_prefix_info(&addr, &prefix, &vpnDST, &vpnRD)) + return false; + + uint32_t type; + if (!decode_u32(ppos, end, &type)) + return false; + + ip_addr remote_addr; + if (!decode_ip_addr(ppos, end, &remote_addr)) + return false; + peer_address = ipa_to_address(remote_addr); + + size_t attrs_end; + if (!decode_chunk(ppos, end, &attrs_end)) + return false; + + if (attrs_end != end) + return false; + + /* Now decode all attributes one by one. */ + while (*ppos < attrs_end) { + uint32_t attr_id; + if (!decode_u32(ppos, attrs_end, &attr_id)) + return false; + + + switch (EA_ID(attr_id)) { + case BA_ORIGIN: { + uint32_t origin; + if (!decode_u32(ppos, attrs_end, &origin)) { + return false; + } + switch (origin) { + case 0: attribute_origin = "IGP"; break; + case 1: attribute_origin = "EGP"; break; + case 2: attribute_origin = "Incomplete"; break; + default: attribute_origin = "?"; + } + + break; + } + + case BA_MULTI_EXIT_DISC: { + uint32_t med; + if (!decode_u32(ppos, attrs_end, &med)) { + return false; + } + + attribute_med = med; + + break; + } + + case BA_LOCAL_PREF: { + uint32_t pref; + if (!decode_u32(ppos, attrs_end, &pref)) { + return false; + } + + attribute_local_preference = pref; + + break; + } + + case BA_ORIGINATOR_ID: { + uint32_t originator; + if (!decode_u32(ppos, attrs_end, &originator)) { + return false; + } + + break; + } + + case BA_AS_PATH: { + if (!decode_as_path(ppos, attrs_end, &attribute_aspath)) { + return false; + } + + break; + } + + case BA_NEXT_HOP: { + size_t attr_end; + if (!decode_chunk(ppos, attrs_end, &attr_end)) { + return false; + } + + if (!recover_next_hop(ppos, attr_end, &next_hop)) { + return false; + } + + break; + } + + case BA_COMMUNITY: { + std::vector communities; + if (!decode_u16_array(ppos, attrs_end, &communities)) { + return false; + } + + if (communities.size() % 2 != 0) { + return false; + } + + for (size_t idx = 0; idx < communities.size() / 2; ++idx) { + attribute_communities.emplace( + communities[idx * 2 + 0], + communities[idx * 2 + 1] + ); + } + + break; + } + + case BA_CLUSTER_LIST: { + std::vector clusters; + if (!decode_u32_array(ppos, attrs_end, &clusters)) { + return false; + } + + break; + } + + case BA_EXT_COMMUNITY: { + std::vector ext_communities; + if (!decode_u32_array(ppos, attrs_end, &ext_communities)) { + return false; + } + + break; + } + + case BA_LARGE_COMMUNITY: { + std::vector large_communities; + if (!decode_u32_array(ppos, attrs_end, &large_communities)) { + return false; + } + + if (large_communities.size() % 3 != 0) { + return false; + } + + for (size_t idx = 0; idx < large_communities.size() / 3; + ++idx) { + + attribute_large_communities.emplace( + large_communities[idx * 3 + 0], + large_communities[idx * 3 + 1], + large_communities[idx * 3 + 2] + ); + } + + break; + } + + case BA_MPLS_LABEL_STACK: { + if (!decode_u32_array(ppos, attrs_end, &labels)) { + return false; + } + + break; + } + + default: + return false; + + } + } + + std::string afi; + std::string safi; + + //FIXME: table name + if (prefix.is_ipv4()) { + afi = "ipv4"; + } else { + afi = "ipv6"; + } + + if (vpnRD == 0) { + safi = "unicast"; + } else { + safi = "mpls-vpn"; + } + + if (type == 1) { + common::icp::rib_update::insert insert = {"bgp", + std::string(vrf), + YANET_RIB_PRIORITY_DEFAULT, + {}}; + + auto& announce = std::get<3>(insert)[{peer_address, + attribute_origin, + attribute_med, + attribute_aspath, + attribute_communities, + attribute_large_communities, + attribute_local_preference}]; + + auto& announce_table = announce[afi + " " + safi]; + announce_table[next_hop].emplace_back(prefix, std::to_string(vpnRD), labels); + + *paction = insert; + } else { + common::icp::rib_update::remove remove = {"bgp", + std::string(vrf), + YANET_RIB_PRIORITY_DEFAULT, + {}}; + + auto& announce = std::get<3>(remove)[peer_address]; + + //FIXME: table name + auto& announce_table = announce[afi + " " + safi]; + announce_table.emplace_back(prefix, std::to_string(vpnRD), labels); + + *paction = remove; + } + + return true; +} + +void +read_bird_feed(const char *sock_name, const char *vrf, class rib_t *rib) +{ + /* Connect to bird export socket. */ + int bird_sock = socket(AF_UNIX, SOCK_STREAM, 0); + struct sockaddr_un server_addr; + server_addr.sun_family = AF_UNIX; + strncpy(server_addr.sun_path, sock_name, sizeof(server_addr.sun_path) - 1); + if (connect(bird_sock, + (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) { + return; + } + + /* + * Read buffer is used to accumulate multuple route updates and + * flush then at once. 1Mib looks good as the buffur size. + */ + const size_t buf_size = 1 << 20; + void *read_buf = malloc(buf_size); + if (read_buf == NULL) { + close(bird_sock); + return; + } + /* + * The variable is the offset to read data to and denotes the first + * byte which could nit be parsed yet. + */ + size_t read_pos = 0; + /* + * Parse position is the position of the next one route update to + * process. + */ + size_t parse_pos = 0; + + common::icp::rib_update::request requests; + + for (;;) + { + /* Read as mush as possible data */ + ssize_t readen = read(bird_sock, + (void *)((uintptr_t)read_buf + read_pos), + buf_size - read_pos); + if (readen <= 0) { + break; + } + + /* Adust read postion and try to recover next route update. */ + read_pos += readen; + while (parse_pos < read_pos) { + /* pos and end denote addresses of a memory chunk to parse. */ + uintptr_t pos = (uintptr_t)read_buf + parse_pos; + uintptr_t end = (uintptr_t)read_buf + read_pos; + + /* Determine boundaries of the next route update. */ + uintptr_t route_end; + if (!decode_chunk(&pos, end, &route_end)) + break; + + common::icp::rib_update::action action; + if (!parse_route_update(&pos, route_end, vrf, &action)) + break; + + requests.emplace_back(action); + + parse_pos = pos - (uintptr_t)read_buf; + } + + rib->rib_update(requests); + rib->rib_flush(); + + if (buf_size - read_pos < buf_size / 2) { + memmove(read_buf, + (void *)((uintptr_t)read_buf + parse_pos), + read_pos - parse_pos); + read_pos = read_pos - parse_pos; + parse_pos = 0; + } + } + + free(read_buf); + close(bird_sock); + + return; +} diff --git a/controlplane/libbird.h b/controlplane/libbird.h new file mode 100644 index 00000000..92646132 --- /dev/null +++ b/controlplane/libbird.h @@ -0,0 +1,175 @@ +#ifndef LIBBIRD_H +#define LIBBIRD_H + +#include + +#define NET_IP4 1 +#define NET_IP6 2 +#define NET_VPN4 3 +#define NET_VPN6 4 +#define NET_ROA4 5 +#define NET_ROA6 6 +#define NET_FLOW4 7 +#define NET_FLOW6 8 +#define NET_IP6_SADR 9 +#define NET_MPLS 10 +#define NET_MAX 11 + +#define NB_IP4 (1 << NET_IP4) +#define NB_IP6 (1 << NET_IP6) +#define NB_VPN4 (1 << NET_VPN4) +#define NB_VPN6 (1 << NET_VPN6) +#define NB_ROA4 (1 << NET_ROA4) +#define NB_ROA6 (1 << NET_ROA6) +#define NB_FLOW4 (1 << NET_FLOW4) +#define NB_FLOW6 (1 << NET_FLOW6) +#define NB_IP6_SADR (1 << NET_IP6_SADR) +#define NB_MPLS (1 << NET_MPLS) + +#define NB_IP (NB_IP4 | NB_IP6) +#define NB_VPN (NB_VPN4 | NB_VPN6) +#define NB_ROA (NB_ROA4 | NB_ROA6) +#define NB_FLOW (NB_FLOW4 | NB_FLOW6) +#define NB_DEST (NB_IP | NB_IP6_SADR | NB_VPN | NB_MPLS) +#define NB_ANY 0xffffffff + +#define BA_ORIGIN 0x01 /* RFC 4271 */ /* WM */ +#define BA_AS_PATH 0x02 /* WM */ +#define BA_NEXT_HOP 0x03 /* WM */ +#define BA_MULTI_EXIT_DISC 0x04 /* ON */ +#define BA_LOCAL_PREF 0x05 /* WD */ +#define BA_ATOMIC_AGGR 0x06 /* WD */ +#define BA_AGGREGATOR 0x07 /* OT */ +#define BA_COMMUNITY 0x08 /* RFC 1997 */ /* OT */ +#define BA_ORIGINATOR_ID 0x09 /* RFC 4456 */ /* ON */ +#define BA_CLUSTER_LIST 0x0a /* RFC 4456 */ /* ON */ +#define BA_MP_REACH_NLRI 0x0e /* RFC 4760 */ +#define BA_MP_UNREACH_NLRI 0x0f /* RFC 4760 */ +#define BA_EXT_COMMUNITY 0x10 /* RFC 4360 */ +#define BA_AS4_PATH 0x11 /* RFC 6793 */ +#define BA_AS4_AGGREGATOR 0x12 /* RFC 6793 */ +#define BA_AIGP 0x1a /* RFC 7311 */ +#define BA_LARGE_COMMUNITY 0x20 /* RFC 8092 */ +#define BA_ONLY_TO_CUSTOMER 0x23 /* RFC 9234 */ + +/* Bird's private internal BGP attributes */ +#define BA_MPLS_LABEL_STACK 0xfe /* MPLS label stack transfer attribute */ + +#define EA_ID(ea) ((ea) & 0xff) +#define EA_PROTO(ea) ((ea) >> 8) + +typedef uint32_t ip4_addr; + +typedef struct ip6_addr { + uint32_t addr[4]; +} ip6_addr; + +typedef ip6_addr ip_addr; + +typedef struct net_addr { + uint8_t type; + uint8_t pxlen; + uint16_t length; + uint8_t data[20]; + uint64_t align[0]; +} net_addr; + +typedef struct net_addr_ip4 { + uint8_t type; + uint8_t pxlen; + uint16_t length; + ip4_addr prefix; +} net_addr_ip4; + +typedef struct net_addr_ip6 { + uint8_t type; + uint8_t pxlen; + uint16_t length; + ip6_addr prefix; +} net_addr_ip6; + +typedef struct net_addr_vpn4 { + uint8_t type; + uint8_t pxlen; + uint16_t length; + ip4_addr prefix; + uint64_t rd; +} net_addr_vpn4; + +typedef struct net_addr_vpn6 { + uint8_t type; + uint8_t pxlen; + uint16_t length; + ip6_addr prefix; + uint32_t padding; + uint64_t rd; +} net_addr_vpn6; + +typedef struct net_addr_roa4 { + uint8_t type; + uint8_t pxlen; + uint16_t length; + ip4_addr prefix; + uint32_t max_pxlen; + uint32_t asn; +} net_addr_roa4; + +typedef struct net_addr_roa6 { + uint8_t type; + uint8_t pxlen; + uint16_t length; + ip6_addr prefix; + uint32_t max_pxlen; + uint32_t asn; +} net_addr_roa6; + +typedef struct net_addr_flow4 { + uint8_t type; + uint8_t pxlen; + uint16_t length; + ip4_addr prefix; + uint8_t data[0]; +} net_addr_flow4; + +typedef struct net_addr_flow6 { + uint8_t type; + uint8_t pxlen; + uint16_t length; + ip6_addr prefix; + uint8_t data[0]; +} net_addr_flow6; + +typedef struct net_addr_mpls { + uint8_t type; + uint8_t pxlen; + uint16_t length; + uint32_t label; +} net_addr_mpls; + +typedef struct net_addr_ip6_sadr { + uint8_t type; + uint8_t dst_pxlen; + uint16_t length; + ip6_addr dst_prefix; + int32_t src_pxlen; /* s32 to avoid padding */ + ip6_addr src_prefix; +} net_addr_ip6_sadr; + +typedef union net_addr_union { + net_addr n; + net_addr_ip4 ip4; + net_addr_ip6 ip6; + net_addr_vpn4 vpn4; + net_addr_vpn6 vpn6; + net_addr_roa4 roa4; + net_addr_roa6 roa6; + net_addr_flow4 flow4; + net_addr_flow6 flow6; + net_addr_ip6_sadr ip6_sadr; + net_addr_mpls mpls; +} net_addr_union; + +void +read_bird_feed(const char *sock_name, const char *vrf, class rib_t *rib); + +#endif diff --git a/controlplane/main.cpp b/controlplane/main.cpp index d5288f79..2fb6debf 100644 --- a/controlplane/main.cpp +++ b/controlplane/main.cpp @@ -1,5 +1,5 @@ #include -#include +//#include #include @@ -58,7 +58,7 @@ int main(int argc, return 3; } - sd_notify(0, "READY=1"); +// sd_notify(0, "READY=1"); application.start(); application.join(); diff --git a/controlplane/meson.build b/controlplane/meson.build index f888b09c..6fe171fa 100644 --- a/controlplane/meson.build +++ b/controlplane/meson.build @@ -1,6 +1,6 @@ dependencies = [] dependencies += libjson.get_variable('nlohmann_json_dep') -dependencies += dependency('libsystemd') +#dependencies += dependency('libsystemd') dependencies += dependency('threads') dependencies += libyanet_fwparser_dep dependencies += libyanet_protobuf_dep @@ -31,7 +31,8 @@ sources = files('acl_compiler.cpp', 'rib.cpp', 'route.cpp', 'telegraf.cpp', - 'tun64.cpp') + 'tun64.cpp', + 'libbird.cpp') foreach arch : archs bin = 'yanet-controlplane' diff --git a/controlplane/rib.cpp b/controlplane/rib.cpp index c66e21ed..bb3eff20 100644 --- a/controlplane/rib.cpp +++ b/controlplane/rib.cpp @@ -1,6 +1,9 @@ #include "rib.h" +#include "libbird.h" #include "controlplane.h" +#include + using namespace controlplane::module; rib_t::rib_t() @@ -873,4 +876,22 @@ void rib_t::rib_thread() std::this_thread::sleep_for(std::chrono::milliseconds{200}); } + +} + +void rib_t::bird_thread() +{ + while (!flagStop) { + read_bird_feed("/tmp/export.sock", "default", this); + + common::icp::rib_update::clear request = {"bgp", std::nullopt}; +/* std::get<1>(request) = {peer_address, + {"default", ///< @todo: vrf + YANET_RIB_PRIORITY_DEFAULT}}; +*/ + rib_clear(request); + + std::this_thread::sleep_for(std::chrono::milliseconds{200}); + } + } diff --git a/controlplane/rib.h b/controlplane/rib.h index c436dc3b..a6f9d977 100644 --- a/controlplane/rib.h +++ b/controlplane/rib.h @@ -62,6 +62,7 @@ class rib_t : public cModule void rib_eor(const common::icp::rib_update::eor& request); void rib_thread(); + void bird_thread(); protected: mutable std::mutex rib_update_mutex; diff --git a/dataplane/main.cpp b/dataplane/main.cpp index e88d5ab3..aeec9503 100644 --- a/dataplane/main.cpp +++ b/dataplane/main.cpp @@ -1,5 +1,5 @@ #include -#include +//#include #include @@ -67,7 +67,7 @@ int main(int argc, return 3; } - sd_notify(0, "READY=1"); +// sd_notify(0, "READY=1"); dataPlane.start(); dataPlane.join(); diff --git a/dataplane/meson.build b/dataplane/meson.build index f3599582..af1ba5d0 100644 --- a/dataplane/meson.build +++ b/dataplane/meson.build @@ -1,7 +1,7 @@ dependencies = [] dependencies += libdpdk.get_variable('dpdk_dep') dependencies += libjson.get_variable('nlohmann_json_dep') -dependencies += dependency('libsystemd') +#dependencies += dependency('libsystemd') dependencies += dependency('threads') sources = files('bus.cpp', diff --git a/logger/main.cpp b/logger/main.cpp index 1492ee98..8510606d 100644 --- a/logger/main.cpp +++ b/logger/main.cpp @@ -318,7 +318,7 @@ int main(int argc, return ret; } - sd_notify(0, "READY=1"); + //sd_notify(0, "READY=1"); return runLogger(); } diff --git a/logger/meson.build b/logger/meson.build index c07d93eb..8ba9e5e4 100644 --- a/logger/meson.build +++ b/logger/meson.build @@ -1,7 +1,7 @@ dependencies = [] dependencies += libdpdk.get_variable('dpdk_dep') dependencies += libjson.get_variable('nlohmann_json_dep') -dependencies += dependency('libsystemd') +#dependencies += dependency('libsystemd') dependencies += dependency('threads') sources = files('main.cpp') diff --git a/meson.build b/meson.build index 970a7484..ccbee825 100644 --- a/meson.build +++ b/meson.build @@ -2,9 +2,7 @@ project('yanet', 'cpp', meson_version: '>= 0.61', default_options: ['cpp_std=c++17', 'buildtype=release', - 'warning_level=2', - 'werror=true', - 'b_lto=true']) + 'warning_level=2']) yanet_rootdir = include_directories('.') From 8581dc1359a4057d14426c030df5fec0edc80d8f Mon Sep 17 00:00:00 2001 From: Georgy Kirichenko Date: Fri, 22 Nov 2024 14:42:02 +0300 Subject: [PATCH 07/11] Start bird import thread --- controlplane/rib.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/controlplane/rib.cpp b/controlplane/rib.cpp index bb3eff20..4d531545 100644 --- a/controlplane/rib.cpp +++ b/controlplane/rib.cpp @@ -72,6 +72,10 @@ eResult rib_t::init() rib_thread(); }); + funcThreads.emplace_back([this]() { + bird_thread(); + }); + return eResult::success; } From 17e89f6f45e79047fdc6415263f4a171772811b7 Mon Sep 17 00:00:00 2001 From: Markuu-s Date: Sat, 28 Dec 2024 16:34:05 +0300 Subject: [PATCH 08/11] Add config-read and run thread_birds with arguments. --- common/controlplaneconfig.h | 29 ++++++++++++++++++++++ controlplane/configparser.cpp | 33 +++++++++++++++++++++++++ controlplane/configparser.h | 1 + controlplane/controlplane.cpp | 18 ++++++++++++++ controlplane/controlplane.h | 1 + controlplane/rib.cpp | 45 +++++++++++++++++++++++------------ controlplane/rib.h | 4 +++- 7 files changed, 115 insertions(+), 16 deletions(-) diff --git a/common/controlplaneconfig.h b/common/controlplaneconfig.h index a763589f..d68a84f8 100644 --- a/common/controlplaneconfig.h +++ b/common/controlplaneconfig.h @@ -141,6 +141,32 @@ class interface_t common::globalBase::tFlow flow; }; +class bird_import_t +{ +public: + void pop(common::stream_in_t& stream) + { + stream.pop(socket); + stream.pop(vrf); + stream.pop(flow); + } + + void push(common::stream_out_t& stream) const + { + stream.push(socket); + stream.push(vrf); + stream.push(flow); + } + +public: + inline static const std::string socketStr = "socket"; + inline static const std::string vrfStr = "vrf"; + + std::string socket; + std::string vrf; + common::globalBase::tFlow flow; +}; + class config_t { public: @@ -168,6 +194,7 @@ class config_t stream.pop(local_prefixes); stream.pop(peers); stream.pop(interfaces); + stream.pop(bird_imports); } void push(common::stream_out_t& stream) const @@ -183,6 +210,7 @@ class config_t stream.push(local_prefixes); stream.push(peers); stream.push(interfaces); + stream.push(bird_imports); } public: @@ -197,6 +225,7 @@ class config_t std::set local_prefixes; ///< for fallback to default std::map peers; std::map interfaces; + std::vector bird_imports; }; } diff --git a/controlplane/configparser.cpp b/controlplane/configparser.cpp index af331d5e..a21d25ea 100644 --- a/controlplane/configparser.cpp +++ b/controlplane/configparser.cpp @@ -197,6 +197,32 @@ controlplane::base_t config_parser_t::loadConfig(const std::string& rootFilePath return baseNext; } +void config_parser_t::loadConfig_route_bird(controlplane::base_t& baseNext, + std::vector& birdsImport, + const nlohmann::json& birdJson) +{ + using BirdImport = controlplane::route::bird_import_t; + for (const auto& elemJson : birdJson) + { + BirdImport import; + + if (exist(elemJson, BirdImport::socketStr)) + { + import.socket = elemJson[BirdImport::socketStr]; + } + + if (exist(elemJson, BirdImport::vrfStr)) + { + import.vrf = elemJson[BirdImport::vrfStr]; + } + + birdsImport.push_back(import); + YANET_LOG_INFO("loadConfig_route_bird: socket(%s), vrf(%s)\n", + import.socket.data(), + import.vrf.data()); + } +} + void config_parser_t::loadConfig_logicalPort(controlplane::base_t& baseNext, const std::string& moduleId, const nlohmann::json& moduleJson) @@ -367,6 +393,13 @@ void config_parser_t::loadConfig_route(controlplane::base_t& baseNext, route.tunnel_enabled = false; } + if (exist(moduleJson, "birdImport")) + { + loadConfig_route_bird(baseNext, + route.bird_imports, + moduleJson["birdImport"]); + } + // route.routeId = routeId; diff --git a/controlplane/configparser.h b/controlplane/configparser.h index ad8af05f..65284ff9 100644 --- a/controlplane/configparser.h +++ b/controlplane/configparser.h @@ -20,6 +20,7 @@ class config_parser_t void loadConfig_logicalPort(controlplane::base_t& baseNext, const std::string& moduleId, const nlohmann::json& moduleJson); void loadConfig_route(controlplane::base_t& baseNext, const std::string& moduleId, const nlohmann::json& moduleJson, const std::string& rootFilePath, const std::map& jsons); void loadConfig_route_peers(controlplane::base_t& baseNext, controlplane::route::config_t& route, const nlohmann::json& json, const std::string& rootFilePath, const std::map& jsons); + void loadConfig_route_bird(controlplane::base_t& baseNext, std::vector& birdsImport, const nlohmann::json& birdJson); void loadConfig_decap(controlplane::base_t& baseNext, const std::string& moduleId, const nlohmann::json& moduleJson); void loadConfig_nat64stateful(controlplane::base_t& baseNext, const std::string& moduleId, const nlohmann::json& moduleJson, const std::string& rootFilePath, const std::map& jsons); void loadConfig_nat64stateless(controlplane::base_t& baseNext, const std::string& moduleId, const nlohmann::json& moduleJson, const std::string& rootFilePath, const std::map& jsons); diff --git a/controlplane/controlplane.cpp b/controlplane/controlplane.cpp index d8919c29..ad22d461 100644 --- a/controlplane/controlplane.cpp +++ b/controlplane/controlplane.cpp @@ -526,6 +526,18 @@ common::icp::controlplane_values::response cControlPlane::controlplane_values() return response; } +common::icp::route_config::response cControlPlane::getRoute() const +{ + common::icp::route_config::response response; + + { + auto current_guard = generations.current_lock_guard(); + response = generations.current().routes; + } + + return response; +} + common::icp::getDecapPrefixes::response cControlPlane::command_getDecapPrefixes() { common::icp::getDecapPrefixes::response response; @@ -924,6 +936,12 @@ eResult cControlPlane::loadConfig(const std::string& rootFilePath, } YANET_LOG_INFO("dataplane has been updated (stage 7)\n"); + for(auto& module : modules) { + if (rib_t* rib = dynamic_cast(module)) { + rib->bird_import_get(); + rib->moduleStart(); + } + } } catch (const error_result_t& error) { diff --git a/controlplane/controlplane.h b/controlplane/controlplane.h index 8d038a22..89d3c593 100644 --- a/controlplane/controlplane.h +++ b/controlplane/controlplane.h @@ -111,6 +111,7 @@ class cControlPlane common::icp::acl_unwind::response acl_unwind(const common::icp::acl_unwind::request& request) const; common::icp::acl_lookup::response acl_lookup(const common::icp::acl_lookup::request& request) const; common::icp::controlplane_values::response controlplane_values() const; + common::icp::route_config::response getRoute() const; common::icp::getDecapPrefixes::response command_getDecapPrefixes(); common::icp::getNat64statelessTranslations::response command_getNat64statelessTranslations(); diff --git a/controlplane/rib.cpp b/controlplane/rib.cpp index 4d531545..a5379f3b 100644 --- a/controlplane/rib.cpp +++ b/controlplane/rib.cpp @@ -1,6 +1,6 @@ #include "rib.h" -#include "libbird.h" #include "controlplane.h" +#include "libbird.h" #include @@ -72,10 +72,6 @@ eResult rib_t::init() rib_thread(); }); - funcThreads.emplace_back([this]() { - bird_thread(); - }); - return eResult::success; } @@ -586,14 +582,14 @@ void rib_t::rib_flush(bool force_flush) controlPlane->route.prefix_update(vrf_priority, updated_prefix, proto_peer_table_name, destination); controlPlane->route.tunnel_prefix_update(vrf_priority, updated_prefix, destination); - //controlPlane->route.linux_prefix_update(vrf_priority, updated_prefix, destination); + // controlPlane->route.linux_prefix_update(vrf_priority, updated_prefix, destination); controlPlane->dregress.prefix_insert(vrf_priority, updated_prefix, destination); } else { controlPlane->route.prefix_update(vrf_priority, updated_prefix, {}, std::monostate()); // TODO: get rid of third parameter controlPlane->route.tunnel_prefix_update(vrf_priority, updated_prefix, std::monostate()); - //controlPlane->route.linux_prefix_update(vrf_priority, updated_prefix, std::monostate()); + // controlPlane->route.linux_prefix_update(vrf_priority, updated_prefix, std::monostate()); controlPlane->dregress.prefix_remove(vrf_priority, updated_prefix); } } @@ -880,22 +876,41 @@ void rib_t::rib_thread() std::this_thread::sleep_for(std::chrono::milliseconds{200}); } +} +void rib_t::bird_import_get() +{ + auto route = controlPlane->getRoute(); + for (auto& [vrf, response] : route) + { + (void)vrf; + auto imports = response.bird_imports; + + for (auto& import : imports) + { + funcThreads.emplace_back([this, import]() { + bird_thread(import.socket, import.vrf); + }); + } + } } -void rib_t::bird_thread() +void rib_t::bird_thread(const std::string& socket, const std::string& vrf) { - while (!flagStop) { - read_bird_feed("/tmp/export.sock", "default", this); + YANET_LOG_DEBUG("Run bird thread: socket(%s), vrf(%s)\n", + socket.data(), + vrf.data()); + while (!flagStop) + { + read_bird_feed(socket.c_str(), vrf.c_str(), this); common::icp::rib_update::clear request = {"bgp", std::nullopt}; -/* std::get<1>(request) = {peer_address, - {"default", ///< @todo: vrf - YANET_RIB_PRIORITY_DEFAULT}}; -*/ + /* std::get<1>(request) = {peer_address, + {"default", ///< @todo: vrf + YANET_RIB_PRIORITY_DEFAULT}}; + */ rib_clear(request); std::this_thread::sleep_for(std::chrono::milliseconds{200}); } - } diff --git a/controlplane/rib.h b/controlplane/rib.h index a6f9d977..06f75332 100644 --- a/controlplane/rib.h +++ b/controlplane/rib.h @@ -50,6 +50,8 @@ class rib_t : public cModule common::icp::rib_summary::response rib_summary(); common::icp::rib_prefixes::response rib_prefixes(); + void bird_import_get(); + common::icp::rib_lookup::response rib_lookup(const common::icp::rib_lookup::request& request); common::icp::rib_get::response rib_get(const common::icp::rib_get::request& request); common::icp::rib_save::response rib_save(); @@ -62,7 +64,7 @@ class rib_t : public cModule void rib_eor(const common::icp::rib_update::eor& request); void rib_thread(); - void bird_thread(); + void bird_thread(const std::string& socket, const std::string& vrf); protected: mutable std::mutex rib_update_mutex; From c5aaf0a0014e9eaac9a94021d5322032e25100d6 Mon Sep 17 00:00:00 2001 From: Markuu-s Date: Sat, 28 Dec 2024 17:58:41 +0300 Subject: [PATCH 09/11] clang-format controlplane.cpp --- controlplane/controlplane.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/controlplane/controlplane.cpp b/controlplane/controlplane.cpp index ad22d461..b461c089 100644 --- a/controlplane/controlplane.cpp +++ b/controlplane/controlplane.cpp @@ -936,8 +936,10 @@ eResult cControlPlane::loadConfig(const std::string& rootFilePath, } YANET_LOG_INFO("dataplane has been updated (stage 7)\n"); - for(auto& module : modules) { - if (rib_t* rib = dynamic_cast(module)) { + for (auto& module : modules) + { + if (rib_t* rib = dynamic_cast(module)) + { rib->bird_import_get(); rib->moduleStart(); } From a9e7fdec05b4e399fe6c96b6e11cbfa83d25b57b Mon Sep 17 00:00:00 2001 From: Markuu-s Date: Sat, 28 Dec 2024 21:34:33 +0300 Subject: [PATCH 10/11] Fix includes. --- controlplane/libbird.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/controlplane/libbird.cpp b/controlplane/libbird.cpp index 79939bb0..3cd478b4 100644 --- a/controlplane/libbird.cpp +++ b/controlplane/libbird.cpp @@ -1,5 +1,8 @@ #include "libbird.h" +#include +#include +#include #include #include "common/type.h" #include "common/icp.h" From 2d82f7ea7a20b98fd0e6713ea801cbccc30dc014 Mon Sep 17 00:00:00 2001 From: Markuu-s Date: Fri, 24 Jan 2025 18:10:03 +0300 Subject: [PATCH 11/11] Fix PR. --- controlplane/configparser.cpp | 4 ++-- controlplane/rib.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/controlplane/configparser.cpp b/controlplane/configparser.cpp index b0352697..76839015 100644 --- a/controlplane/configparser.cpp +++ b/controlplane/configparser.cpp @@ -197,7 +197,7 @@ controlplane::base_t config_parser_t::loadConfig(const std::string& rootFilePath return baseNext; } -void config_parser_t::loadConfig_route_bird(controlplane::base_t& baseNext, +void config_parser_t::loadConfig_route_bird([[maybe_unused]]controlplane::base_t& baseNext, std::vector& birdsImport, const nlohmann::json& birdJson) { @@ -216,10 +216,10 @@ void config_parser_t::loadConfig_route_bird(controlplane::base_t& baseNext, import.vrf = elemJson[BirdImport::vrfStr]; } - birdsImport.push_back(import); YANET_LOG_INFO("loadConfig_route_bird: socket(%s), vrf(%s)\n", import.socket.data(), import.vrf.data()); + birdsImport.push_back(std::move(import)); } } diff --git a/controlplane/rib.cpp b/controlplane/rib.cpp index 53576cc7..16d0f0cf 100644 --- a/controlplane/rib.cpp +++ b/controlplane/rib.cpp @@ -872,7 +872,7 @@ void rib_t::bird_import_get() auto route = controlPlane->getRoute(); for (auto& [vrf, response] : route) { - (void)vrf; + YANET_GCC_BUG_UNUSED(vrf); auto imports = response.bird_imports; for (auto& import : imports)