diff --git a/src/actions/gobgp_action.cpp b/src/actions/gobgp_action.cpp index da8ff425c..1674dc585 100644 --- a/src/actions/gobgp_action.cpp +++ b/src/actions/gobgp_action.cpp @@ -36,7 +36,7 @@ class GrpcClient { GrpcClient(std::shared_ptr channel) : stub_(GobgpApi::NewStub(channel)) { } - bool AnnounceUnicastPrefix(std::string announced_address, + bool AnnounceUnicastPrefixIPv4(std::string announced_address, std::string announced_prefix_nexthop, bool is_withdrawal, unsigned int cidr_mask, @@ -109,6 +109,79 @@ class GrpcClient { return true; } + bool AnnounceUnicastPrefixIPv6(const subnet_ipv6_cidr_mask_t& client_ipv6, + const subnet_ipv6_cidr_mask_t& ipv6_next_hop, + bool is_withdrawal, + uint32_t community_as_32bit_int) { + grpc::ClientContext context; + + // Set timeout for API + std::chrono::system_clock::time_point deadline = + std::chrono::system_clock::now() + std::chrono::seconds(gobgp_client_connection_timeout); + context.set_deadline(deadline); + + auto gobgp_ipv6_unicast_route_family = new gobgpapi::Family; + gobgp_ipv6_unicast_route_family->set_afi(gobgpapi::Family::AFI_IP6); + gobgp_ipv6_unicast_route_family->set_safi(gobgpapi::Family::SAFI_UNICAST); + + gobgpapi::AddPathRequest request; + request.set_table_type(gobgpapi::TableType::GLOBAL); + + gobgpapi::Path* current_path = new gobgpapi::Path; + + current_path->set_allocated_family(gobgp_ipv6_unicast_route_family); + + if (is_withdrawal) { + current_path->set_is_withdraw(true); + } + + // Configure required announce + google::protobuf::Any* current_nlri = new google::protobuf::Any; + gobgpapi::IPAddressPrefix current_ipaddrprefix; + current_ipaddrprefix.set_prefix(print_ipv6_address(client_ipv6.subnet_address)); + current_ipaddrprefix.set_prefix_len(client_ipv6.cidr_prefix_length); + + current_nlri->PackFrom(current_ipaddrprefix); + current_path->set_allocated_nlri(current_nlri); + + // Updating OriginAttribute info for current_path + google::protobuf::Any* current_origin = current_path->add_pattrs(); + gobgpapi::OriginAttribute current_origin_t; + current_origin_t.set_origin(0); + current_origin->PackFrom(current_origin_t); + + // Updating NextHopAttribute info for current_path + google::protobuf::Any* current_next_hop = current_path->add_pattrs(); + gobgpapi::NextHopAttribute current_next_hop_t; + current_next_hop_t.set_next_hop(print_ipv6_address(ipv6_next_hop.subnet_address)); + current_next_hop->PackFrom(current_next_hop_t); + + // Updating CommunitiesAttribute for current_path + google::protobuf::Any *current_communities = current_path->add_pattrs(); + gobgpapi::CommunitiesAttribute current_communities_t; + current_communities_t.add_communities(community_as_32bit_int); + current_communities->PackFrom(current_communities_t); + + request.set_allocated_path(current_path); + + gobgpapi::AddPathResponse response; + + // Don't be confused by name, it also can withdraw announces + auto status = stub_->AddPath(&context, request, &response); + + if (!status.ok()) { + logger << log4cpp::Priority::ERROR + << "AddPath request to BGP daemon failed with code: " << status.error_code() + << " message " << status.error_message(); + + return false; + } + + + return true; + } + + private: std::unique_ptr stub_; }; @@ -244,7 +317,10 @@ void gobgp_ban_manage(std::string action, bool ipv6, std::string ip_as_string, s } if (gobgp_announce_host_ipv6) { - logger << log4cpp::Priority::ERROR << "Sorry but we do not support IPv6 per host announces"; + logger << log4cpp::Priority::INFO << action_name << " " << print_ipv6_cidr_subnet(client_ipv6) << " to GoBGP"; + uint32_t community_as_32bit_int = uint32_t(bgp_community_host_ipv6.asn_number << 16 | bgp_community_host_ipv6.community_number); + + gobgp_client->AnnounceUnicastPrefixIPv6(client_ipv6, ipv6_next_hop, is_withdrawal, community_as_32bit_int); } } else { if (gobgp_announce_whole_subnet) { @@ -255,7 +331,7 @@ void gobgp_ban_manage(std::string action, bool ipv6, std::string ip_as_string, s // https://github.com/osrg/gobgp/blob/0aff30a74216f499b8abfabc50016b041b319749/internal/pkg/table/policy_test.go#L2870 uint32_t community_as_32bit_int = uint32_t(bgp_community_subnet.asn_number << 16 | bgp_community_subnet.community_number); - gobgp_client->AnnounceUnicastPrefix(convert_ip_as_uint_to_string( + gobgp_client->AnnounceUnicastPrefixIPv4(convert_ip_as_uint_to_string( current_attack.customer_network.subnet_address), gobgp_nexthop, is_withdrawal, current_attack.customer_network.cidr_prefix_length, community_as_32bit_int); @@ -268,7 +344,7 @@ void gobgp_ban_manage(std::string action, bool ipv6, std::string ip_as_string, s uint32_t community_as_32bit_int = uint32_t(bgp_community_host.asn_number << 16 | bgp_community_host.community_number); - gobgp_client->AnnounceUnicastPrefix(ip_as_string, gobgp_nexthop, is_withdrawal, 32, community_as_32bit_int); + gobgp_client->AnnounceUnicastPrefixIPv4(ip_as_string, gobgp_nexthop, is_withdrawal, 32, community_as_32bit_int); } } } diff --git a/src/fast_library.cpp b/src/fast_library.cpp index 041d61a34..30a167fce 100644 --- a/src/fast_library.cpp +++ b/src/fast_library.cpp @@ -727,11 +727,11 @@ std::string find_subnet_by_ip_in_string_format(patricia_tree_t* patricia_tree, s // It could not be on start or end of the line boost::regex ipv6_address_compression_algorithm("(0000:){2,}"); -std::string print_ipv6_address(struct in6_addr& ipv6_address) { +std::string print_ipv6_address(const in6_addr& ipv6_address) { char buffer[128]; // For short print - uint8_t* b = ipv6_address.s6_addr; + const uint8_t* b = ipv6_address.s6_addr; sprintf(buffer, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]); diff --git a/src/fast_library.h b/src/fast_library.h index 504322fc8..c9aab1d5d 100644 --- a/src/fast_library.h +++ b/src/fast_library.h @@ -49,7 +49,7 @@ std::vector exec(std::string cmd); uint32_t convert_ip_as_string_to_uint(std::string ip); std::string convert_ip_as_uint_to_string(uint32_t ip_as_integer); std::string convert_int_to_string(int value); -std::string print_ipv6_address(struct in6_addr& ipv6_address); +std::string print_ipv6_address(const struct in6_addr& ipv6_address); std::string print_simple_packet(simple_packet_t packet); std::string convert_timeval_to_date(struct timeval tv); bool convert_hex_as_string_to_uint(std::string hex, uint32_t& value); diff --git a/src/fastnetmon_build.pl b/src/fastnetmon_build.pl index 160863cff..c2587b9bd 100755 --- a/src/fastnetmon_build.pl +++ b/src/fastnetmon_build.pl @@ -694,7 +694,7 @@ sub install_grpc { sub install_gobgp { chdir $temp_folder_for_building_project; - my $gobgp_install_path = "$library_install_folder/gobgp_2_16_0"; + my $gobgp_install_path = "$library_install_folder/gobgp_2_17_0"; if (-e $gobgp_install_path) { print "GoBGP was already installed\n"; @@ -705,10 +705,10 @@ sub install_gobgp { my $distro_file_hash = ''; if ($distro_architecture eq 'x86_64') { - $distro_file_name = 'gobgp_2.16.0_linux_amd64.tar.gz'; - $distro_file_hash = '58dcf1f4b4b64383c5fbb731322c9fc2a2fcd5f0'; + $distro_file_name = 'gobgp_2.17.0_linux_amd64.tar.gz'; + $distro_file_hash = '3b12cf212eb7455be4ac2008fe7389666f1bc5ea'; } elsif ($distro_architecture eq 'i686') { - $distro_file_name = 'gobgp_2.16.0_linux_386.tar.gz'; + $distro_file_name = 'gobgp_2.17.0_linux_386.tar.gz'; $distro_file_hash = '9d6f031058589618f414b4493b5cfa34230c0505'; } else { fast_die("We do not have GoBGP for your platform, please check: https://github.com/osrg/gobgp/releases for available builds"); @@ -716,7 +716,7 @@ sub install_gobgp { print "Download GoBGP\n"; - my $gobgp_download_result = download_file("https://github.com/osrg/gobgp/releases/download/v2.16.0/$distro_file_name", + my $gobgp_download_result = download_file("https://github.com/osrg/gobgp/releases/download/v2.17.0/$distro_file_name", $distro_file_name, $distro_file_hash); unless ($gobgp_download_result) { diff --git a/src/scripts/build_libary_bundle.pl b/src/scripts/build_libary_bundle.pl index b43f70326..197650ac2 100755 --- a/src/scripts/build_libary_bundle.pl +++ b/src/scripts/build_libary_bundle.pl @@ -41,7 +41,7 @@ ndpi log4cpp1.1.1 pf_ring_6.0.3 -gobgp_2_16_0 +gobgp_2_17_0 grpc_1_30_2 libhiredis_0_13 mongo_c_driver_1_16_1