Skip to content

Commit

Permalink
[ovsp4rt] Implement Client class (#713)
Browse files Browse the repository at this point in the history
- Implemented the `Client` `ClientInterface`, and `ClientMock`
  classes, to abstract the interface to the P4Runtime server.

Signed-off-by: Derek Foster <justffoulkes@gmail.com>
  • Loading branch information
ffoulkes authored Dec 10, 2024
1 parent fc2d667 commit e3ba056
Show file tree
Hide file tree
Showing 6 changed files with 304 additions and 5 deletions.
20 changes: 15 additions & 5 deletions ovs-p4rt/sidecar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
# SPDX-License-Identifier: Apache 2.0
#

option(BUILD_CLIENT "Build ovs-p4rt with Client class" OFF)
option(BUILD_JOURNAL "Build ovs-p4rt with Journal class" OFF)
option(BUILD_SPIES "Build ovs-p4rt with spies" OFF)
option(BUILD_SPIES "Build ovs-p4rt spies library" OFF)

mark_as_advanced(BUILD_CLIENT)
mark_as_advanced(BUILD_JOURNAL)
mark_as_advanced(BUILD_SPIES)

Expand Down Expand Up @@ -113,16 +116,23 @@ else()
add_library(ovsp4rt_test ALIAS ovsp4rt)
endif()

#-----------------------------------------------------------------------
# libovsp4rt_spies.a
#-----------------------------------------------------------------------
if(BUILD_SPIES)
add_subdirectory(spies)
endif()

#-----------------------------------------------------------------------
# libovsp4rt_stubs.a
#-----------------------------------------------------------------------
add_subdirectory(stubs)

#-----------------------------------------------------------------------
# libovsp4rt_spies.a
# libovsp4rt_client_o
#-----------------------------------------------------------------------
if(BUILD_SPIES)
add_subdirectory(spies)
if(BUILD_CLIENT)
add_subdirectory(client)
endif()

#-----------------------------------------------------------------------
Expand Down Expand Up @@ -168,5 +178,5 @@ if(BUILD_TESTING)
endif()

add_custom_target(ovsp4rt-unit-tests
DEPENDS ${UNIT_TEST_NAMES}
DEPENDS ${UNIT_TEST_NAMES}
)
36 changes: 36 additions & 0 deletions ovs-p4rt/sidecar/client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# CMake build file for ovs-p4rt/sidecar/client
#
# Copyright 2024 Intel Corporation
# SPDX-License-Identifier: Apache 2.0
#

#-----------------------------------------------------------------------
# ovsp4rt_client_o
#-----------------------------------------------------------------------
add_library(ovsp4rt_client_o OBJECT
ovsp4rt_client.cc
ovsp4rt_client.h
ovsp4rt_client_interface.h
)

target_include_directories(ovsp4rt_client_o PUBLIC
${SIDECAR_SOURCE_DIR}
)

#-----------------------------------------------------------------------
# libovsp4rt_client.a
#-----------------------------------------------------------------------
add_library(ovsp4rt_client STATIC
$<TARGET_OBJECTS:ovsp4rt_client_o>
)

#-----------------------------------------------------------------------
# ovsp4rt_client_so
#-----------------------------------------------------------------------
add_library(ovsp4rt_client_so SHARED EXCLUDE_FROM_ALL
$<TARGET_OBJECTS:ovsp4rt_client_o>
)

set_target_properties(ovsp4rt_client_so PROPERTIES
OUTPUT_NAME ovsp4rt_client
)
66 changes: 66 additions & 0 deletions ovs-p4rt/sidecar/client/ovsp4rt_client.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2022-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "ovsp4rt_client.h"

#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "session/ovsp4rt_credentials.h"
#include "session/ovsp4rt_session.h"

#define DEFAULT_ROLE_NAME "ovs-p4rt"

ABSL_FLAG(uint64_t, device_id, 1, "P4Runtime device ID.");

ABSL_FLAG(std::string, role_name, DEFAULT_ROLE_NAME, "P4 config role name.");

namespace ovsp4rt {

absl::Status Client::connect(const char* grpc_addr) {
// Start a new client session.
auto result = ovsp4rt::OvsP4rtSession::Create(
grpc_addr, GenerateClientCredentials(), absl::GetFlag(FLAGS_device_id),
absl::GetFlag(FLAGS_role_name));
if (!result.ok()) {
return result.status();
}

// Unwrap the session from the StatusOr object.
session_ = std::move(result).value();
return absl::OkStatus();
}

absl::Status Client::getPipelineConfig(::p4::config::v1::P4Info* p4info) {
return GetForwardingPipelineConfig(session_.get(), p4info);
}

::p4::v1::TableEntry* Client::initReadRequest(::p4::v1::ReadRequest* request) {
return SetupTableEntryToRead(session_.get(), request);
}

absl::StatusOr<::p4::v1::ReadResponse> Client::sendReadRequest(
const p4::v1::ReadRequest& request) {
return SendReadRequest(session_.get(), request);
}

::p4::v1::TableEntry* Client::initInsertRequest(
::p4::v1::WriteRequest* request) {
return SetupTableEntryToInsert(session_.get(), request);
}

::p4::v1::TableEntry* Client::initModifyRequest(
::p4::v1::WriteRequest* request) {
return SetupTableEntryToModify(session_.get(), request);
}

::p4::v1::TableEntry* Client::initDeleteRequest(
::p4::v1::WriteRequest* request) {
return SetupTableEntryToDelete(session_.get(), request);
}

absl::Status Client::sendWriteRequest(const p4::v1::WriteRequest& request) {
return SendWriteRequest(session_.get(), request);
}

} // namespace ovsp4rt
77 changes: 77 additions & 0 deletions ovs-p4rt/sidecar/client/ovsp4rt_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#ifndef OVSP4RT_CLIENT_H_
#define OVSP4RT_CLIENT_H_

#include <stdint.h>

#include <string>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "ovsp4rt_client_interface.h"
#include "p4/v1/p4runtime.pb.h"
#include "session/ovsp4rt_session.h"

namespace ovsp4rt {

class Client : public ClientInterface {
public:
Client() {}
virtual ~Client() = default;

// Connects to the P4Runtime server.
virtual absl::Status connect(const char* grpc_addr);

// Returns a pointer to the ovsp4rt session object.
virtual OvsP4rtSession* session() const { return session_.get(); }

// Gets the pipeline configuration from the P4Runtime server.
virtual absl::Status getPipelineConfig(::p4::config::v1::P4Info* p4info);

//--------------------------------------------------------------------

// Initializes a Read Table Entry request message.
virtual ::p4::v1::TableEntry* initReadRequest(::p4::v1::ReadRequest* request);

// Sends a Read Table Entry request to the P4Runtime server.
virtual absl::StatusOr<p4::v1::ReadResponse> sendReadRequest(
const p4::v1::ReadRequest& request);

//--------------------------------------------------------------------

// Initializes an Insert Table Entry request message.
virtual ::p4::v1::TableEntry* initInsertRequest(
::p4::v1::WriteRequest* request);

// Initializes a Modify Table Entry request message.
virtual ::p4::v1::TableEntry* initModifyRequest(
::p4::v1::WriteRequest* request);

// Initializes a Delete Table Entry request message.
virtual ::p4::v1::TableEntry* initDeleteRequest(
::p4::v1::WriteRequest* request);

// Initializes an Insert Table Entry or Delete Table Entry request
// message, depending on the value of the `insert_entry` parameter.
virtual ::p4::v1::TableEntry* initWriteRequest(
::p4::v1::WriteRequest* request, bool insert_entry) {
if (insert_entry) {
return initInsertRequest(request);
} else {
return initDeleteRequest(request);
}
}

// Sends a Write Table Entry request to the P4Runtime server.
virtual absl::Status sendWriteRequest(const p4::v1::WriteRequest& request);

private:
// Pointer to a P4Runtime session object.
std::unique_ptr<ovsp4rt::OvsP4rtSession> session_;
};

} // namespace ovsp4rt

#endif // OVSP4RT_CLIENT_H_
67 changes: 67 additions & 0 deletions ovs-p4rt/sidecar/client/ovsp4rt_client_interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#ifndef OVSP4RT_CLIENT_INTERFACE_H_
#define OVSP4RT_CLIENT_INTERFACE_H_

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "p4/v1/p4runtime.pb.h"
#include "session/ovsp4rt_session.h"

namespace ovsp4rt {

class ClientInterface {
public:
virtual ~ClientInterface() = default;

// Connects to the P4Runtime server.
virtual absl::Status connect(const char* grpc_addr) = 0;

// Returns a pointer to the ovsp4rt session object.
virtual OvsP4rtSession* session() const = 0;

// Gets the pipeline configuration from the P4Runtime server.
virtual absl::Status getPipelineConfig(::p4::config::v1::P4Info* p4info) = 0;

//--------------------------------------------------------------------

// Initializes a Read Table Entry request message.
virtual ::p4::v1::TableEntry* initReadRequest(
::p4::v1::ReadRequest* request) = 0;

// Sends a Read Table Entry request to the P4Runtime server.
virtual absl::StatusOr<p4::v1::ReadResponse> sendReadRequest(
const p4::v1::ReadRequest& request) = 0;

//--------------------------------------------------------------------

// Initializes an Insert Table Entry request message.
virtual ::p4::v1::TableEntry* initInsertRequest(
::p4::v1::WriteRequest* request) = 0;

// Initializes a Modify Table Entry request message.
virtual ::p4::v1::TableEntry* initModifyRequest(
::p4::v1::WriteRequest* request) = 0;

// Initializes a Delete Table Entry request message.
virtual ::p4::v1::TableEntry* initDeleteRequest(
::p4::v1::WriteRequest* request) = 0;

// Initializes an Insert Table Entry or Delete Table Entry request
// message, depending on the value of the `insert_entry` parameter.
virtual ::p4::v1::TableEntry* initWriteRequest(
::p4::v1::WriteRequest* request, bool insert_entry) = 0;

// Sends a Write Table Entry request to the P4Runtime server.
virtual absl::Status sendWriteRequest(
const p4::v1::WriteRequest& request) = 0;

protected:
// Default constructor. To be called by the Mock class instance only.
ClientInterface() {}
};

} // namespace ovsp4rt

#endif // OVSP4RT_CLIENT_INTERFACE_H_
43 changes: 43 additions & 0 deletions ovs-p4rt/sidecar/client/ovsp4rt_client_mock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#ifndef OVSP4RT_CLIENT_MOCK_H_
#define OVSP4RT_CLIENT_MOCK_H_

#include "gmock/gmock.h"
#include "ovsp4rt_client_interface.h"

namespace ovsp4rt {

class ClientMock : public ClientInterface {
public:
MOCK_METHOD(absl::Status, connect, (const char*));

MOCK_METHOD(OvsP4rtSession*, session, (), (const));

MOCK_METHOD(absl::Status, getPipelineConfig, (::p4::config::v1::P4Info*));

MOCK_METHOD(::p4::v1::TableEntry*, initReadRequest, (::p4::v1::ReadRequest*));

MOCK_METHOD(absl::StatusOr<p4::v1::ReadResponse>, sendReadRequest,
(const p4::v1::ReadRequest&));

MOCK_METHOD(::p4::v1::TableEntry*, initInsertRequest,
(::p4::v1::WriteRequest*));

MOCK_METHOD(::p4::v1::TableEntry*, initModifyRequest,
(::p4::v1::WriteRequest*));

MOCK_METHOD(::p4::v1::TableEntry*, initDeleteRequest,
(::p4::v1::WriteRequest*));

MOCK_METHOD(::p4::v1::TableEntry*, initWriteRequest,
(::p4::v1::WriteRequest*, bool));

MOCK_METHOD(absl::Status, sendWriteRequest,
(const p4::v1::WriteRequest& request));
};

} // namespace ovsp4rt

#endif // OVSP4RT_CLIENT_MOCK_H_

0 comments on commit e3ba056

Please sign in to comment.