1
0
Fork 0
mirror of https://github.com/pavel-odintsov/fastnetmon synced 2024-06-01 22:16:27 +02:00

Added GoBGP integration based on new GoBGP API.

This commit is contained in:
Pavel Odintsov 2022-02-09 14:27:32 +00:00
parent 3c828c400f
commit 3a7daa54ac
5 changed files with 740 additions and 127 deletions

View File

@ -329,21 +329,25 @@ if (ENABLE_GOBGP_SUPPORT)
set(GRPC_CPP_PLUGIN "${GRPC_CUSTOM_INSTALL_PATH}/bin/grpc_cpp_plugin")
execute_process(COMMAND ${PROTOC_BINARY} -I ${PROJECT_BINARY_DIR}/../actions --grpc_out=${PROJECT_BINARY_DIR}/../actions --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${PROJECT_BINARY_DIR}/../actions/gobgp_api_client.proto ERROR_VARIABLE PROTOC_STDERR RESULT_VARIABLE PROTOC_RETURN_CODE OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${PROTOC_BINARY} -I ${PROJECT_BINARY_DIR}/../actions --grpc_out=${PROJECT_BINARY_DIR}/../actions --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${PROJECT_BINARY_DIR}/../actions/gobgp.proto ERROR_VARIABLE PROTOC_STDERR RESULT_VARIABLE PROTOC_RETURN_CODE OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Protoc return code: ${PROTOC_RETURN_CODE} std err: ${PROTOC_STDERR}")
execute_process(COMMAND ${PROTOC_BINARY} -I ${PROJECT_BINARY_DIR}/../actions --cpp_out=${PROJECT_BINARY_DIR}/../actions ${PROJECT_BINARY_DIR}/../actions/gobgp_api_client.proto ERROR_VARIABLE PROTOC_STDERR RESULT_VARIABLE PROTOC_RETURN_CODE OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${PROTOC_BINARY} -I ${PROJECT_BINARY_DIR}/../actions --cpp_out=${PROJECT_BINARY_DIR}/../actions ${PROJECT_BINARY_DIR}/../actions/gobgp.proto ${PROJECT_BINARY_DIR}/../actions/attribute.proto ERROR_VARIABLE PROTOC_STDERR RESULT_VARIABLE PROTOC_RETURN_CODE OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Protoc return code: ${PROTOC_RETURN_CODE} std err: ${PROTOC_STDERR}")
# Build gRPC and protocol bufffers libraries and link they to gobgp_action
add_library(gobgp_api_client_pb_cc STATIC actions/gobgp_api_client.pb.cc)
add_library(gobgp_api_client_grpc_pb_cc STATIC actions/gobgp_api_client.grpc.pb.cc)
add_library(gobgp_api_client_pb_cc STATIC actions/gobgp.pb.cc)
add_library(gobgp_api_client_grpc_pb_cc STATIC actions/gobgp.grpc.pb.cc)
target_link_libraries(gobgp_action gobgp_api_client_pb_cc)
target_link_libraries(gobgp_action gobgp_api_client_grpc_pb_cc)
# Add attributes
add_library(attribute_pb_cc STATIC actions/attribute.pb.cc)
target_link_libraries(gobgp_action attribute_pb_cc)
# FastNetMon API
add_definitions(-DFASTNETMON_API)

658
src/actions/attribute.proto Normal file
View File

@ -0,0 +1,658 @@
// Copyright (C) 2018 Nippon Telegraph and Telephone Corporation.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
syntax = "proto3";
import "google/protobuf/any.proto";
import "gobgp.proto";
package gobgpapi;
message OriginAttribute {
uint32 origin = 1;
}
message AsSegment {
uint32 type = 1;
repeated uint32 numbers = 2;
}
message AsPathAttribute {
repeated AsSegment segments = 1;
}
message NextHopAttribute {
string next_hop = 1;
}
message MultiExitDiscAttribute {
uint32 med = 1;
}
message LocalPrefAttribute {
uint32 local_pref = 1;
}
message AtomicAggregateAttribute {
}
message AggregatorAttribute {
uint32 as = 2;
string address = 3;
}
message CommunitiesAttribute {
repeated uint32 communities = 1;
}
message OriginatorIdAttribute {
string id = 1;
}
message ClusterListAttribute {
repeated string ids = 1;
}
// IPAddressPrefix represents the NLRI for:
// - AFI=1, SAFI=1
// - AFI=2, SAFI=1
message IPAddressPrefix {
uint32 prefix_len = 1;
string prefix = 2;
}
// LabeledIPAddressPrefix represents the NLRI for:
// - AFI=1, SAFI=4
// - AFI=2, SAFI=4
message LabeledIPAddressPrefix {
repeated uint32 labels = 1;
uint32 prefix_len = 2;
string prefix = 3;
}
// EncapsulationNLRI represents the NLRI for:
// - AFI=1, SAFI=7
// - AFI=2, SAFI=7
message EncapsulationNLRI {
string address = 1;
}
message RouteDistinguisherTwoOctetAS {
uint32 admin = 1;
uint32 assigned = 2;
}
message RouteDistinguisherIPAddress {
string admin = 1;
uint32 assigned = 2;
}
message RouteDistinguisherFourOctetAS {
uint32 admin = 1;
uint32 assigned = 2;
}
message EthernetSegmentIdentifier {
uint32 type = 1;
bytes value = 2;
}
// EVPNEthernetAutoDiscoveryRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=1
message EVPNEthernetAutoDiscoveryRoute {
// One of:
// - RouteDistinguisherTwoOctetAS
// - RouteDistinguisherIPAddressAS
// - RouteDistinguisherFourOctetAS
google.protobuf.Any rd = 1;
EthernetSegmentIdentifier esi = 2;
uint32 ethernet_tag = 3;
uint32 label = 4;
}
// EVPNMACIPAdvertisementRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=2
message EVPNMACIPAdvertisementRoute {
// One of:
// - RouteDistinguisherTwoOctetAS
// - RouteDistinguisherIPAddressAS
// - RouteDistinguisherFourOctetAS
google.protobuf.Any rd = 1;
EthernetSegmentIdentifier esi = 2;
uint32 ethernet_tag = 3;
string mac_address = 4;
string ip_address = 5;
repeated uint32 labels = 6;
}
// EVPNInclusiveMulticastEthernetTagRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=3
message EVPNInclusiveMulticastEthernetTagRoute {
// One of:
// - RouteDistinguisherTwoOctetAS
// - RouteDistinguisherIPAddressAS
// - RouteDistinguisherFourOctetAS
google.protobuf.Any rd = 1;
uint32 ethernet_tag = 2;
string ip_address = 3;
}
// EVPNEthernetSegmentRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=4
message EVPNEthernetSegmentRoute {
// One of:
// - RouteDistinguisherTwoOctetAS
// - RouteDistinguisherIPAddressAS
// - RouteDistinguisherFourOctetAS
google.protobuf.Any rd = 1;
EthernetSegmentIdentifier esi = 2;
string ip_address = 3;
}
// EVPNIPPrefixRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=5
message EVPNIPPrefixRoute {
// One of:
// - RouteDistinguisherTwoOctetAS
// - RouteDistinguisherIPAddressAS
// - RouteDistinguisherFourOctetAS
google.protobuf.Any rd = 1;
EthernetSegmentIdentifier esi = 2;
uint32 ethernet_tag = 3;
string ip_prefix = 4;
uint32 ip_prefix_len = 5;
string gw_address = 6;
uint32 label = 7;
}
// EVPNIPMSIRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=9
message EVPNIPMSIRoute {
// One of:
// - RouteDistinguisherTwoOctetAS
// - RouteDistinguisherIPAddressAS
// - RouteDistinguisherFourOctetAS
google.protobuf.Any rd = 1;
uint32 ethernet_tag = 2;
google.protobuf.Any rt = 3;
}
// LabeledVPNIPAddressPrefix represents the NLRI for:
// - AFI=1, SAFI=128
// - AFI=2, SAFI=128
message LabeledVPNIPAddressPrefix {
repeated uint32 labels = 1;
// One of:
// - TwoOctetAsSpecificExtended
// - IPv4AddressSpecificExtended
// - FourOctetAsSpecificExtended
google.protobuf.Any rd = 2;
uint32 prefix_len = 3;
string prefix = 4;
}
// RouteTargetMembershipNLRI represents the NLRI for:
// - AFI=1, SAFI=132
message RouteTargetMembershipNLRI {
uint32 as = 1;
// One of:
// - TwoOctetAsSpecificExtended
// - IPv4AddressSpecificExtended
// - FourOctetAsSpecificExtended
google.protobuf.Any rt = 2;
}
message FlowSpecIPPrefix {
uint32 type = 1;
uint32 prefix_len = 2;
string prefix = 3;
// IPv6 only
uint32 offset = 4;
}
message FlowSpecMAC {
uint32 type = 1;
string address = 2;
}
message FlowSpecComponentItem {
// Operator for Numeric type, Operand for Bitmask type
uint32 op = 1;
uint64 value = 2;
}
message FlowSpecComponent {
uint32 type = 1;
repeated FlowSpecComponentItem items = 2;
}
// FlowSpecNLRI represents the NLRI for:
// - AFI=1, SAFI=133
// - AFI=2, SAFI=133
message FlowSpecNLRI {
// One of:
// - FlowSpecIPPrefix
// - FlowSpecMAC
// - FlowSpecComponent
repeated google.protobuf.Any rules = 1;
}
// VPNFlowSpecNLRI represents the NLRI for:
// - AFI=1, SAFI=134
// - AFI=2, SAFI=134
// - AFI=25, SAFI=134
message VPNFlowSpecNLRI {
// One of:
// - RouteDistinguisherTwoOctetAS
// - RouteDistinguisherIPAddressAS
// - RouteDistinguisherFourOctetAS
google.protobuf.Any rd = 1;
// One of:
// - FlowSpecIPPrefix
// - FlowSpecMAC
// - FlowSpecComponent
repeated google.protobuf.Any rules = 2;
}
// OpaqueNLRI represents the NLRI for:
// - AFI=16397, SAFI=241
message OpaqueNLRI {
bytes key = 1;
bytes value = 2;
}
message LsNodeDescriptor {
uint32 asn = 1;
uint32 bgp_ls_id = 2;
uint32 ospf_area_id = 3;
bool pseudonode = 4;
string igp_router_id = 5;
}
message LsLinkDescriptor {
uint32 link_local_id = 1;
uint32 link_remote_id = 2;
string interface_addr_ipv4 = 3;
string neighbor_addr_ipv4 = 4;
string interface_addr_ipv6 = 5;
string neighbor_addr_ipv6 = 6;
}
message LsPrefixDescriptor {
repeated string ip_reachability = 1;
string ospf_route_type = 2;
}
message LsNodeNLRI {
LsNodeDescriptor local_node = 1;
}
message LsLinkNLRI {
LsNodeDescriptor local_node = 1;
LsNodeDescriptor remote_node = 2;
LsLinkDescriptor link_descriptor = 3;
}
message LsPrefixV4NLRI {
LsNodeDescriptor local_node = 1;
LsPrefixDescriptor prefix_descriptor = 2;
}
message LsPrefixV6NLRI {
LsNodeDescriptor local_node = 1;
LsPrefixDescriptor prefix_descriptor = 2;
}
// Based om RFC 7752, Table 1.
enum LsNLRIType {
LS_NLRI_UNKNOWN = 0;
LS_NLRI_NODE = 1;
LS_NLRI_LINK = 2;
LS_NLRI_PREFIX_V4 = 3;
LS_NLRI_PREFIX_V6 = 4;
}
// LsAddrPrefix represents the NLRI for:
// - AFI=16388, SAFI=71
message LsAddrPrefix {
LsNLRIType type = 1;
// One of:
// - LsNodeNLRI
// - LsLinkNLRI
// - LsPrefixV4NLRI
// - LsPrefixV6NLRI
google.protobuf.Any nlri = 2;
}
message MpReachNLRIAttribute {
gobgpapi.Family family = 1;
repeated string next_hops = 2;
// Each NLRI must be one of:
// - IPAddressPrefix
// - LabeledIPAddressPrefix
// - EncapsulationNLRI
// - EVPNEthernetAutoDiscoveryRoute
// - EVPNMACIPAdvertisementRoute
// - EVPNInclusiveMulticastEthernetTagRoute
// - EVPNEthernetSegmentRoute
// - EVPNIPPrefixRoute
// - EVPNIPMSIRoute
// - LabeledVPNIPAddressPrefix
// - RouteTargetMembershipNLRI
// - FlowSpecNLRI
// - VPNFlowSpecNLRI
// - OpaqueNLRI
// - LsAddrPrefix
repeated google.protobuf.Any nlris = 3;
}
message MpUnreachNLRIAttribute {
gobgpapi.Family family = 1;
// The same as NLRI field of MpReachNLRIAttribute
repeated google.protobuf.Any nlris = 3;
}
message TwoOctetAsSpecificExtended {
bool is_transitive = 1;
uint32 sub_type = 2;
uint32 as = 3;
uint32 local_admin = 4;
}
message IPv4AddressSpecificExtended {
bool is_transitive = 1;
uint32 sub_type = 2;
string address = 3;
uint32 local_admin = 4;
}
message FourOctetAsSpecificExtended {
bool is_transitive = 1;
uint32 sub_type = 2;
uint32 as = 3;
uint32 local_admin = 4;
}
message ValidationExtended {
uint32 state = 1;
}
message ColorExtended {
uint32 color = 1;
}
message EncapExtended {
uint32 tunnel_type = 1;
}
message DefaultGatewayExtended {
}
message OpaqueExtended {
bool is_transitive = 1;
bytes value = 3;
}
message ESILabelExtended {
bool is_single_active = 1;
uint32 label = 2;
}
message ESImportRouteTarget {
string es_import = 1;
}
message MacMobilityExtended {
bool is_sticky = 1;
uint32 sequence_num = 2;
}
message RouterMacExtended {
string mac = 1;
}
message TrafficRateExtended {
uint32 as = 1;
float rate = 2;
}
message TrafficActionExtended {
bool terminal = 1;
bool sample = 2;
}
message RedirectTwoOctetAsSpecificExtended {
uint32 as = 1;
uint32 local_admin = 2;
}
message RedirectIPv4AddressSpecificExtended {
string address = 1;
uint32 local_admin = 2;
}
message RedirectFourOctetAsSpecificExtended {
uint32 as = 1;
uint32 local_admin = 2;
}
message TrafficRemarkExtended {
uint32 dscp = 1;
}
message UnknownExtended {
uint32 type = 1;
bytes value = 2;
}
message ExtendedCommunitiesAttribute {
// Each Community must be one of:
// - TwoOctetAsSpecificExtended
// - IPv4AddressSpecificExtended
// - FourOctetAsSpecificExtended
// - OpaqueExtended
// - ESILabelExtended
// - MacMobilityExtended
// - RouterMacExtended
// - TrafficRateExtended
// - TrafficActionExtended
// - RedirectTwoOctetAsSpecificExtended
// - RedirectIPv4AddressSpecificExtended
// - RedirectFourOctetAsSpecificExtended
// - TrafficRemarkExtended
// - UnknownExtended
repeated google.protobuf.Any communities = 1;
}
message As4PathAttribute {
repeated AsSegment segments = 1;
}
message As4AggregatorAttribute {
uint32 as = 2;
string address = 3;
}
message PmsiTunnelAttribute {
uint32 flags = 1;
uint32 type = 2;
uint32 label = 3;
bytes id = 4;
}
message TunnelEncapSubTLVEncapsulation {
uint32 key = 1;
bytes cookie = 2;
}
message TunnelEncapSubTLVProtocol {
uint32 protocol = 1;
}
message TunnelEncapSubTLVColor {
uint32 color = 1;
}
message TunnelEncapSubTLVUnknown {
uint32 type = 1;
bytes value = 2;
}
message TunnelEncapTLV {
uint32 type = 1;
// Each TLV must be one of:
// - TunnelEncapSubTLVEncapsulation
// - TunnelEncapSubTLVProtocol
// - TunnelEncapSubTLVColor
// - TunnelEncapSubTLVUnknown
repeated google.protobuf.Any tlvs = 2;
}
message TunnelEncapAttribute {
repeated TunnelEncapTLV tlvs = 1;
}
message IPv6AddressSpecificExtended {
bool is_transitive = 1;
uint32 sub_type = 2;
string address = 3;
uint32 local_admin = 4;
}
message RedirectIPv6AddressSpecificExtended {
string address = 1;
uint32 local_admin = 2;
}
message IP6ExtendedCommunitiesAttribute {
// Each Community must be one of:
// - IPv6AddressSpecificExtended
// - RedirectIPv6AddressSpecificExtended
repeated google.protobuf.Any communities = 1;
}
message AigpTLVIGPMetric {
uint64 metric = 1;
}
message AigpTLVUnknown {
uint32 type = 1;
bytes value = 2;
}
message AigpAttribute {
// Each TLV must be one of:
// - AigpTLVIGPMetric
// - AigpTLVUnknown
repeated google.protobuf.Any tlvs = 1;
}
message LargeCommunity {
uint32 global_admin = 1;
uint32 local_data1 = 2;
uint32 local_data2 = 3;
}
message LargeCommunitiesAttribute {
repeated LargeCommunity communities = 1;
}
message LsNodeFlags {
bool overload = 1;
bool attached = 2;
bool external = 3;
bool abr = 4;
bool router = 5;
bool v6 = 6;
}
message LsIGPFlags {
bool down = 1;
bool no_unicast = 2;
bool local_address = 3;
bool propagate_nssa = 4;
}
message LsSrRange {
uint32 begin = 1;
uint32 end = 2;
}
message LsSrCapabilities {
bool ipv4_supported = 1;
bool ipv6_supported = 2;
repeated LsSrRange ranges = 3;
}
message LsSrLocalBlock {
repeated LsSrRange ranges = 1;
}
message LsAttributeNode {
string name = 1;
LsNodeFlags flags = 2;
string local_router_id = 3;
string local_router_id_v6 = 4;
bytes isis_area = 5;
bytes opaque = 6;
LsSrCapabilities sr_capabilities = 7;
bytes sr_algorithms = 8;
LsSrLocalBlock sr_local_block = 9;
}
message LsAttributeLink {
string name = 1;
string local_router_id = 2;
string local_router_id_v6 = 3;
string remote_router_id = 4;
string remote_router_id_v6 = 5;
uint32 admin_group = 6;
uint32 default_te_metric = 7;
uint32 igp_metric = 8;
bytes opaque = 9;
float bandwidth = 10;
float reservable_bandwidth = 11;
repeated float unreserved_bandwidth = 12;
uint32 sr_adjacency_sid = 13;
repeated uint32 srlgs = 14;
}
message LsAttributePrefix {
LsIGPFlags igp_flags = 1;
bytes opaque = 2;
uint32 sr_prefix_sid = 3;
}
message LsAttribute {
LsAttributeNode node = 1;
LsAttributeLink link = 2;
LsAttributePrefix prefix = 3;
}
message UnknownAttribute {
uint32 flags = 1;
uint32 type = 2;
bytes value = 3;
}

View File

@ -2,20 +2,16 @@
#include "../fastnetmon_actions.h"
#include "../fastnetmon_types.h"
#include <dlfcn.h>
extern "C" {
// Gobgp library
#include "libgobgp.h"
}
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/security/credentials.h>
#include <grpc/grpc.h>
#include "gobgp_api_client.grpc.pb.h"
#include "gobgp.grpc.pb.h"
#include "attribute.pb.h"
unsigned int gobgp_client_connection_timeout = 5;
using grpc::Channel;
using grpc::ClientContext;
@ -23,18 +19,12 @@ using grpc::Status;
using gobgpapi::GobgpApi;
// Create function pointers
typedef path* (*serialize_path_dynamic_t)(int p0, char* p1);
typedef char* (*decode_path_dynamic_t)(path* p0);
serialize_path_dynamic_t serialize_path_dynamic = NULL;
decode_path_dynamic_t decode_path_dynamic = NULL;
class GrpcClient {
public:
GrpcClient(std::shared_ptr<Channel> channel) : stub_(GobgpApi::NewStub(channel)) {
}
void GetAllActiveAnnounces(unsigned int route_family) {
/*
ClientContext context;
gobgpapi::Table table;
@ -92,9 +82,11 @@ class GrpcClient {
logger << log4cpp::Priority::INFO << "NLRI: " << decode_path_dynamic(&gobgp_lib_path);
// std::cout << "NLRI: " << decode_path(&gobgp_lib_path) << std::endl;
}
*/
}
void AnnounceFlowSpecPrefix(bool withdraw) {
/*
const gobgpapi::ModPathArguments current_mod_path_arguments;
unsigned int AFI_IP = 1;
@ -103,6 +95,7 @@ class GrpcClient {
gobgpapi::Path* current_path = new gobgpapi::Path;
current_path->set_is_withdraw(withdraw);
*/
/*
buf:
@ -116,6 +109,7 @@ class GrpcClient {
int path_attributes_cap;
*/
/*
path* path_c_struct =
serialize_path_dynamic(ipv4_flow_spec_route_family,
(char*)"match destination 10.0.0.0/24 protocol tcp source "
@ -165,93 +159,82 @@ class GrpcClient {
// std::cout << "modpath failed with code: " << status.error_code()
// << " message " << status.error_message() << std::endl;
}
*/
}
void AnnounceUnicastPrefix(std::string announced_prefix, std::string announced_prefix_nexthop, bool is_withdrawal) {
const gobgpapi::ModPathArguments current_mod_path_arguments;
bool AnnounceUnicastPrefix(std::string announced_address, std::string announced_prefix_nexthop, bool is_withdrawal, unsigned int cidr_mask) {
grpc::ClientContext context;
unsigned int AFI_IP = 1;
unsigned int SAFI_UNICAST = 1;
unsigned int ipv4_unicast_route_family = AFI_IP << 16 | SAFI_UNICAST;
// 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);
gobgpapi::Path* current_path = new gobgpapi::Path;
// current_path->set_is_withdraw(withdraw);
if (is_withdrawal) {
auto gobgp_ipv4_unicast_route_family = new gobgpapi::Family;
gobgp_ipv4_unicast_route_family->set_afi(gobgpapi::Family::AFI_IP);
gobgp_ipv4_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_ipv4_unicast_route_family);
if (is_withdrawal) {
current_path->set_is_withdraw(true);
}
}
/*
buf:
char *value;
int len;
// Configure required announce
google::protobuf::Any *current_nlri = new google::protobuf::Any;
gobgpapi::IPAddressPrefix current_ipaddrprefix;
current_ipaddrprefix.set_prefix(announced_address);
current_ipaddrprefix.set_prefix_len(cidr_mask);
path:
buf nlri;
buf** path_attributes;
int path_attributes_len;
int path_attributes_cap;
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(announced_prefix_nexthop);
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(100);
current_communities->PackFrom(current_communities_t);
*/
std::string announce_line = announced_prefix + " nexthop " + announced_prefix_nexthop;
request.set_allocated_path(current_path);
// 10.10.20.33/22 nexthop 10.10.1.99/32
path* path_c_struct =
serialize_path_dynamic(ipv4_unicast_route_family, (char*)announce_line.c_str());
gobgpapi::AddPathResponse response;
if (path_c_struct == NULL) {
logger << log4cpp::Priority::ERROR << "Could not generate path\n";
return;
// 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;
}
// printf("Decoded NLRI output: %s, length %d raw string length: %d\n", decode_path(path_c_struct), path_c_struct->nlri.len, strlen(path_c_struct->nlri.value));
for (int path_attribute_number = 0;
path_attribute_number < path_c_struct->path_attributes_len; path_attribute_number++) {
current_path->add_pattrs(path_c_struct->path_attributes[path_attribute_number]->value,
path_c_struct->path_attributes[path_attribute_number]->len);
}
current_path->set_nlri(path_c_struct->nlri.value, path_c_struct->nlri.len);
gobgpapi::ModPathsArguments request;
request.set_resource(gobgpapi::Resource::GLOBAL);
google::protobuf::RepeatedPtrField< ::gobgpapi::Path>* current_path_list = request.mutable_paths();
current_path_list->AddAllocated(current_path);
request.set_name("");
ClientContext context;
gobgpapi::Error return_error;
// result is a std::unique_ptr<grpc::ClientWriter<api::ModPathArguments> >
auto send_stream = stub_->ModPaths(&context, &return_error);
bool write_result = send_stream->Write(request);
if (!write_result) {
// std::cout << "Write to API failed\n";
logger << log4cpp::Priority::ERROR << "Write to API failed\n";
return;
}
// Finish all writes
send_stream->WritesDone();
auto status = send_stream->Finish();
if (status.ok()) {
// std::cout << "modpath executed correctly" << std::cout;
} else {
// std::cout << "modpath failed with code: " << status.error_code()
// << " message " << status.error_message() << std::endl;
logger << log4cpp::Priority::ERROR << "modpath failed with code: " << status.error_code()
<< " message " << status.error_message();
return;
}
return true;
}
std::string GetNeighbor(std::string neighbor_ip) {
return "not implemented";
/*
gobgpapi::Arguments request;
request.set_family(4);
request.set_name(neighbor_ip);
@ -276,6 +259,7 @@ class GrpcClient {
} else {
return "Something wrong";
}
*/
}
private:
@ -289,8 +273,7 @@ bool gobgp_announce_host = false;
void gobgp_action_init() {
logger << log4cpp::Priority::INFO << "GoBGP action module loaded";
gobgp_client = new GrpcClient(grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()));
// GrpcClient gobgp_client(grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()));
gobgp_client = new GrpcClient(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
if (configuration_map.count("gobgp_next_hop")) {
gobgp_nexthop = configuration_map["gobgp_next_hop"];
@ -303,39 +286,6 @@ void gobgp_action_init() {
if (configuration_map.count("gobgp_announce_whole_subnet")) {
gobgp_announce_whole_subnet = configuration_map["gobgp_announce_whole_subnet"] == "on";
}
// According to this bug report: https://github.com/golang/go/issues/12873
// We have significant issues with popen, daemonization and Go's runtime
// We use non absoulte path here and linker will find it fir us
void* gobgdp_library_handle = dlopen("libgobgp.so", RTLD_NOW);
if (gobgdp_library_handle == NULL) {
logger << log4cpp::Priority::ERROR << "Could not load gobgp binary library: " << dlerror();
exit(1);
}
dlerror(); /* Clear any existing error */
/* According to the ISO C standard, casting between function
pointers and 'void *', as done above, produces undefined results.
POSIX.1-2003 and POSIX.1-2008 accepted this state of affairs and
proposed the following workaround:
*/
serialize_path_dynamic =
(serialize_path_dynamic_t)dlsym(gobgdp_library_handle, "serialize_path");
if (serialize_path_dynamic == NULL) {
logger << log4cpp::Priority::ERROR << "Could not load function serialize_path from the dynamic library";
exit(1);
}
decode_path_dynamic = (decode_path_dynamic_t)dlsym(gobgdp_library_handle, "decode_path");
if (decode_path_dynamic == NULL) {
logger << log4cpp::Priority::ERROR << "Could not load function decode_path from the dynamic library";
exit(1);
}
}
void gobgp_action_shutdown() {
@ -354,12 +304,13 @@ void gobgp_ban_manage(std::string action, std::string ip_as_string, attack_detai
if (gobgp_announce_whole_subnet) {
std::string subnet_as_string_with_mask = convert_subnet_to_string(current_attack.customer_network);
gobgp_client->AnnounceUnicastPrefix(subnet_as_string_with_mask, gobgp_nexthop, is_withdrawal);
logger << log4cpp::Priority::ERROR << "Per network GoBGP announces are not supported yet";
// gobgp_client->AnnounceUnicastPrefix(subnet_as_string_with_mask, gobgp_nexthop, is_withdrawal, );
}
if (gobgp_announce_host) {
std::string ip_as_string_with_mask = ip_as_string + "/32";
gobgp_client->AnnounceUnicastPrefix(ip_as_string_with_mask, gobgp_nexthop, is_withdrawal);
gobgp_client->AnnounceUnicastPrefix(ip_as_string, gobgp_nexthop, is_withdrawal, 32);
}
}

View File

@ -106,7 +106,7 @@ int main(int argc, char** argv) {
// are created. This channel models a connection to an endpoint (in this case,
// localhost at port 50051). We indicate that the channel isn't authenticated
// (use of InsecureCredentials()).
FastnetmonClient fastnetmon(grpc::CreateChannel("localhost:50052", grpc::InsecureCredentials()));
FastnetmonClient fastnetmon(grpc::CreateChannel("localhost:50052", grpc::InsecureChannelCredentials()));
std::string request_command = argv[1];