example/KatranSimpleServiceHandler.cpp (287 lines of code) (raw):

/* Copyright (C) 2018-present, Facebook, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "KatranSimpleServiceHandler.h" #include <cstdint> #include "katran/lib/MacHelpers.h" namespace lb { namespace katran { using Guard = std::lock_guard<std::mutex>; // some helper for most common translations ::katran::VipKey translateVipObject(const Vip& vip) { ::katran::VipKey vk; vk.address = vip.address; vk.port = vip.port; vk.proto = vip.protocol; return vk; } ::katran::NewReal translateRealObject(const Real& real) { ::katran::NewReal nr; nr.address = real.address; nr.weight = real.weight; nr.flags = real.flags; return nr; } ::katran::QuicReal translateQuicRealObject(const QuicReal& real) { ::katran::QuicReal qr; qr.address = real.address; qr.id = real.id; return qr; } KatranSimpleServiceHandler::KatranSimpleServiceHandler( const ::katran::KatranConfig& config) : lb_(config), hcForwarding_(config.enableHc) { lb_.loadBpfProgs(); lb_.attachBpfProgs(); } bool KatranSimpleServiceHandler::changeMac( std::unique_ptr<::lb::katran::Mac> newMac) { Guard lock(giant_); auto mac = ::katran::convertMacToUint(newMac->mac); return lb_.changeMac(mac); } void KatranSimpleServiceHandler::getMac(::lb::katran::Mac& _return) { Guard lock(giant_); auto mac = lb_.getMac(); _return.mac = ::katran::convertMacToString(mac); return; } bool KatranSimpleServiceHandler::addVip( std::unique_ptr<::lb::katran::VipMeta> vipMeta) { bool res; auto vk = translateVipObject(vipMeta->vip); try { Guard lock(giant_); res = lb_.addVip(vk, vipMeta->flags); } catch (const std::exception& e) { LOG(INFO) << "Exception while adding new vip: " << e.what(); res = false; } return res; } bool KatranSimpleServiceHandler::delVip( std::unique_ptr<::lb::katran::Vip> vip) { auto vk = translateVipObject(*vip.get()); Guard lock(giant_); return lb_.delVip(vk); } void KatranSimpleServiceHandler::getAllVips( std::vector<::lb::katran::Vip>& _return) { lb::katran::Vip vip; Guard lock(giant_); auto vips = lb_.getAllVips(); for (auto& v : vips) { vip.address = v.address; vip.port = v.port; vip.protocol = v.proto; _return.push_back(vip); } return; } bool KatranSimpleServiceHandler::modifyVip( std::unique_ptr<::lb::katran::VipMeta> vipMeta) { auto vk = translateVipObject(vipMeta->vip); Guard lock(giant_); return lb_.modifyVip(vk, vipMeta->flags, vipMeta->setFlag); } bool KatranSimpleServiceHandler::modifyReal( std::unique_ptr<::lb::katran::RealMeta> realMeta) { Guard lock(giant_); return lb_.modifyReal(realMeta->address, realMeta->flags, realMeta->setFlag); } int64_t KatranSimpleServiceHandler::getVipFlags( std::unique_ptr<::lb::katran::Vip> vip) { int64_t flags = -1; auto vk = translateVipObject(*vip.get()); try { Guard lock(giant_); flags = lb_.getVipFlags(vk); } catch (const std::exception& e) { LOG(INFO) << "Exception while getting flags for vip" << e.what(); } return flags; } bool KatranSimpleServiceHandler::addRealForVip( std::unique_ptr<::lb::katran::Real> real, std::unique_ptr<::lb::katran::Vip> vip) { bool res; auto vk = translateVipObject(*vip.get()); auto nr = translateRealObject(*real.get()); try { Guard lock(giant_); res = lb_.addRealForVip(nr, vk); } catch (const std::exception& e) { res = false; } return res; } bool KatranSimpleServiceHandler::delRealForVip( std::unique_ptr<::lb::katran::Real> real, std::unique_ptr<::lb::katran::Vip> vip) { auto vk = translateVipObject(*vip.get()); auto nr = translateRealObject(*real.get()); Guard lock(giant_); return lb_.delRealForVip(nr, vk); } bool KatranSimpleServiceHandler::modifyRealsForVip( ::lb::katran::Action action, std::unique_ptr<::lb::katran::Reals> reals, std::unique_ptr<::lb::katran::Vip> vip) { ::katran::ModifyAction a; std::vector<::katran::NewReal> nreals; bool res; switch (action) { case Action::ADD: a = ::katran::ModifyAction::ADD; break; case Action::DEL: a = ::katran::ModifyAction::DEL; break; } auto vk = translateVipObject(*vip.get()); for (auto& real : *reals.get()) { auto nr = translateRealObject(real); nreals.push_back(nr); } try { Guard lock(giant_); res = lb_.modifyRealsForVip(a, nreals, vk); } catch (const std::exception& e) { LOG(INFO) << "Exception while modifying vip: " << e.what(); res = false; } return res; } void KatranSimpleServiceHandler::getRealsForVip( ::lb::katran::Reals& _return, std::unique_ptr<::lb::katran::Vip> vip) { Real r; std::vector<::katran::NewReal> reals; auto vk = translateVipObject(*vip.get()); try { Guard lock(giant_); reals = lb_.getRealsForVip(vk); } catch (const std::exception& e) { LOG(INFO) << "Exception while getting reals from vip: " << e.what(); return; } for (auto& real : reals) { r.address = real.address; r.weight = real.weight; r.flags = real.flags; _return.push_back(r); } return; } bool KatranSimpleServiceHandler::modifyQuicRealsMapping( ::lb::katran::Action action, std::unique_ptr<::lb::katran::QuicReals> reals) { ::katran::ModifyAction a; std::vector<::katran::QuicReal> qreals; bool res{true}; switch (action) { case Action::ADD: a = ::katran::ModifyAction::ADD; break; case Action::DEL: a = ::katran::ModifyAction::DEL; break; } for (auto& real : *reals) { auto qr = translateQuicRealObject(real); qreals.push_back(qr); } try { Guard lock(giant_); lb_.modifyQuicRealsMapping(a, qreals); } catch (const std::exception& e) { LOG(INFO) << "Exception while modifying quic real: " << e.what(); res = false; } return res; } void KatranSimpleServiceHandler::getQuicRealsMapping( ::lb::katran::QuicReals& _return) { QuicReal qr; std::vector<::katran::QuicReal> qreals; try { Guard lock(giant_); qreals = lb_.getQuicRealsMapping(); } catch (const std::exception& e) { LOG(INFO) << "Exception while getting reals from vip: " << e.what(); return; } for (auto& real : qreals) { qr.address = real.address; qr.id = real.id; _return.push_back(qr); } return; } void KatranSimpleServiceHandler::getStatsForVip( ::lb::katran::Stats& _return, std::unique_ptr<::lb::katran::Vip> vip) { auto vk = translateVipObject(*vip.get()); Guard lock(giant_); auto stats = lb_.getStatsForVip(vk); _return.v1 = stats.v1; _return.v2 = stats.v2; } void KatranSimpleServiceHandler::getLruStats(::lb::katran::Stats& _return) { Guard lock(giant_); auto stats = lb_.getLruStats(); _return.v1 = stats.v1; _return.v2 = stats.v2; } void KatranSimpleServiceHandler::getLruMissStats(::lb::katran::Stats& _return) { Guard lock(giant_); auto stats = lb_.getLruMissStats(); _return.v1 = stats.v1; _return.v2 = stats.v2; } void KatranSimpleServiceHandler::getLruFallbackStats( ::lb::katran::Stats& _return) { Guard lock(giant_); auto stats = lb_.getLruFallbackStats(); _return.v1 = stats.v1; _return.v2 = stats.v2; } void KatranSimpleServiceHandler::getIcmpTooBigStats( ::lb::katran::Stats& _return) { Guard lock(giant_); auto stats = lb_.getIcmpTooBigStats(); _return.v1 = stats.v1; _return.v2 = stats.v2; } bool KatranSimpleServiceHandler::addHealthcheckerDst( std::unique_ptr<::lb::katran::Healthcheck> healthcheck) { if (!hcForwarding_) { return false; } bool res; try { Guard lock(giant_); res = lb_.addHealthcheckerDst(healthcheck->somark, healthcheck->address); } catch (const std::exception& e) { LOG(INFO) << "Exception while adding healthcheck: " << e.what(); res = false; } return res; } bool KatranSimpleServiceHandler::delHealthcheckerDst(int32_t somark) { if (!hcForwarding_) { return false; } Guard lock(giant_); return lb_.delHealthcheckerDst(somark); } void KatranSimpleServiceHandler::getHealthcheckersDst( ::lb::katran::hcMap& _return) { if (!hcForwarding_) { return; } Guard lock(giant_); auto hcs = lb_.getHealthcheckersDst(); for (auto& hc : hcs) { _return[hc.first] = hc.second; } return; } } // namespace katran } // namespace lb