This commit is contained in:
yugart 2022-03-30 10:02:20 +00:00 committed by Gitee
parent 8cd12c6a9e
commit ee841df4b2
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
5 changed files with 407 additions and 0 deletions

165
0001-support-arm64.patch Normal file
View File

@ -0,0 +1,165 @@
From 792c1c14d77dc6013ab730fc8d5267ac07864916 Mon Sep 17 00:00:00 2001
From: Jiao Fenfang <jiaofenfang@uniontech.com>
Date: Wed, 26 Jan 2022 14:37:36 +0800
Subject: [PATCH] support arm64
---
src/toa.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
src/toa.h | 2 ++
2 files changed, 87 insertions(+), 8 deletions(-)
diff --git a/src/toa.c b/src/toa.c
index e02ef24..2942674 100644
--- a/src/toa.c
+++ b/src/toa.c
@@ -23,6 +23,50 @@ struct toa_stats_entry toa_stats[] = {
struct toa_stat_mib *ext_stats;
+#if defined(CONFIG_ARM64)
+/*
+ * ARM64 interface
+ * Lookup the page table entry for a virtual address. Return a pointer
+ * to the entry and the level of the mapping.
+ *
+ * Note: We return pud and pmd either when the entry is marked large
+ * or when the present bit is not set. Otherwise we would return a
+ * pointer to a nonexisting mapping.
+ */
+static pte_t *lookup_address(unsigned long address, unsigned int *level)
+{
+ pgd_t *pgdp;
+ pud_t *pudp, pud;
+ pmd_t *pmdp, pmd;
+ pte_t *ptep;
+ unsigned long addr = address;
+
+ unsigned long init_mm = kallsyms_lookup_name("init_mm");
+ if (!init_mm) {
+ TOA_INFO("CPU [%u] lookup_address init_mm null\n", smp_processor_id());
+ return NULL;
+ }
+
+ /*pgdp = pgd_offset_k(addr);*/
+ pgdp = pgd_offset((struct mm_struct *)init_mm, addr);
+ if (pgd_none(READ_ONCE(*pgdp)))
+ return NULL;
+
+ pudp = pud_offset(pgdp, addr);
+ pud = READ_ONCE(*pudp);
+ if (pud_none(pud))
+ return NULL;
+
+ pmdp = pmd_offset(pudp, addr);
+ pmd = READ_ONCE(*pmdp);
+ if (pmd_none(pmd))
+ return NULL;
+
+ ptep = pte_offset_kernel(pmdp, addr);
+ return ptep;
+}
+#endif
+
/*
* Funcs for toa hooks
*/
@@ -304,6 +348,7 @@ hook_toa_functions(void)
/* hook tcp_v4_syn_recv_sock for ipv4 */
struct inet_connection_sock_af_ops *ipv4_specific_p =
(struct inet_connection_sock_af_ops *)&ipv4_specific;
+
#ifdef CONFIG_IP_VS_TOA_IPV6
/* hook inet6_getname for ipv6 */
struct proto_ops *inet6_stream_ops_p =
@@ -316,9 +361,18 @@ hook_toa_functions(void)
pte = lookup_address((unsigned long )inet_stream_ops_p, &level);
if (pte == NULL)
return 1;
- if (pte->pte & ~_PAGE_RW) {
- pte->pte |= _PAGE_RW;
- }
+
+#if defined(CONFIG_ARM64)
+ *pte = pte_mkwrite(*pte);
+ __sync_icache_dcache(*pte);
+ flush_tlb_all();
+#else
+ if (pte->pte & ~_PAGE_RW) {
+ pte->pte |= _PAGE_RW;
+ }
+#endif
+ /*TOA_INFO("CPU [%u] hooked before inet_getname <%p> --> <%p>\n",
+ smp_processor_id(), inet_getname, inet_getname_toa);*/
inet_stream_ops_p->getname = inet_getname_toa;
TOA_INFO("CPU [%u] hooked inet_getname <%p> --> <%p>\n",
@@ -345,7 +399,14 @@ hook_toa_functions(void)
pte = lookup_address((unsigned long )inet_stream_ops_p, &level);
if (pte == NULL)
return 1;
- pte->pte |= pte->pte &~_PAGE_RW;
+
+#if defined(CONFIG_ARM64)
+ *pte = pte_wrprotect(*pte);
+ __sync_icache_dcache(*pte);
+ flush_tlb_all();
+#else
+ pte->pte |= pte->pte &~_PAGE_RW;
+#endif
return 0;
}
@@ -376,9 +437,18 @@ unhook_toa_functions(void)
pte = lookup_address((unsigned long )inet_stream_ops_p, &level);
if (pte == NULL)
return 1;
- if (pte->pte & ~_PAGE_RW) {
- pte->pte |= _PAGE_RW;
- }
+
+#if defined(CONFIG_ARM64)
+ *pte = pte_mkwrite(*pte);
+ __sync_icache_dcache(*pte);
+ flush_tlb_all();
+#else
+ if (pte->pte & ~_PAGE_RW) {
+ pte->pte |= _PAGE_RW;
+ }
+#endif
+ /*TOA_INFO("CPU [%u] unhooked before inet_getname: %p\n",
+ smp_processor_id(), inet_getname);*/
inet_stream_ops_p->getname = inet_getname;
TOA_INFO("CPU [%u] unhooked inet_getname\n",
@@ -403,7 +473,14 @@ unhook_toa_functions(void)
pte = lookup_address((unsigned long )inet_stream_ops_p, &level);
if (pte == NULL)
return 1;
- pte->pte |= pte->pte &~_PAGE_RW;
+
+#if defined(CONFIG_ARM64)
+ *pte = pte_wrprotect(*pte);
+ __sync_icache_dcache(*pte);
+ flush_tlb_all();
+#else
+ pte->pte |= pte->pte &~_PAGE_RW;
+#endif
return 0;
}
diff --git a/src/toa.h b/src/toa.h
index b47fac3..a46f82d 100644
--- a/src/toa.h
+++ b/src/toa.h
@@ -20,6 +20,8 @@
#include <net/ipv6.h>
#include <net/transp_v6.h>
+#include <asm/tlbflush.h>
+
#define TOA_VERSION "1.0.0.0"
#ifdef TOA_DBG_MSG
--
2.20.1

View File

@ -0,0 +1,27 @@
diff --git a/src/Makefile b/src/Makefile
index 155146d..7f61dba 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,15 +4,17 @@
obj-$(CONFIG_TOA) += toa.o
+kerver=$(shell rpm -q kernel-devel --queryformat=%{VERSION}-%{RELEASE}.%{ARCH})
+
default:
- make CONFIG_TOA=m -C /lib/modules/`uname -r`/build M=`pwd` modules
+ make CONFIG_TOA=m -C /lib/modules/${kerver}/build M=`pwd` modules
debug:
- make CONFIG_TOA=m -C /lib/modules/`uname -r`/build M=`pwd` modules EXTRA_CFLAGS="-DTOA_DBG_MSG"
+ make CONFIG_TOA=m -C /lib/modules/${kerver}/build M=`pwd` modules EXTRA_CFLAGS="-DTOA_DBG_MSG"
clean:
rm -f .*.cmd *.o *.ko *.mod.c modules.order Module.symvers
rm -rf .tmp_versions
install:
- test -d "$(DESTDIR)/lib/modules/`uname -r`/extra/net/toa" \
- || mkdir -p "$(DESTDIR)/lib/modules/`uname -r`/extra/net/toa"
- cp *.ko "$(DESTDIR)/lib/modules/`uname -r`/extra/net/toa"
+ test -d "$(DESTDIR)/lib/modules/${kerver}/extra/net/toa" \
+ || mkdir -p "$(DESTDIR)/lib/modules/${kerver}/extra/net/toa"
+ cp *.ko "$(DESTDIR)/lib/modules/${kerver}/extra/net/toa"

107
0003-patch-for-5_10.patch Normal file
View File

@ -0,0 +1,107 @@
diff --git a/src/toa.c b/src/toa.c
index 2942674..82382f9 100644
--- a/src/toa.c
+++ b/src/toa.c
@@ -1,3 +1,4 @@
+#include <linux/kprobes.h>
#include "toa.h"
/*
@@ -7,6 +8,9 @@
unsigned long sk_data_ready_addr = 0;
+typedef unsigned long (*kallsyms_lookup_name_fun_t)(const char *name);
+static kallsyms_lookup_name_fun_t kallsyms_lookup_name_fun;
+
/*
* Statistics of toa in proc /proc/net/toa_stats
*/
@@ -23,6 +27,23 @@ struct toa_stats_entry toa_stats[] = {
struct toa_stat_mib *ext_stats;
+static int toa_get_kallsyms_lookup_name_addr(void)
+{
+ static struct kprobe kp = {
+ .symbol_name = "kallsyms_lookup_name",
+ };
+
+ if (register_kprobe(&kp) < 0)
+ return -1;
+
+ if (!kallsyms_lookup_name_fun) {
+ kallsyms_lookup_name_fun = (kallsyms_lookup_name_fun_t)kp.addr;
+ }
+ unregister_kprobe(&kp);
+
+ return 0;
+}
+
#if defined(CONFIG_ARM64)
/*
* ARM64 interface
@@ -41,7 +62,7 @@ static pte_t *lookup_address(unsigned long address, unsigned int *level)
pte_t *ptep;
unsigned long addr = address;
- unsigned long init_mm = kallsyms_lookup_name("init_mm");
+ unsigned long init_mm = kallsyms_lookup_name_fun("init_mm");
if (!init_mm) {
TOA_INFO("CPU [%u] lookup_address init_mm null\n", smp_processor_id());
return NULL;
@@ -52,7 +73,7 @@ static pte_t *lookup_address(unsigned long address, unsigned int *level)
if (pgd_none(READ_ONCE(*pgdp)))
return NULL;
- pudp = pud_offset(pgdp, addr);
+ pudp = pud_offset((p4d_t *)pgdp, addr);
pud = READ_ONCE(*pudp);
if (pud_none(pud))
return NULL;
@@ -522,6 +543,14 @@ static int toa_stats_seq_open(struct inode *inode, struct file *file)
return single_open(file, toa_stats_show, NULL);
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,5,0)
+static const struct proc_ops toa_stats_fops = {
+ .proc_open = toa_stats_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
+};
+#else
static const struct file_operations toa_stats_fops = {
.owner = THIS_MODULE,
.open = toa_stats_seq_open,
@@ -529,6 +558,7 @@ static const struct file_operations toa_stats_fops = {
.llseek = seq_lseek,
.release = single_release,
};
+#endif
/*
* TOA module init and destory
@@ -538,6 +568,13 @@ static const struct file_operations toa_stats_fops = {
static int __init
toa_init(void)
{
+ int ret = -1;
+
+ ret = toa_get_kallsyms_lookup_name_addr();
+ if (ret < 0) {
+ return 1;
+ }
+
/* alloc statistics array for toa */
ext_stats = alloc_percpu(struct toa_stat_mib);
if (NULL == ext_stats)
@@ -547,7 +584,7 @@ toa_init(void)
/* get the address of function sock_def_readable
* so later we can know whether the sock is for rpc, tux or others
*/
- sk_data_ready_addr = kallsyms_lookup_name("sock_def_readable");
+ sk_data_ready_addr = kallsyms_lookup_name_fun("sock_def_readable");
TOA_INFO("CPU [%u] sk_data_ready_addr = "
"kallsyms_lookup_name(sock_def_readable) = %lu\n",
smp_processor_id(), sk_data_ready_addr);

BIN
TCP_option_address.tar.gz Normal file

Binary file not shown.

108
toa.spec Normal file
View File

@ -0,0 +1,108 @@
%global debug_package %{nil}
# macros for finding system files to update at install time (pci.ids, pcitable)
%define find() %(for f in %*; do if [ -e $f ]; then echo $f; break; fi; done)
Name: TCP_option_address
Summary: Intel(R) Ethernet Adaptive Virtual Function Driver
Version: 1.0.0
Release: 1
#Release: 0.%{krelver}
Vendor: Huawei
License: GPL-2.0
URL: https://github.com/dongzerun/TCP_option_address
Source0: TCP_option_address.tar.gz
Patch0001: 0001-support-arm64.patch
Patch0002: 0002-fix-build-error.patch
Patch0003: 0003-patch-for-5_10.patch
Requires: kernel, findutils, gawk, bash
BuildRequires: kernel-devel hwdata rpm
%description
The TCP Option Address (TOA) module is a kernel module that obtains the source IPv4 address from the option section of a TCP header.
%prep
%autosetup -n %{name} -p1
%build
make -C src clean
make -C src
%install
make -C src DESTDIR=%{buildroot} install
# Remove modules files that we do not want to include
find %{buildroot}/lib/modules/ -name 'modules.*' -exec rm -f {} \;
cd %{buildroot}
find lib -name "toa" \
-fprintf %{_builddir}/%{name}/file.list "/%p\n"
%clean
rm -rf %{buildroot}
%files -f file.list
%defattr(-,root,root)
%doc README.md file.list
%license LICENSE NOTICE
%post
uname -r | grep BOOT || /sbin/depmod -a > /dev/null 2>&1 || true
if which dracut >/dev/null 2>&1; then
echo "Updating initramfs with dracut..."
if dracut --force ; then
echo "Successfully updated initramfs."
else
echo "Failed to update initramfs."
echo "You must update your initramfs image for changes to take place."
exit -1
fi
elif which mkinitrd >/dev/null 2>&1; then
echo "Updating initrd with mkinitrd..."
if mkinitrd; then
echo "Successfully updated initrd."
else
echo "Failed to update initrd."
echo "You must update your initrd image for changes to take place."
exit -1
fi
else
echo "Unable to determine utility to update initrd image."
echo "You must update your initrd manually for changes to take place."
exit -1
fi
%preun
%postun
uname -r | grep BOOT || /sbin/depmod -a > /dev/null 2>&1 || true
if which dracut >/dev/null 2>&1; then
echo "Updating initramfs with dracut..."
if dracut --force ; then
echo "Successfully updated initramfs."
else
echo "Failed to update initramfs."
echo "You must update your initramfs image for changes to take place."
exit -1
fi
elif which mkinitrd >/dev/null 2>&1; then
echo "Updating initrd with mkinitrd..."
if mkinitrd; then
echo "Successfully updated initrd."
else
echo "Failed to update initrd."
echo "You must update your initrd image for changes to take place."
exit -1
fi
else
echo "Unable to determine utility to update initrd image."
echo "You must update your initrd manually for changes to take place."
exit -1
fi
%changelog
* Mon Jan 24 2022 jiaofenfang<jiaofenfang@uniontech.com> - 1.0.0-1
- Package init