example/KatranSimpleServer.cpp (95 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 <signal.h> #include <memory> #include <vector> #include <folly/Conv.h> #include <folly/String.h> #include <folly/init/Init.h> #include <gflags/gflags.h> #include <thrift/lib/cpp2/server/ThriftServer.h> #include "KatranSimpleServiceHandler.h" #include "KatranSimpleServiceSignalHandler.h" #include "katran/lib/MacHelpers.h" using apache::thrift::ThriftServer; using lb::katran::KatranSimpleServiceHandler; DEFINE_int32(port, 12307, "Service port"); DEFINE_int32(thriftMaxRequests, 50000, "Maximum number of active requests"); DEFINE_bool(thriftEnableCodel, true, "Enable Codel queuing timeout"); DEFINE_int32(num_io_threads, 1, "number of IO threads for thrift server"); DEFINE_string(intf, "eth0", "main interface"); DEFINE_string(ipip_intf, "ipip0", "ipip (v4) encap interface"); DEFINE_string(ipip6_intf, "ipip60", "ip(6)ip6 (v6) encap interface"); DEFINE_string(balancer_prog, "./balancer_kern.o", "path to balancer bpf prog"); DEFINE_string( healthchecker_prog, "./healthchecking_ipip.o", "path to healthchecking bpf prog"); DEFINE_string( default_mac, "00:00:00:00:00:01", "mac address of default router. must be in fomrat: xx:xx:xx:xx:xx:xx"); DEFINE_int32(priority, 2307, "tc's priority for bpf progs"); DEFINE_string( map_path, "", "path to pinned map from root xdp prog." " default path forces to work in standalone mode"); DEFINE_int32(prog_pos, 2, "katran's position inside root xdp array"); DEFINE_bool(hc_forwarding, true, "turn on forwarding path for healthchecks"); DEFINE_int32(shutdown_delay, 10000, "shutdown delay in milliseconds"); DEFINE_int64(lru_size, 8000000, "size of LRU table"); DEFINE_string(forwarding_cores, "", "coma separed list of forwarding cores"); DEFINE_string( numa_nodes, "", "coma separed list of numa nodes to forwarding cores mapping"); // routine which parses coma separated string of numbers // (e.g. "1,2,3,4,10,11,12,13") to vector of int32_t // will throw on failure. std::vector<int32_t> parseIntLine(const std::string& line) { std::vector<int32_t> nums; if (!line.empty()) { std::vector<std::string> splitedLine; folly::split(",", line, splitedLine); for (const auto& num_str : splitedLine) { auto num = folly::to<int32_t>(num_str); nums.push_back(num); } } return nums; } int main(int argc, char** argv) { folly::init(&argc, &argv); FLAGS_logtostderr = 1; auto forwardingCores = parseIntLine(FLAGS_forwarding_cores); VLOG(2) << "size of forwarding cores vector is " << forwardingCores.size(); auto numaNodes = parseIntLine(FLAGS_numa_nodes); VLOG(2) << "size of numa nodes vector is " << numaNodes.size(); katran::KatranConfig config = { .mainInterface = FLAGS_intf, .v4TunInterface = FLAGS_ipip_intf, .v6TunInterface = FLAGS_ipip6_intf, .balancerProgPath = FLAGS_balancer_prog, .healthcheckingProgPath = FLAGS_healthchecker_prog, .defaultMac = ::katran::convertMacToUint(FLAGS_default_mac), .priority = static_cast<uint32_t>(FLAGS_priority), .rootMapPath = FLAGS_map_path, .rootMapPos = static_cast<uint32_t>(FLAGS_prog_pos), .enableHc = FLAGS_hc_forwarding, }; config.LruSize = static_cast<uint64_t>(FLAGS_lru_size); config.forwardingCores = forwardingCores; config.numaNodes = numaNodes; auto handler = std::make_shared<KatranSimpleServiceHandler>(config); auto server = std::make_shared<ThriftServer>(); server->setMaxRequests(FLAGS_thriftMaxRequests); server->setEnableCodel(FLAGS_thriftEnableCodel); server->setPort(FLAGS_port); server->setInterface(handler); server->setNumIOWorkerThreads(FLAGS_num_io_threads); LOG(INFO) << "Katran running on port: " << FLAGS_port; // Signal handler lb::katran::KatranSimpleServiceSignalHandler sigHandler( server->getEventBaseManager()->getEventBase(), server.get(), FLAGS_shutdown_delay); sigHandler.registerSignalHandler(SIGINT); sigHandler.registerSignalHandler(SIGTERM); server->serve(); return 0; }