976 lines
40 KiB
Diff
976 lines
40 KiB
Diff
|
|
From aa35a1a1621d911cf9b76eba232814775ea6b4d9 Mon Sep 17 00:00:00 2001
|
||
|
|
From: haozi007 <liuhao27@huawei.com>
|
||
|
|
Date: Mon, 2 Nov 2020 11:15:34 +0800
|
||
|
|
Subject: [PATCH 26/28] network: support mutlnetworks
|
||
|
|
|
||
|
|
1. support mutlnetworks
|
||
|
|
2. support dualstack for default network
|
||
|
|
|
||
|
|
Signed-off-by: haozi007 <liuhao27@huawei.com>
|
||
|
|
---
|
||
|
|
src/api/services/cri/api.proto | 6 +
|
||
|
|
src/daemon/entry/cri/cni_network_plugin.cc | 221 +++++++++++++++++++--
|
||
|
|
src/daemon/entry/cri/cni_network_plugin.h | 14 +-
|
||
|
|
src/daemon/entry/cri/cri_helpers.cc | 4 +-
|
||
|
|
src/daemon/entry/cri/cri_helpers.h | 2 +-
|
||
|
|
src/daemon/entry/cri/cri_runtime_service.h | 13 +-
|
||
|
|
src/daemon/entry/cri/cri_sandbox.cc | 202 +++++++++----------
|
||
|
|
src/daemon/entry/cri/network_plugin.cc | 120 +++++++----
|
||
|
|
src/daemon/entry/cri/network_plugin.h | 10 +-
|
||
|
|
9 files changed, 414 insertions(+), 178 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/api/services/cri/api.proto b/src/api/services/cri/api.proto
|
||
|
|
index 8aba0d3..67e5527 100644
|
||
|
|
--- a/src/api/services/cri/api.proto
|
||
|
|
+++ b/src/api/services/cri/api.proto
|
||
|
|
@@ -399,10 +399,16 @@ message PodSandboxStatusRequest {
|
||
|
|
bool verbose = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
+// PodIP represents an ip of a Pod
|
||
|
|
+message PodIP {
|
||
|
|
+ // an ip is a string representation of an IPV4 or an IPV6
|
||
|
|
+ string ip = 1;
|
||
|
|
+}
|
||
|
|
// PodSandboxNetworkStatus is the status of the network for a PodSandbox.
|
||
|
|
message PodSandboxNetworkStatus {
|
||
|
|
// IP address of the PodSandbox.
|
||
|
|
string ip = 1;
|
||
|
|
+ repeated PodIP additional_ips = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Namespace contains paths to the namespaces.
|
||
|
|
diff --git a/src/daemon/entry/cri/cni_network_plugin.cc b/src/daemon/entry/cri/cni_network_plugin.cc
|
||
|
|
index f15eba3..9cb5722 100644
|
||
|
|
--- a/src/daemon/entry/cri/cni_network_plugin.cc
|
||
|
|
+++ b/src/daemon/entry/cri/cni_network_plugin.cc
|
||
|
|
@@ -80,7 +80,7 @@ auto CNINetwork::GetPaths(Errors &err) -> char **
|
||
|
|
{
|
||
|
|
char **paths = CRIHelpers::StringVectorToCharArray(m_path);
|
||
|
|
if (paths == nullptr) {
|
||
|
|
- err.SetError("Get char ** path failed");
|
||
|
|
+ err.SetError("Get cni network paths failed");
|
||
|
|
}
|
||
|
|
return paths;
|
||
|
|
}
|
||
|
|
@@ -124,6 +124,26 @@ void CniNetworkPlugin::SetDefaultNetwork(std::unique_ptr<CNINetwork> network, st
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+void CniNetworkPlugin::UpdateMutlNetworks(std::vector<std::unique_ptr<CNINetwork>> &multNets,
|
||
|
|
+ std::vector<std::string> &binDirs, Errors &err)
|
||
|
|
+{
|
||
|
|
+ if (multNets.size() == 0) {
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+ WLockNetworkMap(err);
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ m_mutlNetworks.clear();
|
||
|
|
+ for (auto iter = multNets.begin(); iter != multNets.end(); ++iter) {
|
||
|
|
+ (*iter)->SetPaths(binDirs);
|
||
|
|
+ m_mutlNetworks[(*iter)->GetName()] = std::move(*iter);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ UnlockNetworkMap(err);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
CniNetworkPlugin::CniNetworkPlugin(std::vector<std::string> &binDirs, const std::string &confDir,
|
||
|
|
const std::string &podCidr)
|
||
|
|
: m_confDir(confDir)
|
||
|
|
@@ -139,6 +159,7 @@ CniNetworkPlugin::~CniNetworkPlugin()
|
||
|
|
if (m_syncThread.joinable()) {
|
||
|
|
m_syncThread.join();
|
||
|
|
}
|
||
|
|
+ m_mutlNetworks.clear();
|
||
|
|
}
|
||
|
|
|
||
|
|
void CniNetworkPlugin::PlatformInit(Errors &error)
|
||
|
|
@@ -259,7 +280,9 @@ out:
|
||
|
|
void CniNetworkPlugin::GetDefaultCNINetwork(const std::string &confDir, std::vector<std::string> &binDirs, Errors &err)
|
||
|
|
{
|
||
|
|
std::vector<std::string> files;
|
||
|
|
- bool found = false;
|
||
|
|
+ std::vector<std::unique_ptr<CNINetwork>> mutlNets;
|
||
|
|
+ char *default_net_name = nullptr;
|
||
|
|
+ std::string message = { "" };
|
||
|
|
|
||
|
|
if (GetCNIConfFiles(confDir, files, err) != 0) {
|
||
|
|
goto free_out;
|
||
|
|
@@ -279,17 +302,33 @@ void CniNetworkPlugin::GetDefaultCNINetwork(const std::string &confDir, std::vec
|
||
|
|
n_list = nullptr;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
+ DEBUG("parse cni network: %s", n_list->name);
|
||
|
|
|
||
|
|
- SetDefaultNetwork(std::unique_ptr<CNINetwork>(new (std::nothrow) CNINetwork(n_list->name, n_list)), binDirs,
|
||
|
|
- err);
|
||
|
|
- found = true;
|
||
|
|
- break;
|
||
|
|
+ if (default_net_name == nullptr) {
|
||
|
|
+ SetDefaultNetwork(std::unique_ptr<CNINetwork>(new (std::nothrow) CNINetwork(n_list->name, n_list)), binDirs, err);
|
||
|
|
+ default_net_name = util_strdup_s(n_list->name);
|
||
|
|
+ message += default_net_name;
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ if (strcmp(default_net_name, n_list->name) == 0) {
|
||
|
|
+ WARN("Use same name of default net: %s", default_net_name);
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ mutlNets.push_back(std::unique_ptr<CNINetwork>(new (std::nothrow) CNINetwork(n_list->name, n_list)));
|
||
|
|
+ message += ", " + std::string(n_list->name);
|
||
|
|
}
|
||
|
|
- if (!found) {
|
||
|
|
+ if (default_net_name == nullptr) {
|
||
|
|
err.Errorf("No valid networks found in %s", confDir.c_str());
|
||
|
|
+ goto free_out;
|
||
|
|
+ }
|
||
|
|
+ UpdateMutlNetworks(mutlNets, binDirs, err);
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ goto free_out;
|
||
|
|
}
|
||
|
|
+ INFO("Loaded cni plugins successfully, [ %s ]", message.c_str());
|
||
|
|
|
||
|
|
free_out:
|
||
|
|
+ free(default_net_name);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -350,6 +389,71 @@ void CniNetworkPlugin::Status(Errors &err)
|
||
|
|
CheckInitialized(err);
|
||
|
|
}
|
||
|
|
|
||
|
|
+
|
||
|
|
+bool CniNetworkPlugin::SetupMultNetworks(const std::string &ns, const std::string &defaultInterface,
|
||
|
|
+ const std::string &name,
|
||
|
|
+ const std::string &netnsPath, const std::string &podSandboxID,
|
||
|
|
+ const std::map<std::string, std::string> &annotations,
|
||
|
|
+ const std::map<std::string, std::string> &options, Errors &err)
|
||
|
|
+{
|
||
|
|
+ bool ret = false;
|
||
|
|
+ int defaultIdx = -1;
|
||
|
|
+ size_t len = 0;
|
||
|
|
+ cri_pod_network_element **networks = CRIHelpers::GetNetworkPlaneFromPodAnno(annotations, &len, err);
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ ERROR("Couldn't get network plane from pod annotations: %s", err.GetCMessage());
|
||
|
|
+ err.Errorf("Couldn't get network plane from pod annotations: %s", err.GetCMessage());
|
||
|
|
+ goto cleanup;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for (size_t i = 0; i < len; i++) {
|
||
|
|
+ if (networks[i] == nullptr || networks[i]->name == nullptr || networks[i]->interface == nullptr) {
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ struct result *preResult = nullptr;
|
||
|
|
+ auto netIter = m_mutlNetworks.find(networks[i]->name);
|
||
|
|
+ if (netIter == m_mutlNetworks.end()) {
|
||
|
|
+ err.Errorf("Cannot found user defined net: %s", networks[i]->name);
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+ if (defaultInterface == networks[i]->interface) {
|
||
|
|
+ defaultIdx = i;
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ AddToNetwork((netIter->second).get(), name, ns, networks[i]->interface, podSandboxID, netnsPath, annotations, options,
|
||
|
|
+ &preResult, err);
|
||
|
|
+ free_result(preResult);
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ ERROR("Do setup user defined net: %s, failed: %s", networks[i]->name, err.GetCMessage());
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+ INFO("Setup user defained net: %s success", networks[i]->name);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ // mask default network pod, if user defined net use same interface
|
||
|
|
+ if (defaultIdx >= 0) {
|
||
|
|
+ auto netIter = m_mutlNetworks.find(networks[defaultIdx]->name);
|
||
|
|
+ if (netIter == m_mutlNetworks.end()) {
|
||
|
|
+ err.Errorf("Cannot found user defined net: %s", networks[defaultIdx]->name);
|
||
|
|
+ goto cleanup;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ struct result *preResult = nullptr;
|
||
|
|
+ AddToNetwork((netIter->second).get(), name, ns, networks[defaultIdx]->interface, podSandboxID, netnsPath, annotations,
|
||
|
|
+ options, &preResult, err);
|
||
|
|
+ free_result(preResult);
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ ERROR("Do setup user defined net: %s, failed: %s", networks[defaultIdx]->name, err.GetCMessage());
|
||
|
|
+ goto cleanup;
|
||
|
|
+ }
|
||
|
|
+ INFO("Setup default net: %s success", networks[defaultIdx]->name);
|
||
|
|
+ ret = true;
|
||
|
|
+ }
|
||
|
|
+cleanup:
|
||
|
|
+ free_cri_pod_network(networks, len);
|
||
|
|
+ return ret;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
void CniNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name, const std::string &interfaceName,
|
||
|
|
const std::string &id, const std::map<std::string, std::string> &annotations,
|
||
|
|
const std::map<std::string, std::string> &options, Errors &err)
|
||
|
|
@@ -381,17 +485,83 @@ void CniNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name,
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
- AddToNetwork(m_defaultNetwork.get(), name, ns, interfaceName, id, netnsPath, annotations, options, &preResult, err);
|
||
|
|
+ bool setedDefaultNet = SetupMultNetworks(ns, interfaceName, name, netnsPath, id, annotations, options, err);
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ goto unlock;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (setedDefaultNet) {
|
||
|
|
+ goto unlock;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
+ AddToNetwork(m_defaultNetwork.get(), name, ns, interfaceName, id, netnsPath, annotations, options, &preResult, err);
|
||
|
|
free_result(preResult);
|
||
|
|
- preResult = nullptr;
|
||
|
|
if (err.NotEmpty()) {
|
||
|
|
ERROR("Error while adding to cni network: %s", err.GetCMessage());
|
||
|
|
}
|
||
|
|
|
||
|
|
+unlock:
|
||
|
|
UnlockNetworkMap(err);
|
||
|
|
}
|
||
|
|
|
||
|
|
+bool CniNetworkPlugin::TearDownMultNetworks(const std::string &ns, const std::string &defaultInterface,
|
||
|
|
+ const std::string &name,
|
||
|
|
+ const std::string &netnsPath, const std::string &podSandboxID, const std::map<std::string, std::string> &annotations,
|
||
|
|
+ Errors &err)
|
||
|
|
+{
|
||
|
|
+ bool ret = false;
|
||
|
|
+ int defaultIdx = -1;
|
||
|
|
+ size_t len = 0;
|
||
|
|
+ cri_pod_network_element **networks = CRIHelpers::GetNetworkPlaneFromPodAnno(annotations, &len, err);
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ ERROR("Couldn't get network plane from pod annotations: %s", err.GetCMessage());
|
||
|
|
+ err.Errorf("Couldn't get network plane from pod annotations: %s", err.GetCMessage());
|
||
|
|
+ goto cleanup;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for (size_t i = 0; i < len; i++) {
|
||
|
|
+ if (networks[i] == nullptr || networks[i]->name == nullptr || networks[i]->interface == nullptr) {
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ auto netIter = m_mutlNetworks.find(networks[i]->name);
|
||
|
|
+ if (netIter == m_mutlNetworks.end()) {
|
||
|
|
+ WARN("Cannot found user defined net: %s", networks[i]->name);
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ if (defaultInterface == networks[i]->interface) {
|
||
|
|
+ defaultIdx = i;
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ DeleteFromNetwork((netIter->second).get(), name, ns, networks[i]->interface, podSandboxID, netnsPath, annotations, err);
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ ERROR("Do teardown user defined net: %s, failed: %s", networks[i]->name, err.GetCMessage());
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+ INFO("Teardown user defained net: %s success", networks[i]->name);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ // mask default network pod, if user defined net use same interface
|
||
|
|
+ if (defaultIdx >= 0) {
|
||
|
|
+ auto netIter = m_mutlNetworks.find(networks[defaultIdx]->name);
|
||
|
|
+ if (netIter == m_mutlNetworks.end()) {
|
||
|
|
+ err.Errorf("Cannot found user defined net: %s", networks[defaultIdx]->name);
|
||
|
|
+ goto cleanup;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ DeleteFromNetwork((netIter->second).get(), name, ns, networks[defaultIdx]->interface, podSandboxID, netnsPath,
|
||
|
|
+ annotations, err);
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ ERROR("Do teardown user defined net: %s, failed: %s", networks[defaultIdx]->name, err.GetCMessage());
|
||
|
|
+ goto cleanup;
|
||
|
|
+ }
|
||
|
|
+ INFO("Teardown default net: %s success", networks[defaultIdx]->name);
|
||
|
|
+ ret = true;
|
||
|
|
+ }
|
||
|
|
+cleanup:
|
||
|
|
+ free_cri_pod_network(networks, len);
|
||
|
|
+ return ret;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
void CniNetworkPlugin::TearDownPod(const std::string &ns, const std::string &name, const std::string &interfaceName,
|
||
|
|
const std::string &id, const std::map<std::string, std::string> &annotations,
|
||
|
|
Errors &err)
|
||
|
|
@@ -400,6 +570,7 @@ void CniNetworkPlugin::TearDownPod(const std::string &ns, const std::string &nam
|
||
|
|
if (err.NotEmpty()) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
+ Errors tmpErr;
|
||
|
|
|
||
|
|
std::string netnsPath = m_criImpl->GetNetNS(id, err);
|
||
|
|
if (err.NotEmpty()) {
|
||
|
|
@@ -413,8 +584,21 @@ void CniNetworkPlugin::TearDownPod(const std::string &ns, const std::string &nam
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
- DeleteFromNetwork(m_defaultNetwork.get(), name, ns, interfaceName, id, netnsPath, annotations, err);
|
||
|
|
+ bool defaultNetDone = TearDownMultNetworks(ns, interfaceName, name, netnsPath, id, annotations, err);
|
||
|
|
+ if (defaultNetDone) {
|
||
|
|
+ goto unlock;
|
||
|
|
+ }
|
||
|
|
+ if (err.NotEmpty()) {
|
||
|
|
+ WARN("Teardown user defined networks failed: %s", err.GetCMessage());
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ DeleteFromNetwork(m_defaultNetwork.get(), name, ns, interfaceName, id, netnsPath, annotations, tmpErr);
|
||
|
|
+ if (tmpErr.NotEmpty()) {
|
||
|
|
+ WARN("Teardown default network failed: %s", tmpErr.GetCMessage());
|
||
|
|
+ err.AppendError(tmpErr.GetMessage());
|
||
|
|
+ }
|
||
|
|
|
||
|
|
+unlock:
|
||
|
|
UnlockNetworkMap(err);
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -464,7 +648,7 @@ void CniNetworkPlugin::GetPodNetworkStatus(const std::string & /*ns*/, const std
|
||
|
|
PodNetworkStatus &status, Errors &err)
|
||
|
|
{
|
||
|
|
std::string netnsPath;
|
||
|
|
- std::string ip;
|
||
|
|
+ std::vector<std::string> ips;
|
||
|
|
Errors tmpErr;
|
||
|
|
|
||
|
|
if (podSandboxID.empty()) {
|
||
|
|
@@ -482,15 +666,15 @@ void CniNetworkPlugin::GetPodNetworkStatus(const std::string & /*ns*/, const std
|
||
|
|
podSandboxID.c_str());
|
||
|
|
goto out;
|
||
|
|
}
|
||
|
|
- ip = GetPodIP(m_nsenterPath, netnsPath, interfaceName, err);
|
||
|
|
+ GetPodIP(m_nsenterPath, netnsPath, interfaceName, ips, err);
|
||
|
|
if (err.NotEmpty()) {
|
||
|
|
ERROR("GetPodIP failed: %s", err.GetCMessage());
|
||
|
|
goto out;
|
||
|
|
}
|
||
|
|
- status.SetIP(ip);
|
||
|
|
+ status.SetIPs(ips);
|
||
|
|
|
||
|
|
out:
|
||
|
|
- INFO("get_pod_network_status: %s", podSandboxID.c_str());
|
||
|
|
+ INFO("Get pod: %s network status success", podSandboxID.c_str());
|
||
|
|
}
|
||
|
|
|
||
|
|
void CniNetworkPlugin::AddToNetwork(CNINetwork *snetwork, const std::string &podName, const std::string &podNamespace,
|
||
|
|
@@ -761,7 +945,8 @@ void CniNetworkPlugin::RLockNetworkMap(Errors &error)
|
||
|
|
{
|
||
|
|
int ret = pthread_rwlock_rdlock(&m_netsLock);
|
||
|
|
if (ret != 0) {
|
||
|
|
- error.Errorf("Get read lock failed: %s", strerror(ret));
|
||
|
|
+ error.Errorf("Failed to get read lock");
|
||
|
|
+ ERROR("Get read lock failed: %s", strerror(ret));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -769,7 +954,8 @@ void CniNetworkPlugin::WLockNetworkMap(Errors &error)
|
||
|
|
{
|
||
|
|
int ret = pthread_rwlock_wrlock(&m_netsLock);
|
||
|
|
if (ret != 0) {
|
||
|
|
- error.Errorf("Get write lock failed: %s", strerror(ret));
|
||
|
|
+ error.Errorf("Failed to get write lock");
|
||
|
|
+ ERROR("Get write lock failed: %s", strerror(ret));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -777,7 +963,8 @@ void CniNetworkPlugin::UnlockNetworkMap(Errors &error)
|
||
|
|
{
|
||
|
|
int ret = pthread_rwlock_unlock(&m_netsLock);
|
||
|
|
if (ret != 0) {
|
||
|
|
- error.Errorf("Unlock failed: %s", strerror(ret));
|
||
|
|
+ error.Errorf("Failed to unlock");
|
||
|
|
+ ERROR("Unlock failed: %s", strerror(ret));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
diff --git a/src/daemon/entry/cri/cni_network_plugin.h b/src/daemon/entry/cri/cni_network_plugin.h
|
||
|
|
index 02c95fb..c59c200 100644
|
||
|
|
--- a/src/daemon/entry/cri/cni_network_plugin.h
|
||
|
|
+++ b/src/daemon/entry/cri/cni_network_plugin.h
|
||
|
|
@@ -146,6 +146,9 @@ private:
|
||
|
|
void RLockNetworkMap(Errors &error);
|
||
|
|
void WLockNetworkMap(Errors &error);
|
||
|
|
void UnlockNetworkMap(Errors &error);
|
||
|
|
+
|
||
|
|
+ void UpdateMutlNetworks(std::vector<std::unique_ptr<CNINetwork>> &multNets, std::vector<std::string> &binDirs,
|
||
|
|
+ Errors &err);
|
||
|
|
void SetDefaultNetwork(std::unique_ptr<CNINetwork> network, std::vector<std::string> &binDirs, Errors &err);
|
||
|
|
void SetPodCidr(const std::string &podCidr);
|
||
|
|
static auto GetCNIConfFiles(const std::string &pluginDir, std::vector<std::string> &vect_files, Errors &err) -> int;
|
||
|
|
@@ -155,10 +158,19 @@ private:
|
||
|
|
void ResetCNINetwork(std::map<std::string, std::unique_ptr<CNINetwork>> &newNets, Errors &err);
|
||
|
|
void UpdateDefaultNetwork();
|
||
|
|
|
||
|
|
+ bool SetupMultNetworks(const std::string &ns, const std::string &defaultInterface, const std::string &name,
|
||
|
|
+ const std::string &netnsPath, const std::string &podSandboxID, const std::map<std::string, std::string> &annotations,
|
||
|
|
+ const std::map<std::string, std::string> &options, Errors &err);
|
||
|
|
+
|
||
|
|
+ bool TearDownMultNetworks(const std::string &ns, const std::string &defaultInterface, const std::string &name,
|
||
|
|
+ const std::string &netnsPath, const std::string &podSandboxID, const std::map<std::string, std::string> &annotations,
|
||
|
|
+ Errors &err);
|
||
|
|
+
|
||
|
|
NoopNetworkPlugin m_noop;
|
||
|
|
std::unique_ptr<CNINetwork> m_loNetwork { nullptr };
|
||
|
|
-
|
||
|
|
std::unique_ptr<CNINetwork> m_defaultNetwork { nullptr };
|
||
|
|
+ std::map<std::string, std::unique_ptr<CNINetwork>> m_mutlNetworks;
|
||
|
|
+
|
||
|
|
CRIRuntimeServiceImpl *m_criImpl { nullptr };
|
||
|
|
std::string m_nsenterPath;
|
||
|
|
std::string m_confDir;
|
||
|
|
diff --git a/src/daemon/entry/cri/cri_helpers.cc b/src/daemon/entry/cri/cri_helpers.cc
|
||
|
|
index ee633b7..34d32e5 100644
|
||
|
|
--- a/src/daemon/entry/cri/cri_helpers.cc
|
||
|
|
+++ b/src/daemon/entry/cri/cri_helpers.cc
|
||
|
|
@@ -389,7 +389,7 @@ auto sha256(const char *val) -> std::string
|
||
|
|
return outputBuffer;
|
||
|
|
}
|
||
|
|
|
||
|
|
-auto GetNetworkPlaneFromPodAnno(const google::protobuf::Map<std::string, std::string> &annotations, size_t *len,
|
||
|
|
+auto GetNetworkPlaneFromPodAnno(const std::map<std::string, std::string> &annotations, size_t *len,
|
||
|
|
Errors &error) -> cri_pod_network_element **
|
||
|
|
{
|
||
|
|
auto iter = annotations.find(CRIHelpers::Constants::POD_NETWORK_ANNOTATION_KEY);
|
||
|
|
@@ -399,7 +399,7 @@ auto GetNetworkPlaneFromPodAnno(const google::protobuf::Map<std::string, std::st
|
||
|
|
parser_error err = nullptr;
|
||
|
|
result = cri_pod_network_parse_data(iter->second.c_str(), nullptr, &err, len);
|
||
|
|
if (result == nullptr) {
|
||
|
|
- error.Errorf("parse pod network json failed: %s", err);
|
||
|
|
+ error.Errorf("parse pod network json: %s failed: %s", iter->second.c_str(), err);
|
||
|
|
}
|
||
|
|
free(err);
|
||
|
|
}
|
||
|
|
diff --git a/src/daemon/entry/cri/cri_helpers.h b/src/daemon/entry/cri/cri_helpers.h
|
||
|
|
index 3ea9ba6..b9fb153 100644
|
||
|
|
--- a/src/daemon/entry/cri/cri_helpers.h
|
||
|
|
+++ b/src/daemon/entry/cri/cri_helpers.h
|
||
|
|
@@ -94,7 +94,7 @@ auto IsImageNotFoundError(const std::string &err) -> bool;
|
||
|
|
|
||
|
|
auto sha256(const char *val) -> std::string;
|
||
|
|
|
||
|
|
-auto GetNetworkPlaneFromPodAnno(const google::protobuf::Map<std::string, std::string> &annotations,
|
||
|
|
+auto GetNetworkPlaneFromPodAnno(const std::map<std::string, std::string> &annotations,
|
||
|
|
size_t *len, Errors &error) -> cri_pod_network_element **;
|
||
|
|
|
||
|
|
auto CheckpointToSandbox(const std::string &id,
|
||
|
|
diff --git a/src/daemon/entry/cri/cri_runtime_service.h b/src/daemon/entry/cri/cri_runtime_service.h
|
||
|
|
index 66837e9..1a0f601 100644
|
||
|
|
--- a/src/daemon/entry/cri/cri_runtime_service.h
|
||
|
|
+++ b/src/daemon/entry/cri/cri_runtime_service.h
|
||
|
|
@@ -210,9 +210,12 @@ private:
|
||
|
|
void ConstructPodSandboxCheckpoint(const runtime::v1alpha2::PodSandboxConfig &config,
|
||
|
|
cri::PodSandboxCheckpoint &checkpoint);
|
||
|
|
|
||
|
|
- auto GetIP(const std::string &podSandboxID, container_inspect *inspect, const std::string &networkInterface,
|
||
|
|
- Errors &error) -> std::string;
|
||
|
|
- auto GetIPFromPlugin(container_inspect *inspect, const std::string &networkInterface, Errors &error) -> std::string;
|
||
|
|
+ void GetIPs(const std::string &podSandboxID, container_inspect *inspect, const std::string &networkInterface,
|
||
|
|
+ std::vector<std::string> &ips, Errors &error);
|
||
|
|
+ void GetFormatIPsForMultNet(container_inspect *inspect, const std::string &defaultInterface,
|
||
|
|
+ const runtime::v1alpha2::PodSandboxMetadata &metadata, std::vector<std::string> &result, Errors &error);
|
||
|
|
+ auto GetIPsFromPlugin(container_inspect *inspect, const std::string &networkInterface,
|
||
|
|
+ Errors &error) -> std::vector<std::string>;
|
||
|
|
auto GetNetworkReady(const std::string &podSandboxID, Errors &error) -> bool;
|
||
|
|
void SetNetworkReady(const std::string &podSandboxID, bool ready, Errors &error);
|
||
|
|
void ClearNetworkReady(const std::string &podSandboxID);
|
||
|
|
@@ -247,9 +250,6 @@ private:
|
||
|
|
|
||
|
|
void SetupSandboxNetwork(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &response_id,
|
||
|
|
const std::string &jsonCheckpoint, Errors &error);
|
||
|
|
- void SetupUserDefinedNetworkPlane(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &response_id,
|
||
|
|
- container_inspect *inspect_data, std::map<std::string, std::string> &stdAnnos,
|
||
|
|
- std::map<std::string, std::string> &options, Errors &error);
|
||
|
|
void StartSandboxContainer(const std::string &response_id, Errors &error);
|
||
|
|
auto CreateSandboxContainer(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &image,
|
||
|
|
std::string &jsonCheckpoint, const std::string &runtimeHandler,
|
||
|
|
@@ -273,6 +273,7 @@ private:
|
||
|
|
auto ClearCniNetwork(const std::string &realSandboxID, bool hostNetwork, const std::string &ns,
|
||
|
|
const std::string &name, std::vector<std::string> &errlist,
|
||
|
|
std::map<std::string, std::string> &stdAnnos, Errors &error) -> int;
|
||
|
|
+
|
||
|
|
auto RemoveAllContainersInSandbox(const std::string &realSandboxID, std::vector<std::string> &errors) -> int;
|
||
|
|
auto DoRemovePodSandbox(const std::string &realSandboxID, std::vector<std::string> &errors) -> int;
|
||
|
|
static void MergeSecurityContextToHostConfig(const runtime::v1alpha2::PodSandboxConfig &c, host_config *hc,
|
||
|
|
diff --git a/src/daemon/entry/cri/cri_sandbox.cc b/src/daemon/entry/cri/cri_sandbox.cc
|
||
|
|
index 6db9616..b44c86c 100644
|
||
|
|
--- a/src/daemon/entry/cri/cri_sandbox.cc
|
||
|
|
+++ b/src/daemon/entry/cri/cri_sandbox.cc
|
||
|
|
@@ -458,44 +458,6 @@ void CRIRuntimeServiceImpl::StartSandboxContainer(const std::string &response_id
|
||
|
|
free_container_start_response(start_response);
|
||
|
|
}
|
||
|
|
|
||
|
|
-void CRIRuntimeServiceImpl::SetupUserDefinedNetworkPlane(const runtime::v1alpha2::PodSandboxConfig &config,
|
||
|
|
- const std::string &response_id,
|
||
|
|
- container_inspect *inspect_data,
|
||
|
|
- std::map<std::string, std::string> &stdAnnos,
|
||
|
|
- std::map<std::string, std::string> &options, Errors &error)
|
||
|
|
-{
|
||
|
|
- google::protobuf::Map<std::string, std::string> annotations;
|
||
|
|
- CRIHelpers::ExtractAnnotations(inspect_data->config->annotations, annotations);
|
||
|
|
-
|
||
|
|
- size_t len = 0;
|
||
|
|
- cri_pod_network_element **networks = CRIHelpers::GetNetworkPlaneFromPodAnno(annotations, &len, error);
|
||
|
|
- if (error.NotEmpty()) {
|
||
|
|
- ERROR("Couldn't get network plane from pod annotations: %s", error.GetCMessage());
|
||
|
|
- error.Errorf("Couldn't get network plane from pod annotations: %s", error.GetCMessage());
|
||
|
|
- goto cleanup;
|
||
|
|
- }
|
||
|
|
- for (size_t i = 0; i < len; i++) {
|
||
|
|
- if ((networks[i] != nullptr) && (networks[i]->name != nullptr) && (networks[i]->interface != nullptr) &&
|
||
|
|
- strcmp(networks[i]->name, Network::DEFAULT_NETWORK_PLANE_NAME.c_str()) != 0) {
|
||
|
|
- INFO("SetupPod net: %s", networks[i]->name);
|
||
|
|
- m_pluginManager->SetUpPod(config.metadata().namespace_(), config.metadata().name(), networks[i]->interface,
|
||
|
|
- response_id, stdAnnos, options, error);
|
||
|
|
- if (error.Empty()) {
|
||
|
|
- continue;
|
||
|
|
- }
|
||
|
|
- Errors tmpErr;
|
||
|
|
- StopContainerHelper(response_id, tmpErr);
|
||
|
|
- if (tmpErr.NotEmpty()) {
|
||
|
|
- WARN("Failed to stop sandbox container %s for pod %s: %s", response_id.c_str(), networks[i]->name,
|
||
|
|
- tmpErr.GetCMessage());
|
||
|
|
- }
|
||
|
|
- goto cleanup;
|
||
|
|
- }
|
||
|
|
- }
|
||
|
|
-cleanup:
|
||
|
|
- free_cri_pod_network(networks, len);
|
||
|
|
-}
|
||
|
|
-
|
||
|
|
void CRIRuntimeServiceImpl::SetupSandboxNetwork(const runtime::v1alpha2::PodSandboxConfig &config,
|
||
|
|
const std::string &response_id, const std::string &jsonCheckpoint,
|
||
|
|
Errors &error)
|
||
|
|
@@ -685,45 +647,6 @@ cleanup:
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
-auto CRIRuntimeServiceImpl::TearDownPodCniNetwork(const std::string &realSandboxID, std::vector<std::string> &errlist,
|
||
|
|
- std::map<std::string, std::string> &stdAnnos, const std::string &ns,
|
||
|
|
- const std::string &name, Errors &error) -> int
|
||
|
|
-{
|
||
|
|
- int ret = 0;
|
||
|
|
- cri_pod_network_element **networks = nullptr;
|
||
|
|
- container_inspect *inspect_data = InspectContainer(realSandboxID, error);
|
||
|
|
- if (inspect_data == nullptr) {
|
||
|
|
- return -1;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- google::protobuf::Map<std::string, std::string> annotations;
|
||
|
|
- CRIHelpers::ExtractAnnotations(inspect_data->config->annotations, annotations);
|
||
|
|
- size_t len = 0;
|
||
|
|
-
|
||
|
|
- networks = CRIHelpers::GetNetworkPlaneFromPodAnno(annotations, &len, error);
|
||
|
|
- if (error.NotEmpty()) {
|
||
|
|
- ERROR("Couldn't get network plane from pod annotations: %s", error.GetCMessage());
|
||
|
|
- error.Errorf("Couldn't get network plane from pod annotations: %s", error.GetCMessage());
|
||
|
|
- ret = -1;
|
||
|
|
- goto cleanup;
|
||
|
|
- }
|
||
|
|
- for (size_t i = 0; i < len; i++) {
|
||
|
|
- if ((networks[i] != nullptr) && (networks[i]->name != nullptr) && (networks[i]->interface != nullptr) &&
|
||
|
|
- strcmp(networks[i]->name, Network::DEFAULT_NETWORK_PLANE_NAME.c_str()) != 0) {
|
||
|
|
- Errors tmpErr;
|
||
|
|
- m_pluginManager->TearDownPod(ns, name, networks[i]->interface, inspect_data->id, stdAnnos, tmpErr);
|
||
|
|
- if (tmpErr.NotEmpty()) {
|
||
|
|
- WARN("TearDownPod cni network failed: %s", tmpErr.GetCMessage());
|
||
|
|
- errlist.push_back(tmpErr.GetMessage());
|
||
|
|
- }
|
||
|
|
- }
|
||
|
|
- }
|
||
|
|
-cleanup:
|
||
|
|
- free_cri_pod_network(networks, len);
|
||
|
|
- free_container_inspect(inspect_data);
|
||
|
|
- return ret;
|
||
|
|
-}
|
||
|
|
-
|
||
|
|
auto CRIRuntimeServiceImpl::ClearCniNetwork(const std::string &realSandboxID, bool hostNetwork, const std::string &ns,
|
||
|
|
const std::string &name, std::vector<std::string> &errlist,
|
||
|
|
std::map<std::string, std::string> &stdAnnos, Errors &
|
||
|
|
@@ -966,8 +889,19 @@ void CRIRuntimeServiceImpl::SetSandboxStatusNetwork(container_inspect *inspect,
|
||
|
|
std::unique_ptr<runtime::v1alpha2::PodSandboxStatus> &podStatus,
|
||
|
|
Errors &error)
|
||
|
|
{
|
||
|
|
- std::string interfaceIP = GetIP(podSandboxID, inspect, Network::DEFAULT_NETWORK_INTERFACE_NAME, error);
|
||
|
|
- podStatus->mutable_network()->set_ip(interfaceIP);
|
||
|
|
+ std::vector<std::string> ips;
|
||
|
|
+ size_t i;
|
||
|
|
+
|
||
|
|
+ GetIPs(podSandboxID, inspect, Network::DEFAULT_NETWORK_INTERFACE_NAME, ips, error);
|
||
|
|
+ if (ips.size() == 0) {
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+ podStatus->mutable_network()->set_ip(ips[0]);
|
||
|
|
+
|
||
|
|
+ for (i = 1; i < ips.size(); i++) {
|
||
|
|
+ auto tPoint = podStatus->mutable_network()->add_additional_ips();
|
||
|
|
+ tPoint->set_ip(ips[i]);
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
void CRIRuntimeServiceImpl::PodSandboxStatusToGRPC(container_inspect *inspect, const std::string &podSandboxID,
|
||
|
|
@@ -1019,66 +953,126 @@ void CRIRuntimeServiceImpl::PodSandboxStatusToGRPC(container_inspect *inspect, c
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
-auto CRIRuntimeServiceImpl::GetIPFromPlugin(container_inspect *inspect, const std::string &networkInterface,
|
||
|
|
- Errors &error) -> std::string
|
||
|
|
+void CRIRuntimeServiceImpl::GetFormatIPsForMultNet(container_inspect *inspect, const std::string &defaultInterface,
|
||
|
|
+ const runtime::v1alpha2::PodSandboxMetadata &metadata, std::vector<std::string> &result, Errors &error)
|
||
|
|
{
|
||
|
|
- if (inspect == nullptr || inspect->id == nullptr || inspect->name == nullptr) {
|
||
|
|
- error.SetError("Empty arguments");
|
||
|
|
- return "";
|
||
|
|
+ size_t len = 0;
|
||
|
|
+ cri_pod_network_element **elems { nullptr };
|
||
|
|
+ parser_error jerr { nullptr };
|
||
|
|
+
|
||
|
|
+ if (inspect->config == nullptr || inspect->config->annotations == nullptr) {
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for (size_t i = 0; i < inspect->config->annotations->len; i++) {
|
||
|
|
+ if (strcmp(inspect->config->annotations->keys[i], CRIHelpers::Constants::POD_NETWORK_ANNOTATION_KEY.c_str()) != 0) {
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ elems = cri_pod_network_parse_data(inspect->config->annotations->values[i], nullptr, &jerr, &len);
|
||
|
|
+ if (elems == nullptr) {
|
||
|
|
+ ERROR("parse mutlnetwork config failed: %s", jerr);
|
||
|
|
+ error.SetError("parse mutlnetwork config failed");
|
||
|
|
+ goto out;
|
||
|
|
+ }
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for (size_t i = 0; i < len; i++) {
|
||
|
|
+ if (elems[i]->interface == nullptr || strcmp(elems[i]->interface, defaultInterface.c_str()) == 0) {
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ Network::PodNetworkStatus status;
|
||
|
|
+ m_pluginManager->GetPodNetworkStatus(metadata.namespace_(), metadata.name(), elems[i]->interface, inspect->id, status,
|
||
|
|
+ error);
|
||
|
|
+ if (error.NotEmpty()) {
|
||
|
|
+ goto out;
|
||
|
|
+ }
|
||
|
|
+ // add a sentry to make ips of mutlnetwork store from position 2
|
||
|
|
+ if (result.size() < 2) {
|
||
|
|
+ result.push_back("");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ result.push_back(std::string(elems[i]->name) + "@" + std::string(elems[i]->interface) + "@[" + CXXUtils::StringsJoin(
|
||
|
|
+ status.GetIPs(), ", ") + "]");
|
||
|
|
+ }
|
||
|
|
+out:
|
||
|
|
+ for (size_t i = 0; i < len; i++) {
|
||
|
|
+ free_cri_pod_network_element(elems[i]);
|
||
|
|
+ elems[i] = nullptr;
|
||
|
|
}
|
||
|
|
+ free(elems);
|
||
|
|
+ free(jerr);
|
||
|
|
+}
|
||
|
|
|
||
|
|
+auto CRIRuntimeServiceImpl::GetIPsFromPlugin(container_inspect *inspect, const std::string &networkInterface,
|
||
|
|
+ Errors &error) -> std::vector<std::string>
|
||
|
|
+{
|
||
|
|
+ std::vector<std::string> ret;
|
||
|
|
runtime::v1alpha2::PodSandboxMetadata metadata;
|
||
|
|
+ std::string defaultInterface = networkInterface;
|
||
|
|
+
|
||
|
|
+ if (inspect == nullptr || inspect->id == nullptr || inspect->name == nullptr) {
|
||
|
|
+ error.SetError("Empty arguments");
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
CRINaming::ParseSandboxName(inspect->name, metadata, error);
|
||
|
|
if (error.NotEmpty()) {
|
||
|
|
- return "";
|
||
|
|
+ return ret;
|
||
|
|
}
|
||
|
|
- std::string cid = inspect->id;
|
||
|
|
- Network::PodNetworkStatus status;
|
||
|
|
- if (networkInterface.empty()) {
|
||
|
|
- m_pluginManager->GetPodNetworkStatus(metadata.namespace_(), metadata.name(),
|
||
|
|
- Network::DEFAULT_NETWORK_INTERFACE_NAME, cid, status, error);
|
||
|
|
- } else {
|
||
|
|
- m_pluginManager->GetPodNetworkStatus(metadata.namespace_(), metadata.name(), networkInterface, cid, status,
|
||
|
|
- error);
|
||
|
|
+ if (defaultInterface.empty()) {
|
||
|
|
+ defaultInterface = Network::DEFAULT_NETWORK_INTERFACE_NAME;
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+ // step 1: get ips of default network
|
||
|
|
+ Network::PodNetworkStatus status;
|
||
|
|
+ m_pluginManager->GetPodNetworkStatus(metadata.namespace_(), metadata.name(), defaultInterface, inspect->id, status,
|
||
|
|
+ error);
|
||
|
|
if (error.NotEmpty()) {
|
||
|
|
- return "";
|
||
|
|
+ return ret;
|
||
|
|
+ }
|
||
|
|
+ for (auto &iter : status.GetIPs()) {
|
||
|
|
+ ret.push_back(iter);
|
||
|
|
}
|
||
|
|
|
||
|
|
- return status.GetIP();
|
||
|
|
+ // step 2: get ips of mutl networks
|
||
|
|
+ GetFormatIPsForMultNet(inspect, defaultInterface, metadata, ret, error);
|
||
|
|
+
|
||
|
|
+ return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
-auto CRIRuntimeServiceImpl::GetIP(const std::string &podSandboxID, container_inspect *inspect,
|
||
|
|
- const std::string &networkInterface, Errors &error) -> std::string
|
||
|
|
+void CRIRuntimeServiceImpl::GetIPs(const std::string &podSandboxID, container_inspect *inspect,
|
||
|
|
+ const std::string &networkInterface, std::vector<std::string> &ips, Errors &error)
|
||
|
|
{
|
||
|
|
if (inspect == nullptr || inspect->network_settings == nullptr) {
|
||
|
|
- return "";
|
||
|
|
+ return;
|
||
|
|
}
|
||
|
|
if (SharesHostNetwork(inspect) != 0) {
|
||
|
|
// For sandboxes using host network, the shim is not responsible for reporting the IP.
|
||
|
|
- return "";
|
||
|
|
+ return;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool ready = GetNetworkReady(podSandboxID, error);
|
||
|
|
if (error.Empty() && !ready) {
|
||
|
|
WARN("Network %s do not ready", podSandboxID.c_str());
|
||
|
|
- return "";
|
||
|
|
+ return;
|
||
|
|
}
|
||
|
|
|
||
|
|
error.Clear();
|
||
|
|
- auto ip = GetIPFromPlugin(inspect, networkInterface, error);
|
||
|
|
+ auto tmpIPs = GetIPsFromPlugin(inspect, networkInterface, error);
|
||
|
|
if (error.Empty()) {
|
||
|
|
- return ip;
|
||
|
|
+ for (const auto &iter : tmpIPs) {
|
||
|
|
+ ips.push_back(iter);
|
||
|
|
+ }
|
||
|
|
+ return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (inspect->network_settings->ip_address != nullptr) {
|
||
|
|
WARN("Use container inspect ip info: %s", error.GetCMessage());
|
||
|
|
error.Clear();
|
||
|
|
- return inspect->network_settings->ip_address;
|
||
|
|
+ ips.push_back(inspect->network_settings->ip_address);
|
||
|
|
}
|
||
|
|
|
||
|
|
WARN("Failed to read pod IP from plugin/docker: %s", error.GetCMessage());
|
||
|
|
- return "";
|
||
|
|
}
|
||
|
|
|
||
|
|
std::unique_ptr<runtime::v1alpha2::PodSandboxStatus>
|
||
|
|
diff --git a/src/daemon/entry/cri/network_plugin.cc b/src/daemon/entry/cri/network_plugin.cc
|
||
|
|
index 0cab31a..311ebb6 100644
|
||
|
|
--- a/src/daemon/entry/cri/network_plugin.cc
|
||
|
|
+++ b/src/daemon/entry/cri/network_plugin.cc
|
||
|
|
@@ -65,25 +65,58 @@ static void runGetIP(void *cmdArgs)
|
||
|
|
execvp(tmpArgs[0], args);
|
||
|
|
}
|
||
|
|
|
||
|
|
-static std::string GetOnePodIP(std::string nsenterPath, std::string netnsPath, std::string interfaceName,
|
||
|
|
- std::string addrType, Errors &error)
|
||
|
|
+static std::string ParseIPFromLine(const char *line, const char *stdout_str)
|
||
|
|
{
|
||
|
|
- char *stderr_str { nullptr };
|
||
|
|
- char *stdout_str { nullptr };
|
||
|
|
- char *strErr { nullptr };
|
||
|
|
- char **lines { nullptr };
|
||
|
|
+ char *cIP { nullptr };
|
||
|
|
char **fields { nullptr };
|
||
|
|
+ char *strErr { nullptr };
|
||
|
|
struct ipnet *ipnet_val {
|
||
|
|
nullptr
|
||
|
|
};
|
||
|
|
+ std::string ret;
|
||
|
|
+
|
||
|
|
+ fields = util_string_split(line, ' ');
|
||
|
|
+ if (fields == nullptr) {
|
||
|
|
+ ERROR("Out of memory");
|
||
|
|
+ goto out;
|
||
|
|
+ }
|
||
|
|
+ if (util_array_len((const char **)fields) < 4) {
|
||
|
|
+ ERROR("Unexpected address output %s ", line);
|
||
|
|
+ goto out;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (parse_cidr(fields[3], &ipnet_val, &strErr) != 0) {
|
||
|
|
+ ERROR("CNI failed to parse ip from output %s due to %s", stdout_str, strErr);
|
||
|
|
+ goto out;
|
||
|
|
+ }
|
||
|
|
+ cIP = ip_to_string(ipnet_val->ip, ipnet_val->ip_len);
|
||
|
|
+ if (cIP == nullptr) {
|
||
|
|
+ ERROR("Out of memory");
|
||
|
|
+ goto out;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ ret = cIP;
|
||
|
|
+out:
|
||
|
|
+ free(cIP);
|
||
|
|
+ free(strErr);
|
||
|
|
+ free_ipnet_type(ipnet_val);
|
||
|
|
+ util_free_array(fields);
|
||
|
|
+ return ret;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static void GetOnePodIP(std::string nsenterPath, std::string netnsPath, std::string interfaceName,
|
||
|
|
+ std::string addrType, std::vector<std::string> &ips, Errors &error)
|
||
|
|
+{
|
||
|
|
+ char *stderr_str { nullptr };
|
||
|
|
+ char *stdout_str { nullptr };
|
||
|
|
+ char **lines { nullptr };
|
||
|
|
char **args { nullptr };
|
||
|
|
- std::string result { "" };
|
||
|
|
- char *cIP { nullptr };
|
||
|
|
+ size_t i;
|
||
|
|
|
||
|
|
args = (char **)util_common_calloc_s(sizeof(char *) * 5);
|
||
|
|
if (args == nullptr) {
|
||
|
|
error.SetError("Out of memory");
|
||
|
|
- return result;
|
||
|
|
+ return;
|
||
|
|
}
|
||
|
|
|
||
|
|
args[0] = util_strdup_s(nsenterPath.c_str());
|
||
|
|
@@ -102,52 +135,55 @@ static std::string GetOnePodIP(std::string nsenterPath, std::string netnsPath, s
|
||
|
|
error.SetError("Out of memory");
|
||
|
|
goto free_out;
|
||
|
|
}
|
||
|
|
- if (util_array_len((const char **)lines) < 1) {
|
||
|
|
- error.Errorf("Unexpected command output %s", stdout_str);
|
||
|
|
- goto free_out;
|
||
|
|
- }
|
||
|
|
|
||
|
|
- fields = util_string_split(lines[0], ' ');
|
||
|
|
- if (fields == nullptr) {
|
||
|
|
- error.SetError("Out of memory");
|
||
|
|
- goto free_out;
|
||
|
|
- }
|
||
|
|
- if (util_array_len((const char **)fields) < 4) {
|
||
|
|
- error.Errorf("Unexpected address output %s ", lines[0]);
|
||
|
|
+ if (util_array_len((const char **)lines) == 0) {
|
||
|
|
+ error.Errorf("Unexpected command output %s", stdout_str);
|
||
|
|
goto free_out;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (parse_cidr(fields[3], &ipnet_val, &strErr) != 0) {
|
||
|
|
- error.Errorf("CNI failed to parse ip from output %s due to %s", stdout_str, strErr);
|
||
|
|
- goto free_out;
|
||
|
|
- }
|
||
|
|
- cIP = ip_to_string(ipnet_val->ip, ipnet_val->ip_len);
|
||
|
|
- if (cIP == nullptr) {
|
||
|
|
- error.SetError("Out of memory");
|
||
|
|
- goto free_out;
|
||
|
|
+ for (i = 0; i < util_array_len((const char **)lines); i++) {
|
||
|
|
+ // ip string min length must bigger than 4
|
||
|
|
+ if (lines[i] == nullptr || strlen(lines[i]) < 4) {
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ std::string tIP = ParseIPFromLine(lines[i], stdout_str);
|
||
|
|
+ if (tIP.empty()) {
|
||
|
|
+ error.Errorf("parse %s to ip failed", lines[i]);
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+ ips.push_back(tIP);
|
||
|
|
}
|
||
|
|
- result = cIP;
|
||
|
|
- free(cIP);
|
||
|
|
|
||
|
|
free_out:
|
||
|
|
- free_ipnet_type(ipnet_val);
|
||
|
|
free(stdout_str);
|
||
|
|
free(stderr_str);
|
||
|
|
util_free_array(args);
|
||
|
|
util_free_array(lines);
|
||
|
|
- util_free_array(fields);
|
||
|
|
- return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
-std::string GetPodIP(const std::string &nsenterPath, const std::string &netnsPath, const std::string &interfaceName,
|
||
|
|
- Errors &error)
|
||
|
|
+void GetPodIP(const std::string &nsenterPath, const std::string &netnsPath, const std::string &interfaceName,
|
||
|
|
+ std::vector<std::string> &getIPs, Errors &error)
|
||
|
|
{
|
||
|
|
- std::string ip = GetOnePodIP(nsenterPath, netnsPath, interfaceName, "-4", error);
|
||
|
|
+ Errors tmpErr;
|
||
|
|
+
|
||
|
|
+ GetOnePodIP(nsenterPath, netnsPath, interfaceName, "-4", getIPs, tmpErr);
|
||
|
|
+ if (tmpErr.NotEmpty()) {
|
||
|
|
+ WARN("Get ipv4 failed: %s", tmpErr.GetCMessage());
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ GetOnePodIP(nsenterPath, netnsPath, interfaceName, "-6", getIPs, error);
|
||
|
|
if (error.NotEmpty()) {
|
||
|
|
- return GetOnePodIP(nsenterPath, netnsPath, interfaceName, "-6", error);
|
||
|
|
+ WARN("Get ipv6 failed: %s", tmpErr.GetCMessage());
|
||
|
|
}
|
||
|
|
|
||
|
|
- return ip;
|
||
|
|
+ if (getIPs.size() > 0) {
|
||
|
|
+ error.Clear();
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (tmpErr.NotEmpty()) {
|
||
|
|
+ error.AppendError(tmpErr.GetMessage());
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
void InitNetworkPlugin(std::vector<std::shared_ptr<NetworkPlugin>> *plugins, std::string networkPluginName,
|
||
|
|
@@ -290,14 +326,14 @@ void PodNetworkStatus::SetAPIVersion(const std::string &version)
|
||
|
|
m_apiVersion = version;
|
||
|
|
}
|
||
|
|
|
||
|
|
-const std::string &PodNetworkStatus::GetIP() const
|
||
|
|
+const std::vector<std::string> &PodNetworkStatus::GetIPs() const
|
||
|
|
{
|
||
|
|
- return m_ip;
|
||
|
|
+ return m_ips;
|
||
|
|
}
|
||
|
|
|
||
|
|
-void PodNetworkStatus::SetIP(const std::string &ip)
|
||
|
|
+void PodNetworkStatus::SetIPs(std::vector<std::string> &ips)
|
||
|
|
{
|
||
|
|
- m_ip = ip;
|
||
|
|
+ m_ips = ips;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PluginManager::Lock(const std::string &fullPodName, Errors &error)
|
||
|
|
diff --git a/src/daemon/entry/cri/network_plugin.h b/src/daemon/entry/cri/network_plugin.h
|
||
|
|
index 5a46eb8..24afd71 100644
|
||
|
|
--- a/src/daemon/entry/cri/network_plugin.h
|
||
|
|
+++ b/src/daemon/entry/cri/network_plugin.h
|
||
|
|
@@ -82,13 +82,13 @@ public:
|
||
|
|
void SetKind(const std::string &kind);
|
||
|
|
const std::string &GetAPIVersion() const;
|
||
|
|
void SetAPIVersion(const std::string &version);
|
||
|
|
- const std::string &GetIP() const;
|
||
|
|
- void SetIP(const std::string &ip);
|
||
|
|
+ const std::vector<std::string> &GetIPs() const;
|
||
|
|
+ void SetIPs(std::vector<std::string> &ips);
|
||
|
|
|
||
|
|
private:
|
||
|
|
std::string m_kind;
|
||
|
|
std::string m_apiVersion;
|
||
|
|
- std::string m_ip;
|
||
|
|
+ std::vector<std::string> m_ips;
|
||
|
|
};
|
||
|
|
|
||
|
|
class NetworkPlugin {
|
||
|
|
@@ -227,8 +227,8 @@ void InitNetworkPlugin(std::vector<std::shared_ptr<NetworkPlugin>> *plugins, std
|
||
|
|
void ProbeNetworkPlugins(const std::string &pluginDir, const std::string &binDir,
|
||
|
|
std::vector<std::shared_ptr<NetworkPlugin>> *plugins);
|
||
|
|
|
||
|
|
-std::string GetPodIP(const std::string &nsenterPath, const std::string &netnsPath, const std::string &interfaceName,
|
||
|
|
- Errors &error);
|
||
|
|
+void GetPodIP(const std::string &nsenterPath, const std::string &netnsPath, const std::string &interfaceName,
|
||
|
|
+ std::vector<std::string> &getIPs, Errors &error);
|
||
|
|
|
||
|
|
const std::string &GetInterfaceName();
|
||
|
|
} // namespace Network
|
||
|
|
--
|
||
|
|
2.20.1
|
||
|
|
|