Fix a small memory leak and adjusted the code style.
Resolves: RHEL-24810 Signed-off-by: Mohammad Heib <mheib@redhat.com>
This commit is contained in:
parent
795b55d53b
commit
2534e21c62
File diff suppressed because it is too large
Load Diff
688
0001-issue-4223310-VMA-support-for-kernel-6.10.patch
Normal file
688
0001-issue-4223310-VMA-support-for-kernel-6.10.patch
Normal file
@ -0,0 +1,688 @@
|
||||
From 1849e0ad10acf3430d21193a8fc9ca3f12e976a9 Mon Sep 17 00:00:00 2001
|
||||
From: Tomer Cabouly <tcabouly@nvidia.com>
|
||||
Date: Mon, 13 Jan 2025 09:13:58 +0000
|
||||
Subject: issue: 4223310 VMA support for kernel 6.10
|
||||
|
||||
Kernel 6.10 netlink has breaked VMA functionality.
|
||||
Transitioned to libnl - an abstraction that wraps netlink.
|
||||
|
||||
Signed-off-by: Tomer Cabouly <tcabouly@nvidia.com>
|
||||
---
|
||||
src/vma/proto/netlink_socket_mgr.h | 204 ++++++++++-------------------
|
||||
src/vma/proto/route_table_mgr.cpp | 143 ++++++++++----------
|
||||
src/vma/proto/route_table_mgr.h | 4 +-
|
||||
src/vma/proto/rule_table_mgr.cpp | 98 +++++++-------
|
||||
src/vma/proto/rule_table_mgr.h | 4 +-
|
||||
src/vma/proto/rule_val.cpp | 3 -
|
||||
src/vma/proto/rule_val.h | 6 -
|
||||
7 files changed, 198 insertions(+), 264 deletions(-)
|
||||
|
||||
diff --git a/src/vma/proto/netlink_socket_mgr.h b/src/vma/proto/netlink_socket_mgr.h
|
||||
index ab14de05..c576721c 100644
|
||||
--- a/src/vma/proto/netlink_socket_mgr.h
|
||||
+++ b/src/vma/proto/netlink_socket_mgr.h
|
||||
@@ -35,6 +35,7 @@
|
||||
#ifndef NETLINK_SOCKET_MGR_H
|
||||
#define NETLINK_SOCKET_MGR_H
|
||||
|
||||
+#include <cstddef>
|
||||
#include <unistd.h>
|
||||
#include <bits/sockaddr.h>
|
||||
#include <stdio.h>
|
||||
@@ -49,6 +50,11 @@
|
||||
#include <netinet/ether.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
+#include <netlink/netlink.h>
|
||||
+#include <netlink/msg.h>
|
||||
+#include <netlink/route/route.h>
|
||||
+#include <netlink/route/rule.h>
|
||||
+#include <netlink/route/link.h>
|
||||
|
||||
#include "utils/bullseye.h"
|
||||
#include "utils/lock_wrapper.h"
|
||||
@@ -97,19 +103,19 @@ protected:
|
||||
|
||||
table_t m_tab;
|
||||
|
||||
- virtual bool parse_enrty(nlmsghdr *nl_header, Type *p_val) = 0;
|
||||
+ virtual bool parse_entry(struct nl_object *nl_obj, void *p_val_context) = 0;
|
||||
virtual void update_tbl();
|
||||
virtual void print_val_tbl();
|
||||
|
||||
void build_request(struct nlmsghdr **nl_msg);
|
||||
bool query(struct nlmsghdr *&nl_msg, int &len);
|
||||
int recv_info();
|
||||
- void parse_tbl(int len, int *p_ent_num = NULL);
|
||||
+ void parse_tbl_from_latest_cache(struct nl_cache *cache_state);
|
||||
|
||||
private:
|
||||
nl_data_t m_data_type;
|
||||
|
||||
- int m_fd; // netlink socket to communicate with the kernel
|
||||
+ nl_sock *m_sock; // netlink socket to communicate with the kernel
|
||||
uint32_t m_pid; // process pid
|
||||
uint32_t m_seq_num; // seq num of the netlink messages
|
||||
char m_msg_buf[MSG_BUFF_SIZE]; // we use this buffer for sending/receiving netlink messages
|
||||
@@ -118,6 +124,7 @@ private:
|
||||
|
||||
/*********************************Implementation ********************************/
|
||||
|
||||
+
|
||||
template <typename Type>
|
||||
netlink_socket_mgr <Type>::netlink_socket_mgr(nl_data_t data_type)
|
||||
{
|
||||
@@ -132,14 +139,19 @@ netlink_socket_mgr <Type>::netlink_socket_mgr(nl_data_t data_type)
|
||||
|
||||
// Create Socket
|
||||
BULLSEYE_EXCLUDE_BLOCK_START
|
||||
- if ((m_fd = orig_os_api.socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
|
||||
+ m_sock = nl_socket_alloc();
|
||||
+ if (m_sock == nullptr) {
|
||||
__log_err("NL socket Creation: ");
|
||||
return;
|
||||
}
|
||||
|
||||
- if (orig_os_api.fcntl(m_fd, F_SETFD, FD_CLOEXEC) != 0) {
|
||||
- __log_warn("Fail in fctl, error = %d", errno);
|
||||
+ if (nl_connect(m_sock, NETLINK_ROUTE) < 0) {
|
||||
+ __log_err("NL socket Connection: ");
|
||||
+ nl_socket_free(m_sock);
|
||||
+ m_sock = nullptr;
|
||||
+ return;
|
||||
}
|
||||
+
|
||||
BULLSEYE_EXCLUDE_BLOCK_END
|
||||
|
||||
__log_dbg("Done");
|
||||
@@ -149,161 +161,79 @@ template <typename Type>
|
||||
netlink_socket_mgr <Type>::~netlink_socket_mgr()
|
||||
{
|
||||
__log_dbg("");
|
||||
- if (m_fd) {
|
||||
- orig_os_api.close(m_fd);
|
||||
- m_fd = -1;
|
||||
+ if (m_sock != nullptr) {
|
||||
+ nl_socket_free(m_sock);
|
||||
+ m_sock = nullptr;
|
||||
}
|
||||
-
|
||||
- __log_dbg("Done");
|
||||
-}
|
||||
-
|
||||
-// This function build Netlink request to retrieve data (Rule, Route) from kernel.
|
||||
-// Parameters :
|
||||
-// nl_msg : request to be returned
|
||||
-template <typename Type>
|
||||
-void netlink_socket_mgr <Type>::build_request(struct nlmsghdr **nl_msg)
|
||||
-{
|
||||
- struct rtmsg *rt_msg;
|
||||
-
|
||||
- memset(m_msg_buf, 0, m_buff_size);
|
||||
-
|
||||
- // point the header and the msg structure pointers into the buffer
|
||||
- *nl_msg = (struct nlmsghdr *)m_msg_buf;
|
||||
- rt_msg = (struct rtmsg *)NLMSG_DATA(*nl_msg);
|
||||
-
|
||||
- //Fill in the nlmsg header
|
||||
- (*nl_msg)->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
||||
- (*nl_msg)->nlmsg_seq = m_seq_num++;
|
||||
- (*nl_msg)->nlmsg_pid = m_pid;
|
||||
- rt_msg->rtm_family = AF_INET;
|
||||
-
|
||||
- if (m_data_type == RULE_DATA_TYPE)
|
||||
- {
|
||||
- (*nl_msg)->nlmsg_type = RTM_GETRULE;
|
||||
- }
|
||||
- else if (m_data_type == ROUTE_DATA_TYPE)
|
||||
- {
|
||||
- (*nl_msg)->nlmsg_type = RTM_GETROUTE;
|
||||
- }
|
||||
-
|
||||
- (*nl_msg)->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
|
||||
-
|
||||
-}
|
||||
-
|
||||
-// Query built request and receive requested data (Rule, Route)
|
||||
-// Parameters:
|
||||
-// nl_msg : request that is built previously.
|
||||
-// len : length of received data.
|
||||
-template <typename Type>
|
||||
-bool netlink_socket_mgr <Type>::query(struct nlmsghdr *&nl_msg, int &len)
|
||||
-{
|
||||
- if(m_fd < 0)
|
||||
- return false;
|
||||
-
|
||||
- BULLSEYE_EXCLUDE_BLOCK_START
|
||||
- if(orig_os_api.send(m_fd, nl_msg, nl_msg->nlmsg_len, 0) < 0){
|
||||
- __log_err("Write To Socket Failed...\n");
|
||||
- return false;
|
||||
- }
|
||||
- if((len = recv_info()) < 0) {
|
||||
- __log_err("Read From Socket Failed...\n");
|
||||
- return false;
|
||||
- }
|
||||
- BULLSEYE_EXCLUDE_BLOCK_END
|
||||
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-// Receive requested data and save it locally.
|
||||
-// Return length of received data.
|
||||
-template <typename Type>
|
||||
-int netlink_socket_mgr <Type>::recv_info()
|
||||
-{
|
||||
- struct nlmsghdr *nlHdr;
|
||||
- int readLen = 0, msgLen = 0;
|
||||
-
|
||||
- char *buf_ptr = m_msg_buf;
|
||||
-
|
||||
- do{
|
||||
- //Receive response from the kernel
|
||||
- BULLSEYE_EXCLUDE_BLOCK_START
|
||||
- if((readLen = orig_os_api.recv(m_fd, buf_ptr, MSG_BUFF_SIZE - msgLen, 0)) < 0){
|
||||
- __log_err("SOCK READ: ");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- nlHdr = (struct nlmsghdr *)buf_ptr;
|
||||
-
|
||||
- //Check if the header is valid
|
||||
- if((NLMSG_OK(nlHdr, (u_int)readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR))
|
||||
- {
|
||||
- __log_err("Error in received packet, readLen = %d, msgLen = %d, type=%d, bufLen = %d", readLen, nlHdr->nlmsg_len, nlHdr->nlmsg_type, MSG_BUFF_SIZE);
|
||||
- if (nlHdr->nlmsg_len == MSG_BUFF_SIZE) {
|
||||
- __log_err("The buffer we pass to netlink is too small for reading the whole table");
|
||||
- }
|
||||
- return -1;
|
||||
- }
|
||||
- BULLSEYE_EXCLUDE_BLOCK_END
|
||||
-
|
||||
- buf_ptr += readLen;
|
||||
- msgLen += readLen;
|
||||
-
|
||||
- //Check if the its the last message
|
||||
- if(nlHdr->nlmsg_type == NLMSG_DONE ||
|
||||
- (nlHdr->nlmsg_flags & NLM_F_MULTI) == 0) {
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- } while((nlHdr->nlmsg_seq != m_seq_num) || (nlHdr->nlmsg_pid != m_pid));
|
||||
- return msgLen;
|
||||
+ __log_dbg("Done");
|
||||
}
|
||||
|
||||
// Update data in a table
|
||||
template <typename Type>
|
||||
void netlink_socket_mgr <Type>::update_tbl()
|
||||
{
|
||||
- struct nlmsghdr *nl_msg = NULL;
|
||||
- int counter = 0;
|
||||
- int len = 0;
|
||||
-
|
||||
m_tab.entries_num = 0;
|
||||
|
||||
- // Build Netlink request to get route entry
|
||||
- build_request(&nl_msg);
|
||||
+ struct nl_cache *cache_state = nullptr;
|
||||
+ int err = 0;
|
||||
|
||||
- // Query built request and receive requested data
|
||||
- if (!query(nl_msg, len))
|
||||
- return;
|
||||
+ // cache allocation fetches the latest existing rules/routes
|
||||
+ if (m_data_type == RULE_DATA_TYPE) {
|
||||
+ err = rtnl_rule_alloc_cache(m_sock, AF_INET, &cache_state);
|
||||
+ } else if (m_data_type == ROUTE_DATA_TYPE) {
|
||||
+ err = rtnl_route_alloc_cache(m_sock, AF_INET, 0, &cache_state);
|
||||
+ }
|
||||
|
||||
- // Parse received data in custom object (route_val)
|
||||
- parse_tbl(len, &counter);
|
||||
+ if (err < 0) {
|
||||
+ if (cache_state) {
|
||||
+ nl_cache_free(cache_state);
|
||||
+ }
|
||||
+
|
||||
+ throw_vma_exception("Failed to allocate route cache");
|
||||
+ }
|
||||
|
||||
- m_tab.entries_num = counter;
|
||||
+ // Parse received data in custom object (route_val)
|
||||
+ parse_tbl_from_latest_cache(cache_state);
|
||||
|
||||
- if (counter >= MAX_TABLE_SIZE) {
|
||||
- __log_warn("reached the maximum route table size");
|
||||
+ if (cache_state) {
|
||||
+ nl_cache_free(cache_state);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse received data in a table
|
||||
-// Parameters:
|
||||
+// Parameters:
|
||||
// len : length of received data.
|
||||
// p_ent_num : number of rows in received data.
|
||||
template <typename Type>
|
||||
-void netlink_socket_mgr <Type>::parse_tbl(int len, int *p_ent_num)
|
||||
+void netlink_socket_mgr<Type>::parse_tbl_from_latest_cache(struct nl_cache *cache_state)
|
||||
{
|
||||
- struct nlmsghdr *nl_header;
|
||||
- int entry_cnt = 0;
|
||||
+ uint16_t entry_cnt = 0;
|
||||
+
|
||||
+ struct nl_iterator_context {
|
||||
+ Type *p_val_array;
|
||||
+ uint16_t &entry_cnt;
|
||||
+ netlink_socket_mgr<Type> *this_ptr;
|
||||
+ } iterator_context = {m_tab.value, entry_cnt, this};
|
||||
+
|
||||
+ // a lambda can't be casted to a c-fptr with ref captures - so we provide context ourselves
|
||||
+ nl_cache_foreach(
|
||||
+ cache_state,
|
||||
+ [](struct nl_object *nl_obj, void *context) {
|
||||
+ nl_iterator_context *operation_context =
|
||||
+ reinterpret_cast<nl_iterator_context *>(context);
|
||||
+ const bool is_valid_entry = operation_context->this_ptr->parse_entry(
|
||||
+ nl_obj, operation_context->p_val_array + operation_context->entry_cnt);
|
||||
+ if (is_valid_entry) {
|
||||
+ ++operation_context->entry_cnt;
|
||||
+ }
|
||||
+ },
|
||||
+ &iterator_context);
|
||||
|
||||
- nl_header = (struct nlmsghdr *) m_msg_buf;
|
||||
- for(;NLMSG_OK(nl_header, (u_int)len) && entry_cnt < MAX_TABLE_SIZE; nl_header = NLMSG_NEXT(nl_header, len))
|
||||
- {
|
||||
- if (parse_enrty(nl_header, &m_tab.value[entry_cnt])) {
|
||||
- entry_cnt++;
|
||||
- }
|
||||
+ m_tab.entries_num = entry_cnt;
|
||||
+ if (m_tab.entries_num >= MAX_TABLE_SIZE) {
|
||||
+ __log_warn("reached the maximum route table size");
|
||||
}
|
||||
- if (p_ent_num)
|
||||
- *p_ent_num = entry_cnt;
|
||||
}
|
||||
|
||||
//print the table
|
||||
diff --git a/src/vma/proto/route_table_mgr.cpp b/src/vma/proto/route_table_mgr.cpp
|
||||
index bb97320f..45af9a8d 100644
|
||||
--- a/src/vma/proto/route_table_mgr.cpp
|
||||
+++ b/src/vma/proto/route_table_mgr.cpp
|
||||
@@ -235,87 +235,98 @@ void route_table_mgr::rt_mgr_update_source_ip()
|
||||
}
|
||||
}
|
||||
|
||||
-bool route_table_mgr::parse_enrty(nlmsghdr *nl_header, route_val *p_val)
|
||||
+bool route_table_mgr::parse_entry(struct nl_object *nl_obj, void *p_val_context)
|
||||
{
|
||||
- int len;
|
||||
- struct rtmsg *rt_msg;
|
||||
- struct rtattr *rt_attribute;
|
||||
-
|
||||
- // get route entry header
|
||||
- rt_msg = (struct rtmsg *) NLMSG_DATA(nl_header);
|
||||
+ route_val *p_val = static_cast<route_val *>(p_val_context);
|
||||
+ // Cast the generic nl_object to a specific route or rule object
|
||||
+ struct rtnl_route *route = reinterpret_cast<struct rtnl_route *>(nl_obj);
|
||||
|
||||
// we are not concerned about the local and default route table
|
||||
- if (rt_msg->rtm_family != AF_INET || rt_msg->rtm_table == RT_TABLE_LOCAL)
|
||||
+ if (rtnl_route_get_family(route) != AF_INET || rtnl_route_get_table(route) == RT_TABLE_LOCAL) {
|
||||
return false;
|
||||
+ }
|
||||
|
||||
- p_val->set_protocol(rt_msg->rtm_protocol);
|
||||
- p_val->set_scope(rt_msg->rtm_scope);
|
||||
- p_val->set_type(rt_msg->rtm_type);
|
||||
- p_val->set_table_id(rt_msg->rtm_table);
|
||||
-
|
||||
- in_addr_t dst_mask = htonl(VMA_NETMASK(rt_msg->rtm_dst_len));
|
||||
- p_val->set_dst_mask(dst_mask);
|
||||
- p_val->set_dst_pref_len(rt_msg->rtm_dst_len);
|
||||
+ // Set protocol, scope, type, and table ID using libnl functions
|
||||
+ p_val->set_protocol(rtnl_route_get_protocol(route));
|
||||
+ p_val->set_scope(rtnl_route_get_scope(route));
|
||||
+ p_val->set_type(rtnl_route_get_type(route));
|
||||
+ p_val->set_table_id(rtnl_route_get_table(route));
|
||||
+
|
||||
+ // Set destination mask and prefix length
|
||||
+ struct nl_addr *dst = rtnl_route_get_dst(route);
|
||||
+ if (dst != nullptr) {
|
||||
+ in_addr_t dst_mask = htonl(VMA_NETMASK(nl_addr_get_prefixlen(dst)));
|
||||
+ p_val->set_dst_mask(dst_mask);
|
||||
+ p_val->set_dst_pref_len(nl_addr_get_prefixlen(dst));
|
||||
+ }
|
||||
|
||||
- len = RTM_PAYLOAD(nl_header);
|
||||
- rt_attribute = (struct rtattr *) RTM_RTA(rt_msg);
|
||||
+ parse_attr(route, p_val);
|
||||
|
||||
- for (;RTA_OK(rt_attribute, len);rt_attribute=RTA_NEXT(rt_attribute,len)) {
|
||||
- parse_attr(rt_attribute, p_val);
|
||||
- }
|
||||
p_val->set_state(true);
|
||||
p_val->set_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
-void route_table_mgr::parse_attr(struct rtattr *rt_attribute, route_val *p_val)
|
||||
+static inline bool get_addr_from_nl_addr(struct nl_addr *addr, in_addr_t *p_addr)
|
||||
{
|
||||
- switch (rt_attribute->rta_type) {
|
||||
- case RTA_DST:
|
||||
- p_val->set_dst_addr(*(in_addr_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
- // next hop IPv4 address
|
||||
- case RTA_GATEWAY:
|
||||
- p_val->set_gw(*(in_addr_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
- // unique ID associated with the network interface
|
||||
- case RTA_OIF:
|
||||
- p_val->set_if_index(*(int *)RTA_DATA(rt_attribute));
|
||||
- char if_name[IFNAMSIZ];
|
||||
- if_indextoname(p_val->get_if_index(),if_name);
|
||||
- p_val->set_if_name(if_name);
|
||||
- break;
|
||||
- case RTA_SRC:
|
||||
- case RTA_PREFSRC:
|
||||
- p_val->set_src_addr(*(in_addr_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
- case RTA_TABLE:
|
||||
- p_val->set_table_id(*(uint32_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
- case RTA_METRICS:
|
||||
- {
|
||||
- struct rtattr *rta = (struct rtattr *)RTA_DATA(rt_attribute);
|
||||
- int len = RTA_PAYLOAD(rt_attribute);
|
||||
- uint16_t type;
|
||||
- while (RTA_OK(rta, len)) {
|
||||
- type = rta->rta_type;
|
||||
- switch (type) {
|
||||
- case RTAX_MTU:
|
||||
- p_val->set_mtu(*(uint32_t *)RTA_DATA(rta));
|
||||
- break;
|
||||
- default:
|
||||
- rt_mgr_logdbg("got unexpected METRICS %d %x",
|
||||
- type, *(uint32_t *)RTA_DATA(rta));
|
||||
- break;
|
||||
- }
|
||||
- rta = RTA_NEXT(rta, len);
|
||||
+ if (addr && nl_addr_get_family(addr) == AF_INET) {
|
||||
+ void *binary_addr = nl_addr_get_binary_addr(addr);
|
||||
+ unsigned int addr_len = nl_addr_get_len(addr);
|
||||
+
|
||||
+ if (binary_addr && addr_len == sizeof(in_addr_t)) {
|
||||
+ memcpy(p_addr, binary_addr, sizeof(in_addr_t));
|
||||
+ return true;
|
||||
}
|
||||
- break;
|
||||
}
|
||||
- default:
|
||||
- rt_mgr_logdbg("got unexpected type %d %x", rt_attribute->rta_type,
|
||||
- *(uint32_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+void route_table_mgr::parse_attr(struct rtnl_route *route, route_val *p_val)
|
||||
+{
|
||||
+ struct nl_addr *addr;
|
||||
+
|
||||
+ // Destination Address
|
||||
+ addr = rtnl_route_get_dst(route);
|
||||
+ in_addr_t dst_addr = 0;
|
||||
+ if (get_addr_from_nl_addr(addr, &dst_addr) && dst_addr) {
|
||||
+ p_val->set_dst_addr(dst_addr);
|
||||
+ }
|
||||
+
|
||||
+ // Gateway Address (Next Hop)
|
||||
+ struct rtnl_nexthop *nh = rtnl_route_nexthop_n(route, 0); // Assuming the first nexthop
|
||||
+ in_addr_t gw_addr = 0;
|
||||
+ if (nh && get_addr_from_nl_addr(rtnl_route_nh_get_gateway(nh), &gw_addr) && gw_addr) {
|
||||
+ p_val->set_gw(gw_addr);
|
||||
+ }
|
||||
+
|
||||
+ // Output Interface Index and Name
|
||||
+ const int if_index = rtnl_route_nh_get_ifindex(nh);
|
||||
+ if (if_index > 0) {
|
||||
+ p_val->set_if_index(if_index);
|
||||
+
|
||||
+ char if_name[IFNAMSIZ] = {0};
|
||||
+ if_indextoname(if_index, if_name);
|
||||
+ p_val->set_if_name(if_name);
|
||||
+ }
|
||||
+
|
||||
+ // Source Address
|
||||
+ addr = rtnl_route_get_pref_src(route);
|
||||
+ in_addr_t pref_src_addr = 0;
|
||||
+ if (get_addr_from_nl_addr(addr, &pref_src_addr) && pref_src_addr) {
|
||||
+ p_val->set_src_addr(pref_src_addr);
|
||||
+ }
|
||||
+
|
||||
+ // Table ID
|
||||
+ int table_id = rtnl_route_get_table(route);
|
||||
+ p_val->set_table_id(table_id);
|
||||
+
|
||||
+ // Metrics (e.g., MTU)
|
||||
+ uint32_t mtu = 0;
|
||||
+ int get_metric_result = rtnl_route_get_metric(route, RTAX_MTU, &mtu);
|
||||
+ if (get_metric_result == 0) {
|
||||
+ if (mtu > 0) {
|
||||
+ p_val->set_mtu(mtu);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/vma/proto/route_table_mgr.h b/src/vma/proto/route_table_mgr.h
|
||||
index ea68bf76..2798498f 100644
|
||||
--- a/src/vma/proto/route_table_mgr.h
|
||||
+++ b/src/vma/proto/route_table_mgr.h
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
virtual void notify_cb(event *ev);
|
||||
|
||||
protected:
|
||||
- virtual bool parse_enrty(nlmsghdr *nl_header, route_val *p_val);
|
||||
+ virtual bool parse_entry(struct nl_object *nl_obj, void *p_val_context);
|
||||
|
||||
private:
|
||||
// in constructor creates route_entry for each net_dev, to receive events in case there are no other route_entrys
|
||||
@@ -80,7 +80,7 @@ private:
|
||||
|
||||
// save current main rt table
|
||||
void update_tbl();
|
||||
- void parse_attr(struct rtattr *rt_attribute, route_val *p_val);
|
||||
+ void parse_attr(struct rtnl_route *route, route_val *p_val);
|
||||
|
||||
void rt_mgr_update_source_ip();
|
||||
|
||||
diff --git a/src/vma/proto/rule_table_mgr.cpp b/src/vma/proto/rule_table_mgr.cpp
|
||||
index ea417654..6c341cc2 100644
|
||||
--- a/src/vma/proto/rule_table_mgr.cpp
|
||||
+++ b/src/vma/proto/rule_table_mgr.cpp
|
||||
@@ -94,74 +94,76 @@ void rule_table_mgr::update_tbl()
|
||||
}
|
||||
|
||||
// Parse received rule entry into custom object (rule_val).
|
||||
-// Parameters:
|
||||
-// nl_header : object that contain rule entry.
|
||||
+// Parameters:
|
||||
+// nl_obj : object that contain rule entry.
|
||||
// p_val : custom object that contain parsed rule data.
|
||||
// return true if its not related to local or default table, false otherwise.
|
||||
-bool rule_table_mgr::parse_enrty(nlmsghdr *nl_header, rule_val *p_val)
|
||||
+bool rule_table_mgr::parse_entry(struct nl_object *nl_obj, void *p_val_context)
|
||||
{
|
||||
- int len;
|
||||
- struct rtmsg *rt_msg;
|
||||
- struct rtattr *rt_attribute;
|
||||
-
|
||||
- // get rule entry header
|
||||
- rt_msg = (struct rtmsg *) NLMSG_DATA(nl_header);
|
||||
+ rule_val *p_val = static_cast<rule_val *>(p_val_context);
|
||||
+ // Cast the generic nl_object to a specific route or rule object
|
||||
+ struct rtnl_rule *rule = reinterpret_cast<struct rtnl_rule *>(nl_obj);
|
||||
|
||||
- // we are not concerned about the local and default rule table
|
||||
- if (rt_msg->rtm_family != AF_INET || rt_msg->rtm_table == RT_TABLE_LOCAL)
|
||||
+ uint32_t table_id = rtnl_rule_get_table(rule);
|
||||
+ if (rtnl_rule_get_family(rule) != AF_INET || table_id == RT_TABLE_LOCAL) {
|
||||
return false;
|
||||
+ }
|
||||
|
||||
- p_val->set_protocol(rt_msg->rtm_protocol);
|
||||
- p_val->set_scope(rt_msg->rtm_scope);
|
||||
- p_val->set_type(rt_msg->rtm_type);
|
||||
- p_val->set_tos(rt_msg->rtm_tos);
|
||||
- p_val->set_table_id(rt_msg->rtm_table);
|
||||
+ p_val->set_tos(rtnl_rule_get_dsfield(rule));
|
||||
+ p_val->set_table_id(table_id);
|
||||
|
||||
- len = RTM_PAYLOAD(nl_header);
|
||||
- rt_attribute = (struct rtattr *) RTM_RTA(rt_msg);
|
||||
+ parse_attr(rule, p_val);
|
||||
|
||||
- for (;RTA_OK(rt_attribute, len);rt_attribute=RTA_NEXT(rt_attribute,len)) {
|
||||
- parse_attr(rt_attribute, p_val);
|
||||
- }
|
||||
p_val->set_state(true);
|
||||
p_val->set_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parse received rule attribute for given rule.
|
||||
-// Parameters:
|
||||
-// rt_attribute : object that contain rule attribute.
|
||||
+// Parameters:
|
||||
+// rule : object that contain rule attribute.
|
||||
// p_val : custom object that contain parsed rule data.
|
||||
-void rule_table_mgr::parse_attr(struct rtattr *rt_attribute, rule_val *p_val)
|
||||
+void rule_table_mgr::parse_attr(struct rtnl_rule *rule, rule_val *p_val)
|
||||
{
|
||||
- switch (rt_attribute->rta_type) {
|
||||
- case FRA_PRIORITY:
|
||||
- p_val->set_priority(*(uint32_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
- case FRA_DST:
|
||||
- p_val->set_dst_addr(*(in_addr_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
- case FRA_SRC:
|
||||
- p_val->set_src_addr(*(in_addr_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
- case FRA_IFNAME:
|
||||
- p_val->set_iif_name((char *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
- case FRA_TABLE:
|
||||
- p_val->set_table_id(*(uint32_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
+ // FRA_PRIORITY: Rule Priority
|
||||
+ uint32_t priority = rtnl_rule_get_prio(rule);
|
||||
+ if (priority) {
|
||||
+ p_val->set_priority(priority);
|
||||
+ }
|
||||
+
|
||||
+ // FRA_DST: Destination Address
|
||||
+ struct nl_addr *dst = rtnl_rule_get_dst(rule);
|
||||
+ if (dst) {
|
||||
+ p_val->set_dst_addr(*(in_addr_t *)nl_addr_get_binary_addr(dst));
|
||||
+ }
|
||||
+
|
||||
+ // FRA_SRC: Source Address
|
||||
+ struct nl_addr *src = rtnl_rule_get_src(rule);
|
||||
+ if (src) {
|
||||
+ p_val->set_src_addr(*(in_addr_t *)nl_addr_get_binary_addr(src));
|
||||
+ }
|
||||
+
|
||||
+ // FRA_IFNAME: Input Interface Name
|
||||
+ char *iif_name = rtnl_rule_get_iif(rule);
|
||||
+ if (iif_name) {
|
||||
+ p_val->set_iif_name(iif_name);
|
||||
+ }
|
||||
+
|
||||
+ // FRA_TABLE: Table ID
|
||||
+ uint32_t table_id = rtnl_rule_get_table(rule);
|
||||
+ if (table_id) {
|
||||
+ p_val->set_table_id(table_id);
|
||||
+ }
|
||||
+
|
||||
#if DEFINED_FRA_OIFNAME
|
||||
- case FRA_OIFNAME:
|
||||
- p_val->set_oif_name((char *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
-#endif
|
||||
- default:
|
||||
- rr_mgr_logdbg("got undetected rta_type %d %x", rt_attribute->rta_type, *(uint32_t *)RTA_DATA(rt_attribute));
|
||||
- break;
|
||||
+ // FRA_OIFNAME: Output Interface Name (if available)
|
||||
+ char *oif_name = rtnl_rule_get_oif(rule);
|
||||
+ if (oif_name) {
|
||||
+ p_val->set_oif_name(oif_name);
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
|
||||
-
|
||||
// Create rule entry object for given destination key and fill it with matching rule value from rule table.
|
||||
// Parameters:
|
||||
// key : key object that contain information about destination.
|
||||
diff --git a/src/vma/proto/rule_table_mgr.h b/src/vma/proto/rule_table_mgr.h
|
||||
index 74d6be40..273675a4 100644
|
||||
--- a/src/vma/proto/rule_table_mgr.h
|
||||
+++ b/src/vma/proto/rule_table_mgr.h
|
||||
@@ -55,12 +55,12 @@ public:
|
||||
bool rule_resolve(route_rule_table_key key, std::deque<uint32_t> &table_id_list);
|
||||
|
||||
protected:
|
||||
- virtual bool parse_enrty(nlmsghdr *nl_header, rule_val *p_val);
|
||||
+ virtual bool parse_entry(struct nl_object *nl_obj, void *p_val_context);
|
||||
virtual void update_tbl();
|
||||
|
||||
private:
|
||||
|
||||
- void parse_attr(struct rtattr *rt_attribute, rule_val *p_val);
|
||||
+ void parse_attr(struct rtnl_rule *rule, rule_val *p_val);
|
||||
|
||||
bool find_rule_val(route_rule_table_key key, std::deque<rule_val*>* &p_val);
|
||||
bool is_matching_rule(route_rule_table_key rrk, rule_val* p_val);
|
||||
diff --git a/src/vma/proto/rule_val.cpp b/src/vma/proto/rule_val.cpp
|
||||
index 23309d22..1be700a0 100644
|
||||
--- a/src/vma/proto/rule_val.cpp
|
||||
+++ b/src/vma/proto/rule_val.cpp
|
||||
@@ -47,9 +47,6 @@
|
||||
|
||||
rule_val::rule_val(): cache_observer()
|
||||
{
|
||||
- m_protocol = 0;
|
||||
- m_scope = 0;
|
||||
- m_type = 0;
|
||||
m_dst_addr = 0;
|
||||
m_src_addr = 0;
|
||||
memset(m_oif_name, 0, IFNAMSIZ * sizeof(char));
|
||||
diff --git a/src/vma/proto/rule_val.h b/src/vma/proto/rule_val.h
|
||||
index 7340c765..58bdd71a 100644
|
||||
--- a/src/vma/proto/rule_val.h
|
||||
+++ b/src/vma/proto/rule_val.h
|
||||
@@ -53,9 +53,6 @@ public:
|
||||
|
||||
inline void set_dst_addr(in_addr_t const &dst_addr) { m_dst_addr = dst_addr; };
|
||||
inline void set_src_addr(in_addr_t const &src_addr) { m_src_addr = src_addr; };
|
||||
- inline void set_protocol(unsigned char protocol) { m_protocol = protocol; };
|
||||
- inline void set_scope(unsigned char scope) { m_scope = scope; };
|
||||
- inline void set_type(unsigned char type) { m_type = type; };
|
||||
inline void set_tos(unsigned char tos) { m_tos = tos; };
|
||||
inline void set_table_id(uint32_t table_id) { m_table_id = table_id; };
|
||||
inline void set_iif_name(char *iif_name) { memcpy(m_iif_name, iif_name, IFNAMSIZ); };
|
||||
@@ -79,9 +76,6 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
- unsigned char m_protocol;
|
||||
- unsigned char m_scope;
|
||||
- unsigned char m_type;
|
||||
unsigned char m_tos;
|
||||
|
||||
union {
|
||||
--
|
||||
2.47.1
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
Name: libvma
|
||||
Version: 9.8.60
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Summary: A library for boosting TCP and UDP traffic (over RDMA hardware)
|
||||
|
||||
License: GPLv2 or BSD
|
||||
Url: https://github.com/Mellanox/libvma
|
||||
Source0: https://github.com/Mellanox/libvma/archive/%{version}/%{name}-%{version}.tar.gz
|
||||
Patch0: 0001-Fix-build-failure.patch
|
||||
Patch1: 0001-Issue-4223310-VMA-support-for-kernel-6.10.patch
|
||||
Patch1: 0001-issue-4223310-VMA-support-for-kernel-6.10.patch
|
||||
|
||||
# libvma currently supports only the following architectures
|
||||
ExclusiveArch: x86_64 ppc64le ppc64 aarch64
|
||||
@ -101,6 +101,10 @@ rm -f $RPM_BUILD_ROOT/%{_sysconfdir}/init.d/vma
|
||||
%{_mandir}/man8/vma_stats.*
|
||||
|
||||
%changelog
|
||||
* Tue Jan 14 2025 Mohammad Heib <mheib@redhat.com> - 9.8.60-3
|
||||
- Fix a small memory leak and adjusted the code style.
|
||||
Resolves: RHEL-24810
|
||||
|
||||
* Mon Jan 06 2025 Mohammad Heib <mheib@redhat.com> - 9.8.60-2
|
||||
- Add support for kernel 6.10.
|
||||
Resolves: RHEL-24810
|
||||
|
Loading…
Reference in New Issue
Block a user