PI源码分析以及服务注入(3)

demo_grpc server 端代码分析

首先,需要说明的是在本项目中编译后端即目标交换机不是 bmv2, 使用 dummy交换机, 该交换机的所有相关代码都没有实现,需要开发者根据自己的目标交换机来实现具体的函数。

函数入口

pi_server_main.cpp 是整个server 端的入口。关键函数:

1
2
3
4
5
PIGrpcServerRunAddr(server_address);
```
查看函数 <font color=red>void PIGrpcServerRunAddr(const char *server_address)</font>, 该函数位于 pi_server.cpp 文件中。该函数将会初始化整个服务器,包括绑定服务等等。下面将会分析P4runtime 提供的相关服务。在该文件中,类 P4RuntimeServiceImpl 实现了p4runtime 的服务。
```cpp
class P4RuntimeServiceImpl : public p4v1::P4Runtime::Service {...}

p4runtime 的服务函数包括:

  1. Write 函数,

    Status Write(ServerContext *context,
                const p4v1::WriteRequest *request,
                p4v1::WriteResponse *rep) override {}
    

    简介:Write 函数实现了 Write rpc服务,用作 client 向 server 端进行相关写操作。关键代码:

    auto device = Devices::get(request->device_id());//根据device_id确定要访问的设备;
    ...
    auto device_mgr = device->get_p4_mgr();// 获取访问对象的 p4_mgr, 该 p4_mgr 由p4代码段生成的json文件配置而成。
    ...
    auto status = device_mgr->write(*request);// 将client端的request交由device_mgr, 由device_mgr进行相关处理。
    
  2. Read 函数

    Status Read(ServerContext *context,
               const p4v1::ReadRequest *request,
               ServerWriter<p4v1::ReadResponse> *writer) override {...}
    

    简介: Read 函数实现了 p4runtime proto 中的 Read rpc 服务。用于从client端向server端读取信息。server端将转发请求给device_mgr,之后server端收到device_mgr的返回信息,然后在发送给client端:

    auto status = device_mgr->read(*request, &response);
    writer->Write(response);//结果写回client端
    
  3. SetForwardingPipelineConfig 函数
    Status SetForwardingPipelineConfig(
       ServerContext *context,
       const p4v1::SetForwardingPipelineConfigRequest *request,
       p4v1::SetForwardingPipelineConfigResponse *rep) override {...}
    
    简介: 该函数实现了 rpc SetForwardingPipelineConfig 服务
    auto device_mgr = device->get_or_add_p4_mgr();// 获取或者重新分配给一个device_mgr给device;
     auto status = device_mgr->pipeline_config_set(
         request->action(), request->config()); // 配置device_mgr
    
  4. GetForwardingPipelineConfig 函数
    Status GetForwardingPipelineConfig(
       ServerContext *context,
       const p4v1::GetForwardingPipelineConfigRequest *request,
       p4v1::GetForwardingPipelineConfigResponse *rep) override {...}
    
    简介: 获取device的配置文件
  5. StreamChannel 函数
    Status StreamChannel(ServerContext *context,
                        StreamChannelReaderWriter *stream) override {...}
    
    简介: 双向 stream rpc 服务。server端会根据从 request中解析出来的字段 update_case 来做出相应的决策。分析部分代码:
    case p4v1::StreamMessageRequest::kPacket:
     {
       if (connection_status.connection == nullptr) break;
       auto device_id = connection_status.device_id;
       Devices::get(device_id)->process_packet_out(
           connection_status.connection.get(), request.packet());
     }
     break;
    
    这段代码执行了packet_out 操作, 即将 client 端的packet发送到device设备上。

summery for server services

以上5个函数实现了所有server端提供的 rpc 服务。这5个函数也是在 p4runtime proto 中提前定义好的 rpc 服务。