Skip to content

Commit

Permalink
LRU delete API
Browse files Browse the repository at this point in the history
Summary: Thrift API and corresponding `katranadm lru delete` command to delete given 5-tuple from all per-cpu LRU maps.

Reviewed By: lima1756

Differential Revision: D69325191

fbshipit-source-id: 8f96757b1734a50f53fde83b3b5dbb50d2e35779
  • Loading branch information
avasylev authored and facebook-github-bot committed Feb 11, 2025
1 parent 71da95d commit 63d39e2
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 28 deletions.
111 changes: 83 additions & 28 deletions katran/lib/KatranLb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2295,34 +2295,11 @@ KatranLb::LruEntries KatranLb::searchLru(
uint16_t srcPort) {
LruEntries lruEntries;

flow_key key = {};

auto vip = folly::IPAddress::tryFromString(dstVip.address);
if (!vip) {
LOG(ERROR) << "Invalid vip address: " << dstVip.address;
auto maybeKey = flowKeyFromParams(dstVip, srcIp, srcPort);
if (!maybeKey) {
return lruEntries;
}
auto beAddr = IpHelpers::parseAddrToBe(*vip);
if (vip->isV4()) {
key.dst = beAddr.daddr;
} else {
memcpy(key.dstv6, beAddr.v6daddr, sizeof(key.dstv6));
}
key.port16[1] = htons(dstVip.port);

auto src = folly::IPAddress::tryFromString(srcIp);
if (!src) {
LOG(ERROR) << "Invalid src address: " << srcIp;
return lruEntries;
}
auto beSrcAddr = IpHelpers::parseAddrToBe(*src);
if (src->isV4()) {
key.src = beSrcAddr.daddr;
} else {
memcpy(key.srcv6, beSrcAddr.v6daddr, sizeof(key.srcv6));
}
key.port16[0] = htons(srcPort);
key.proto = dstVip.proto;
flow_key key = *maybeKey;

for (int cpu = 0; cpu < lruMapsFd_.size(); cpu++) {
int mapFd = lruMapsFd_[cpu];
Expand All @@ -2347,10 +2324,10 @@ KatranLb::LruEntries KatranLb::searchLru(
LOG(ERROR) << "LRU fallback cache map not found";
}

int64_t current_time_ns = BpfAdapter::getKtimeNs();
int64_t currentTimeNs = BpfAdapter::getKtimeNs();
for (auto& entry : lruEntries) {
if (entry.atime > 0) {
entry.atime_delta_sec = (current_time_ns - entry.atime) / 1000000000;
entry.atime_delta_sec = (currentTimeNs - entry.atime) / 1000000000;
}
}
return lruEntries;
Expand Down Expand Up @@ -2384,6 +2361,84 @@ std::optional<KatranLb::LruEntry> KatranLb::lookupLruMap(
return entry;
}

std::optional<flow_key> KatranLb::flowKeyFromParams(
const VipKey& dstVip,
const std::string& srcIp,
uint16_t srcPort) {
flow_key key = {};

auto vip = folly::IPAddress::tryFromString(dstVip.address);
if (!vip) {
LOG(ERROR) << "Invalid vip address: " << dstVip.address;
return std::nullopt;
}
auto beAddr = IpHelpers::parseAddrToBe(*vip);
if (vip->isV4()) {
key.dst = beAddr.daddr;
} else {
memcpy(key.dstv6, beAddr.v6daddr, sizeof(key.dstv6));
}
key.port16[1] = htons(dstVip.port);

auto src = folly::IPAddress::tryFromString(srcIp);
if (!src) {
LOG(ERROR) << "Invalid src address: " << srcIp;
return std::nullopt;
}
auto beSrcAddr = IpHelpers::parseAddrToBe(*src);
if (src->isV4()) {
key.src = beSrcAddr.daddr;
} else {
memcpy(key.srcv6, beSrcAddr.v6daddr, sizeof(key.srcv6));
}
key.port16[0] = htons(srcPort);
key.proto = dstVip.proto;
return key;
}

std::vector<std::string> KatranLb::deleteLru(
const VipKey& dstVip,
const std::string& srcIp,
uint16_t srcPort) {
std::vector<std::string> mapsWithDeletions;
auto maybeKey = flowKeyFromParams(dstVip, srcIp, srcPort);
if (!maybeKey) {
return mapsWithDeletions;
}
flow_key key = *maybeKey;
for (int cpu = 0; cpu < lruMapsFd_.size(); cpu++) {
int mapFd = lruMapsFd_[cpu];
if (mapFd <= 0) {
continue;
}
int res = bpfAdapter_->bpfMapDeleteElement(mapFd, &key);
if (res == 0) {
mapsWithDeletions.push_back("cpu" + std::to_string(cpu));
} else {
if (errno != ENOENT) {
// ENOENT is expected in case there is no entry in the lru map
LOG(ERROR) << "Error while querying lru map: " << errno;
}
}
}

int fallbackMapFd = bpfAdapter_->getMapFdByName("fallback_cache");
if (fallbackMapFd > 0) {
int res = bpfAdapter_->bpfMapDeleteElement(fallbackMapFd, &key);
if (res == 0) {
mapsWithDeletions.push_back("fallback");
} else {
if (errno != ENOENT) {
// ENOENT is expected in case there is no entry in the lru map
LOG(ERROR) << "Error while querying lru map: " << errno;
}
}
} else {
LOG(ERROR) << "LRU fallback cache map not found";
}
return mapsWithDeletions;
}

bool KatranLb::updateVipMap(
const ModifyAction action,
const VipKey& vip,
Expand Down
12 changes: 12 additions & 0 deletions katran/lib/KatranLb.h
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,13 @@ class KatranLb {
LruEntries
searchLru(const VipKey& dstVip, const std::string& srcIp, uint16_t srcPort);

/*
* Delete given 5 tuple from all per-CPU and fallback LRU maps.
* Returns list of maps where the entry was deleted.
*/
std::vector<std::string>
deleteLru(const VipKey& dstVip, const std::string& srcIp, uint16_t srcPort);

/**
* @param src ip address of the src
* @return true is the update is successful
Expand Down Expand Up @@ -1088,6 +1095,11 @@ class KatranLb {

std::optional<LruEntry> lookupLruMap(int mapFd, flow_key& key);

static std::optional<flow_key> flowKeyFromParams(
const VipKey& dstVip,
const std::string& srcIp,
uint16_t srcPort);

/**
* main configurations of katran
*/
Expand Down

0 comments on commit 63d39e2

Please sign in to comment.