mirror of
https://github.com/osrg/gobgp.git
synced 2024-05-11 05:55:10 +00:00
grpc: Update and Modify C++ sample client
This patch updates C++ sample gRPC client for GoBGP v1.12 gRPC API. And this removes the route announcement feature from C++ sample client, for maintenance and uniformity. Signed-off-by: Satoshi Fujimoto <[email protected]>
This commit is contained in:
+13
-12
@@ -90,18 +90,19 @@ $ bash build.sh
|
||||
|
||||
### Let's run it:
|
||||
```bash
|
||||
LD_LIBRARY_PATH=".:/opt/grpc/lib:/opt/protobuf_3.0.0_alpha4/lib" ./gobgp_api_client
|
||||
|
||||
List of announced prefixes for route family: 65537
|
||||
|
||||
Prefix: 10.10.20.0/22
|
||||
NLRI: {"nlri":{"prefix":"10.10.20.0/22"},"attrs":[{"type":1,"value":0},{"type":3,"nexthop":"0.0.0.0"}]}
|
||||
|
||||
|
||||
List of announced prefixes for route family: 65669
|
||||
|
||||
Prefix: [destination:10.0.0.0/24][protocol: tcp][source:20.0.0.0/24]
|
||||
NLRI: {"nlri":{"value":[{"type":1,"value":{"prefix":"10.0.0.0/24"}},{"type":3,"value":[{"op":129,"value":6}]},{"type":2,"value":{"prefix":"20.0.0.0/24"}}]},"attrs":[{"type":1,"value":0},{"type":14,"nexthop":"0.0.0.0","afi":1,"safi":133,"value":[{"value":[{"type":1,"value":{"prefix":"10.0.0.0/24"}},{"type":3,"value":[{"op":129,"value":6}]},{"type":2,"value":{"prefix":"20.0.0.0/24"}}]}]},{"type":16,"value":[{"type":128,"subtype":8,"value":"10:10"}]}]}
|
||||
$ ./gobgp_api_client 172.18.0.2
|
||||
BGP neighbor is: 10.0.0.2, remote AS: 1
|
||||
BGP version: 4, remote route ID
|
||||
BGP state = active, up for 0
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0seconds
|
||||
Configured hold time is 90
|
||||
BGP neighbor is: 10.0.0.3, remote AS: 1
|
||||
BGP version: 4, remote route ID
|
||||
BGP state = active, up for 0
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0seconds
|
||||
Configured hold time is 90
|
||||
```
|
||||
|
||||
## <a name="nodejs"> Node.js
|
||||
|
||||
@@ -25,218 +25,44 @@ using gobgpapi::GobgpApi;
|
||||
class GrpcClient {
|
||||
public:
|
||||
GrpcClient(std::shared_ptr<Channel> channel) : stub_(GobgpApi::NewStub(channel)) {}
|
||||
void GetAllActiveAnnounces(unsigned int route_family) {
|
||||
ClientContext context;
|
||||
gobgpapi::Table table;
|
||||
|
||||
table.set_family(route_family);
|
||||
// We could specify certain neighbor here
|
||||
table.set_name("");
|
||||
table.set_type(gobgpapi::Resource::GLOBAL);
|
||||
|
||||
gobgpapi::Table response_table;
|
||||
|
||||
auto status = stub_->GetRib(&context, table, &response_table);
|
||||
|
||||
if (!status.ok()) {
|
||||
// error_message
|
||||
std::cout << "Problem with RPC: " << status.error_code() << " message " << status.error_message() << std::endl;
|
||||
return;
|
||||
} else {
|
||||
// std::cout << "RPC working well" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "List of announced prefixes for route family: " << route_family << std::endl << std::endl;
|
||||
|
||||
for (auto current_destination : response_table.destinations()) {
|
||||
std::cout << "Prefix: " << current_destination.prefix() << std::endl;
|
||||
|
||||
//std::cout << "Paths size: " << current_destination.paths_size() << std::endl;
|
||||
|
||||
gobgpapi::Path my_path = current_destination.paths(0);
|
||||
|
||||
// std::cout << "Pattrs size: " << my_path.pattrs_size() << std::endl;
|
||||
|
||||
buf my_nlri;
|
||||
my_nlri.value = (char*)my_path.nlri().c_str();
|
||||
my_nlri.len = my_path.nlri().size();
|
||||
|
||||
path_t gobgp_lib_path;
|
||||
gobgp_lib_path.nlri = my_nlri;
|
||||
// Not used in library code!
|
||||
gobgp_lib_path.path_attributes_cap = 0;
|
||||
gobgp_lib_path.path_attributes_len = my_path.pattrs_size();
|
||||
|
||||
buf* my_path_attributes[ my_path.pattrs_size() ];
|
||||
for (int i = 0; i < my_path.pattrs_size(); i++) {
|
||||
my_path_attributes[i] = (buf*)malloc(sizeof(buf));
|
||||
my_path_attributes[i]->len = my_path.pattrs(i).size();
|
||||
my_path_attributes[i]->value = (char*)my_path.pattrs(i).c_str();
|
||||
}
|
||||
|
||||
gobgp_lib_path.path_attributes = my_path_attributes;
|
||||
|
||||
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;
|
||||
unsigned int SAFI_FLOW_SPEC_UNICAST = 133;
|
||||
unsigned int ipv4_flow_spec_route_family = AFI_IP<<16 | SAFI_FLOW_SPEC_UNICAST;
|
||||
|
||||
gobgpapi::Path* current_path = new gobgpapi::Path;
|
||||
current_path->set_is_withdraw(withdraw);
|
||||
|
||||
/*
|
||||
buf:
|
||||
char *value;
|
||||
int len;
|
||||
|
||||
path:
|
||||
buf nlri;
|
||||
buf** path_attributes;
|
||||
int path_attributes_len;
|
||||
int path_attributes_cap;
|
||||
*/
|
||||
|
||||
path* path_c_struct = serialize_path(ipv4_flow_spec_route_family, (char*)"match destination 10.0.0.0/24 protocol tcp source 20.0.0.0/24 then redirect 10:10");
|
||||
|
||||
// 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("");
|
||||
std::string GetNeighbor() {
|
||||
gobgpapi::GetNeighborRequest request;
|
||||
|
||||
ClientContext context;
|
||||
|
||||
gobgpapi::Error return_error;
|
||||
|
||||
// result is a std::unique_ptr<grpc::ClientWriter<gobgpapi::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";
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
void AnnounceUnicastPrefix(bool withdraw) {
|
||||
const gobgpapi::ModPathArguments current_mod_path_arguments;
|
||||
|
||||
unsigned int AFI_IP = 1;
|
||||
unsigned int SAFI_UNICAST = 1;
|
||||
unsigned int ipv4_unicast_route_family = AFI_IP<<16 | SAFI_UNICAST;
|
||||
|
||||
gobgpapi::Path* current_path = new gobgpapi::Path;
|
||||
current_path->set_is_withdraw(withdraw);
|
||||
|
||||
/*
|
||||
buf:
|
||||
char *value;
|
||||
int len;
|
||||
|
||||
path:
|
||||
buf nlri;
|
||||
buf** path_attributes;
|
||||
int path_attributes_len;
|
||||
int path_attributes_cap;
|
||||
*/
|
||||
|
||||
// 10.10.20.33/22 nexthop 10.10.1.99/32
|
||||
path* path_c_struct = serialize_path(ipv4_unicast_route_family, (char*)"10.10.20.33/22");
|
||||
|
||||
// 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";
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetNeighbor(std::string neighbor_ip) {
|
||||
gobgpapi::Arguments request;
|
||||
request.set_family(4);
|
||||
request.set_name(neighbor_ip);
|
||||
|
||||
ClientContext context;
|
||||
|
||||
gobgpapi::Peer peer;
|
||||
grpc::Status status = stub_->GetNeighbor(&context, request, &peer);
|
||||
gobgpapi::GetNeighborResponse response;
|
||||
grpc::Status status = stub_->GetNeighbor(&context, request, &response);
|
||||
|
||||
if (status.ok()) {
|
||||
gobgpapi::PeerConf peer_conf = peer.conf();
|
||||
gobgpapi::PeerState peer_info = peer.info();
|
||||
|
||||
std::stringstream buffer;
|
||||
|
||||
buffer
|
||||
<< "Peer AS: " << peer_conf.peer_as() << "\n"
|
||||
<< "Peer router id: " << peer_conf.id() << "\n"
|
||||
<< "Peer flops: " << peer_info.flops() << "\n"
|
||||
<< "BGP state: " << peer_info.bgp_state();
|
||||
for (int i=0; i < response.peers_size(); i++) {
|
||||
|
||||
gobgpapi::PeerConf peer_conf = response.peers(i).conf();
|
||||
gobgpapi::PeerState peer_info = response.peers(i).info();
|
||||
gobgpapi::Timers peer_timers = response.peers(i).timers();
|
||||
|
||||
buffer
|
||||
<< "BGP neighbor is: " << peer_conf.neighbor_address()
|
||||
<< ", remote AS: " << peer_conf.peer_as() << "\n"
|
||||
<< "\tBGP version: 4, remote route ID " << peer_conf.id() << "\n"
|
||||
<< "\tBGP state = " << peer_info.bgp_state()
|
||||
<< ", up for " << peer_timers.state().uptime() << "\n"
|
||||
<< "\tBGP OutQ = " << peer_info.out_q()
|
||||
<< ", Flops = " << peer_info.flops() << "\n"
|
||||
<< "\tHold time is " << peer_timers.state().hold_time()
|
||||
<< ", keepalive interval is " << peer_timers.state().keepalive_interval() << "seconds\n"
|
||||
<< "\tConfigured hold time is " << peer_timers.config().hold_time() << "\n";
|
||||
|
||||
}
|
||||
return buffer.str();
|
||||
} else {
|
||||
return "Something wrong";
|
||||
std::stringstream buffer;
|
||||
buffer
|
||||
<< status.error_code() << "\n"
|
||||
<< status.error_message() << "\n"
|
||||
<< status.error_details() << "\n";
|
||||
return buffer.str();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,25 +71,16 @@ class GrpcClient {
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
GrpcClient gobgp_client(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
|
||||
|
||||
std::string reply = gobgp_client.GetNeighbor("213.133.111.200");
|
||||
std::cout << "Neighbor information: " << reply << std::endl;
|
||||
if(argc < 2) {
|
||||
std::cout << "Usage: ./gobgp_api_client [gobgp address]\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
gobgp_client.AnnounceUnicastPrefix(false);
|
||||
std::string addr = argv[1];
|
||||
GrpcClient gobgp_client(grpc::CreateChannel(addr + ":50051", grpc::InsecureChannelCredentials()));
|
||||
|
||||
gobgp_client.AnnounceFlowSpecPrefix(false);
|
||||
|
||||
unsigned int AFI_IP = 1;
|
||||
unsigned int SAFI_UNICAST = 1;
|
||||
unsigned int SAFI_FLOW_SPEC_UNICAST = 133;
|
||||
|
||||
unsigned int ipv4_unicast_route_family = AFI_IP<<16 | SAFI_UNICAST;
|
||||
unsigned int ipv4_flow_spec_route_family = AFI_IP<<16 | SAFI_FLOW_SPEC_UNICAST;
|
||||
|
||||
gobgp_client.GetAllActiveAnnounces(ipv4_unicast_route_family);
|
||||
std::cout << std::endl << std::endl;
|
||||
gobgp_client.GetAllActiveAnnounces(ipv4_flow_spec_route_family);
|
||||
std::string reply = gobgp_client.GetNeighbor();
|
||||
std::cout << reply;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user