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:
Satoshi Fujimoto
2017-06-30 13:33:07 +09:00
parent aea13caea6
commit 487c30fbc4
2 changed files with 49 additions and 231 deletions
+13 -12
View File
@@ -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
+36 -219
View File
@@ -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;
}