Skip to content

Commit

Permalink
Merge pull request #572 from noironetworks/opflex-hpp-optimization
Browse files Browse the repository at this point in the history
Changes for local network policies
  • Loading branch information
mchalla authored Jul 18, 2024
2 parents efa3d40 + dab0a5c commit c027360
Show file tree
Hide file tree
Showing 29 changed files with 854 additions and 104 deletions.
2 changes: 2 additions & 0 deletions agent-ovs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ libopflex_agent_la_include_HEADERS = \
lib/include/opflexagent/Snat.h \
lib/include/opflexagent/SnatSource.h \
lib/include/opflexagent/SnatListener.h \
lib/include/opflexagent/FSNetpolSource.h \
lib/include/opflexagent/FSPacketDropLogConfigSource.h \
lib/include/opflexagent/PacketDropLogConfig.h \
lib/include/opflexagent/Faults.h \
Expand Down Expand Up @@ -228,6 +229,7 @@ libopflex_agent_la_SOURCES = \
lib/Snat.cpp \
lib/SnatManager.cpp \
lib/SnatSource.cpp \
lib/FSNetpolSource.cpp \
lib/FSPacketDropLogConfigSource.cpp \
lib/AgentPrometheusManager.cpp

Expand Down
30 changes: 29 additions & 1 deletion agent-ovs/lib/Agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <opflexagent/FSLearningBridgeSource.h>
#include <opflexagent/FSExternalEndpointSource.h>
#include <opflexagent/FSSnatSource.h>
#include <opflexagent/FSNetpolSource.h>
#include <opflexagent/FSPacketDropLogConfigSource.h>
#include <opflexagent/logging.h>

Expand Down Expand Up @@ -78,7 +79,8 @@ Agent::Agent(OFFramework& framework_, const LogParams& _logParams)
prometheusExposeEpSvcNan(false),
behaviorL34FlowsWithoutSubnet(true),
logParams(_logParams),
startupPolicyEnabled(false) {
startupPolicyEnabled(false),
localNetpolEnabled(false) {
std::random_device rng;
std::mt19937 urng(rng());
uuid = to_string(basic_random_generator<std::mt19937>(urng)());
Expand Down Expand Up @@ -149,6 +151,7 @@ void Agent::setProperties(const boost::property_tree::ptree& properties) {
static const std::string ENDPOINT_SOURCE_MODEL_LOCAL("endpoint-sources.model-local");
static const std::string SERVICE_SOURCE_PATH("service-sources.filesystem");
static const std::string SNAT_SOURCE_PATH("snat-sources.filesystem");
static const std::string NETPOL_SOURCE_PATH("netpol-sources.filesystem");
static const std::string DROP_LOG_CFG_SOURCE_FSPATH("drop-log-config-sources.filesystem");
static const std::string FAULT_SOURCE_FSPATH("host-agent-fault-sources.filesystem");
static const std::string PACKET_EVENT_NOTIF_SOCK("packet-event-notif.socket-name");
Expand Down Expand Up @@ -194,6 +197,7 @@ void Agent::setProperties(const boost::property_tree::ptree& properties) {
static const std::string OPFLEX_POLICY_FILE("opflex.startup.policy-file");
static const std::string OPFLEX_LOCAL_RESOLVE_AFTER_CONNECTION("opflex.startup.resolve-aft-conn");
static const std::string OPFLEX_STARTUP_POLICY_DURATION("opflex.startup.policy-duration");
static const std::string OPFLEX_ENABLE_LOCAL_NETPOL("opflex.enable-local-netpol");

// set feature flags to true
clearFeatureFlags();
Expand Down Expand Up @@ -327,6 +331,13 @@ void Agent::setProperties(const boost::property_tree::ptree& properties) {
snatSourcePaths.insert(v.second.data());
}

optional<const ptree&> netpolSource =
properties.get_child_optional(NETPOL_SOURCE_PATH);
if (netpolSource) {
for (const ptree::value_type &v : netpolSource.get())
netpolSourcePaths.insert(v.second.data());
}

optional<const ptree&> dropLogCfgSrc =
properties.get_child_optional(DROP_LOG_CFG_SOURCE_FSPATH);

Expand Down Expand Up @@ -556,6 +567,13 @@ void Agent::setProperties(const boost::property_tree::ptree& properties) {
localResolveAftConn = lResolveAftConn.get();
LOG(INFO) << "Startup policy resolve after connection set to " << localResolveAftConn;
}

optional<bool> enableLocalNetpol =
properties.get_optional<bool>(OPFLEX_ENABLE_LOCAL_NETPOL);
if (enableLocalNetpol && enableLocalNetpol.get()) {
localNetpolEnabled = true;
LOG(INFO) << "Local Network Policy is enabled";
}
}

void Agent::applyProperties() {
Expand All @@ -568,13 +586,16 @@ void Agent::applyProperties() {
policyManager.setOpflexDomain(opflexDomain.get());
}

policyManager.configLocalNetpol(localNetpolEnabled);
if (endpointSourceFSPaths.empty() &&
endpointSourceModelLocalNames.empty())
LOG(ERROR) << "No endpoint sources found in configuration.";
if (serviceSourcePaths.empty())
LOG(INFO) << "No service sources found in configuration.";
if (snatSourcePaths.empty())
LOG(INFO) << "No SNAT sources found in configuration.";
if (netpolSourcePaths.empty())
LOG(INFO) << "No Local Network Policy sources found in configuration.";
if (opflexPeers.empty())
LOG(ERROR) << "No Opflex peers found in configuration";
if (renderers.empty())
Expand Down Expand Up @@ -696,6 +717,13 @@ void Agent::start() {
new FSSnatSource(&snatManager, fsWatcher, path);
snatSources.emplace_back(source);
}
if (localNetpolEnabled) {
for (const std::string& path : netpolSourcePaths) {
FSNetpolSource* source =
new FSNetpolSource(framework, fsWatcher, path);
netpolSources.emplace_back(source);
}
}
if(!dropLogCfgSourcePath.empty()) {
opflex::modb::URI uri = (opflex::modb::URIBuilder()
.addElement("PolicyUniverse").addElement("ObserverDropLogConfig")
Expand Down
80 changes: 61 additions & 19 deletions agent-ovs/lib/EndpointManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,17 +883,32 @@ bool EndpointManager::updateEndpointLocal(const string& uuid,
}
newlocall2eps.insert(l2e->getURI());

vector<shared_ptr<EndPointToSecGroupRSrc> > oldSecGrps;
l2e->resolveEpdrEndPointToSecGroupRSrc(oldSecGrps);
const set<URI>& secGrps = es.endpoint->getSecurityGroups();
for (const shared_ptr<EndPointToSecGroupRSrc>& og :
oldSecGrps) {
optional<URI> targ = og->getTargetURI();
if (!targ || secGrps.find(targ.get()) == secGrps.end())
og->remove();
}
for (const URI& sg : secGrps) {
l2e->addEpdrEndPointToSecGroupRSrc(sg.toString());
if (policyManager.useLocalNetpol()) {
vector<shared_ptr<EndPointToLocalSecGroupRSrc> > oldSecGrps;
l2e->resolveEpdrEndPointToLocalSecGroupRSrc(oldSecGrps);
const set<URI>& secGrps = es.endpoint->getSecurityGroups();
for (const shared_ptr<EndPointToLocalSecGroupRSrc>& og :
oldSecGrps) {
optional<URI> targ = og->getTargetURI();
if (!targ || secGrps.find(targ.get()) == secGrps.end())
og->remove();
}
for (const URI& sg : secGrps) {
l2e->addEpdrEndPointToLocalSecGroupRSrc(sg.toString());
}
} else {
vector<shared_ptr<EndPointToSecGroupRSrc> > oldSecGrps;
l2e->resolveEpdrEndPointToSecGroupRSrc(oldSecGrps);
const set<URI>& secGrps = es.endpoint->getSecurityGroups();
for (const shared_ptr<EndPointToSecGroupRSrc>& og :
oldSecGrps) {
optional<URI> targ = og->getTargetURI();
if (!targ || secGrps.find(targ.get()) == secGrps.end())
og->remove();
}
for (const URI& sg : secGrps) {
l2e->addEpdrEndPointToSecGroupRSrc(sg.toString());
}
}

const optional<URI>& qosPol =
Expand Down Expand Up @@ -1007,13 +1022,33 @@ static URI formSecGroupURI (SecurityGroupContext& sgc) {
.build();
}

/* Form the URI of local secGroup from the given security group.
* This is needed since we want to generate URI without the EPR prefixes of the EP */
static URI formLocalSecGroupURI (SecurityGroupContext& sgc) {
optional<const string&> sgOpt = sgc.getSecGroup();
if (!sgOpt)
return URIBuilder().build();
const auto& sg = sgOpt.get();
size_t spaceStart = sg.find("PolicySpace") + 12;
size_t gsgStart = sg.rfind("GbpLocalSecGroup");
size_t nameStart = gsgStart + 17;
return URIBuilder()
.addElement("PolicyUniverse")
.addElement("PolicySpace")
.addElement(sg.substr(spaceStart, gsgStart-spaceStart-1))
.addElement("GbpLocalSecGroup")
.addElement(sg.substr(nameStart, sg.size()-nameStart-1))
.build();
}

static shared_ptr<modelgbp::epr::L2Ep>
populateL2E(shared_ptr<modelgbp::epr::L2Universe>& l2u,
shared_ptr<const Endpoint>& ep,
const string& uuid,
shared_ptr<modelgbp::gbp::BridgeDomain>& bd,
const URI& egURI,
const set<URI>& secGroups) {
const set<URI>& secGroups,
bool localNetpolEnabled) {
using namespace modelgbp::gbp;
using namespace modelgbp::gbpe;
using namespace modelgbp::epr;
Expand All @@ -1028,7 +1063,8 @@ populateL2E(shared_ptr<modelgbp::epr::L2Universe>& l2u,
vector<shared_ptr<SecurityGroupContext> > outSGC;
l2e->resolveEprSecurityGroupContext(outSGC);
for (auto &sgc : outSGC) {
auto sgURI = formSecGroupURI(*sgc);
auto sgURI = localNetpolEnabled ? formLocalSecGroupURI(*sgc)
: formSecGroupURI(*sgc);
if (secGroups.find(sgURI) == secGroups.end())
sgc->remove();
}
Expand Down Expand Up @@ -1073,7 +1109,8 @@ populateL3E(shared_ptr<modelgbp::epr::L3Universe>& l3u,
shared_ptr<modelgbp::gbp::RoutingDomain>& rd,
const string& ip,
const URI& egURI,
const set<URI>& secGroups) {
const set<URI>& secGroups,
bool localNetpolEnabled) {
using namespace modelgbp::gbp;
using namespace modelgbp::epr;

Expand All @@ -1087,7 +1124,8 @@ populateL3E(shared_ptr<modelgbp::epr::L3Universe>& l3u,
vector<shared_ptr<SecurityGroupContext> > outSGC;
l3e->resolveEprSecurityGroupContext(outSGC);
for (auto &sgc : outSGC) {
auto sgURI = formSecGroupURI(*sgc);
auto sgURI = localNetpolEnabled ? formLocalSecGroupURI(*sgc)
: formSecGroupURI(*sgc);
if (secGroups.find(sgURI) == secGroups.end())
sgc->remove();
}
Expand Down Expand Up @@ -1132,7 +1170,8 @@ bool EndpointManager::updateEndpointReg(const string& uuid) {
{
shared_ptr<L2Ep> l2e =
populateL2E(l2u.get(), es.endpoint, uuid,
bd.get(), egURI.get(), secGroups);
bd.get(), egURI.get(), secGroups,
policyManager.useLocalNetpol());

newl2eps.insert(l2e->getURI());
}
Expand All @@ -1152,7 +1191,8 @@ bool EndpointManager::updateEndpointReg(const string& uuid) {
shared_ptr<L2Ep> fl2e =
populateL2E(l2u.get(), es.endpoint, ipm.getUUID(), fbd.get(),
ipm.getEgURI().get(),
secGroups);
secGroups,
policyManager.useLocalNetpol());
newl2eps.insert(fl2e->getURI());
}
}
Expand All @@ -1171,7 +1211,8 @@ bool EndpointManager::updateEndpointReg(const string& uuid) {
shared_ptr<L3Ep> l3e =
populateL3E(l3u.get(), es.endpoint, uuid,
rd.get(), ip, egURI.get(),
secGroups);
secGroups,
policyManager.useLocalNetpol());
newl3eps.insert(l3e->getURI());
}

Expand All @@ -1192,7 +1233,8 @@ bool EndpointManager::updateEndpointReg(const string& uuid) {
populateL3E(l3u.get(), es.endpoint, ipm.getUUID(),
frd.get(), ipm.getFloatingIP().get(),
ipm.getEgURI().get(),
secGroups);
secGroups,
policyManager.useLocalNetpol());
newl3eps.insert(fl3e->getURI());
}
}
Expand Down
24 changes: 17 additions & 7 deletions agent-ovs/lib/FSEndpointSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,23 @@ void FSEndpointSource::updated(const fs::path& filePath) {
optional<string> secGrpName =
v.second.get_optional<string>(SEC_GROUP_NAME);
if (secGrpName && secGrpPS) {
newep.addSecurityGroup(opflex::modb::URIBuilder()
.addElement("PolicyUniverse")
.addElement("PolicySpace")
.addElement(secGrpPS.get())
.addElement("GbpSecGroup")
.addElement(secGrpName.get())
.build());
if (manager->getAgent().getPolicyManager().useLocalNetpol()) {
newep.addSecurityGroup(opflex::modb::URIBuilder()
.addElement("PolicyUniverse")
.addElement("PolicySpace")
.addElement(secGrpPS.get())
.addElement("GbpLocalSecGroup")
.addElement(secGrpName.get())
.build());
} else {
newep.addSecurityGroup(opflex::modb::URIBuilder()
.addElement("PolicyUniverse")
.addElement("PolicySpace")
.addElement(secGrpPS.get())
.addElement("GbpSecGroup")
.addElement(secGrpName.get())
.build());
}
}
}
}
Expand Down
98 changes: 98 additions & 0 deletions agent-ovs/lib/FSNetpolSource.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* -*- C++ -*-; c-basic-offset: 4; indent-tabs-mode: nil */
/*
* Implementation for FSNetpolSource class.
*
* Copyright (c) 2024 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if defined(HAVE_SYS_INOTIFY_H) && defined(HAVE_SYS_EVENTFD_H)
#define USE_INOTIFY
#endif

#include <stdexcept>
#include <sstream>
#include <boost/algorithm/string/predicate.hpp>

#include <opflexagent/FSNetpolSource.h>
#include <opflexagent/logging.h>

namespace opflexagent {

using boost::optional;
namespace fs = boost::filesystem;
using std::string;
using std::runtime_error;

FSNetpolSource::FSNetpolSource(opflex::ofcore::OFFramework& framework_,
FSWatcher& listener,
const std::string& netpolDir)
: framework(framework_) {
LOG(INFO) << "Watching " << netpolDir << " for netpol data";
listener.addWatch(netpolDir, *this);
}

static bool isnetpol(fs::path filePath) {
string fstr = filePath.filename().string();
return (boost::algorithm::ends_with(fstr, ".netpol") &&
!boost::algorithm::starts_with(fstr, "."));
}

void FSNetpolSource::updated(const fs::path& filePath) {
if (!isnetpol(filePath)) return;

try {
string pathstr = filePath.string();
netpol_map_t::const_iterator it = knownNetpols.find(pathstr);
if (it != knownNetpols.end()) {
deleted(filePath);
}
opflex::modb::mointernal::StoreClient::notif_t notifs;
size_t n =
framework.updateMOs(pathstr, opflex::gbp::PolicyUpdateOp::REPLACE, &notifs);
knownNetpols[pathstr] = notifs;

LOG(INFO) << "Updated Netpol " << filePath.stem()
<< " from " << filePath
<< " ( " << n << " Objects )";
} catch (const std::exception& ex) {
LOG(ERROR) << "Could not load netpol from: "
<< filePath << ": "
<< ex.what();
} catch (...) {
LOG(ERROR) << "Unknown error while loading netpol "
<< "information from "
<< filePath;
}
}

void FSNetpolSource::deleted(const fs::path& filePath) {
try {
string pathstr = filePath.string();
netpol_map_t::iterator it = knownNetpols.find(pathstr);
if (it != knownNetpols.end()) {

framework.deleteMOs(it->second);
LOG(INFO) << "Removed netpol-uuid "
<< filePath.stem()
<< " at " << filePath
<< " ( " << it->second.size() << " Objects )";
knownNetpols.erase(it);
}
} catch (const std::exception& ex) {
LOG(ERROR) << "Could not delete netpol for "
<< filePath << ": "
<< ex.what();
} catch (...) {
LOG(ERROR) << "Unknown error while deleting netpol information for "
<< filePath;
}
}

} /* namespace opflexagent */
Loading

0 comments on commit c027360

Please sign in to comment.