g_xsk.push_back(socket);
return socket;
});
+ luaCtx.registerFunction<std::string(std::shared_ptr<XskSocket>::*)()const>("getMetrics", [](const std::shared_ptr<XskSocket>& xsk) {
+ std::string result;
+ if (!xsk) {
+ return result;
+ }
+ return xsk->getMetrics();
+ });
#endif /* HAVE_XSK */
/* EDNSOptionView */
luaCtx.registerFunction<size_t(EDNSOptionView::*)()const>("count", [](const EDNSOptionView& option) {
}
}
+std::string XskSocket::getMetrics() const
+{
+ struct xdp_statistics stats;
+ socklen_t optlen = sizeof(stats);
+ int err = getsockopt(xskFd(), SOL_XDP, XDP_STATISTICS, &stats, &optlen);
+ if (err) {
+ return "";
+ }
+ if (optlen != sizeof(struct xdp_statistics)) {
+ return "";
+ }
+
+ ostringstream ret;
+ ret << "RX dropped: " << std::to_string(stats.rx_dropped) << std::endl;
+ ret << "RX invalid descs: " << std::to_string(stats.rx_invalid_descs) << std::endl;
+ ret << "TX invalid descs: " << std::to_string(stats.tx_invalid_descs) << std::endl;
+ ret << "RX ring full: " << std::to_string(stats.rx_ring_full) << std::endl;
+ ret << "RX fill ring empty descs: " << std::to_string(stats.rx_fill_ring_empty_descs) << std::endl;
+ ret << "RX ring empty descs: " << std::to_string(stats.tx_ring_empty_descs) << std::endl;
+ return ret.str();
+}
+
XskSocket::XskUmem::~XskUmem()
{
if (umem) {
// look at incoming packets in rx, return them if parsing succeeeded
std::vector<XskPacketPtr> recv(uint32_t recvSizeMax, uint32_t* failedCount);
void addWorker(std::shared_ptr<XskWorker> s, const ComboAddress& dest, bool isTCP);
+ std::string getMetrics() const;
};
class XskPacket
{