diff --git a/0001-support-arm64.patch b/0001-support-arm64.patch new file mode 100644 index 0000000..f0dec88 --- /dev/null +++ b/0001-support-arm64.patch @@ -0,0 +1,165 @@ +From 792c1c14d77dc6013ab730fc8d5267ac07864916 Mon Sep 17 00:00:00 2001 +From: Jiao Fenfang +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 + #include + ++#include ++ + #define TOA_VERSION "1.0.0.0" + + #ifdef TOA_DBG_MSG +-- +2.20.1 + diff --git a/0002-fix-build-error.patch b/0002-fix-build-error.patch new file mode 100644 index 0000000..eca1953 --- /dev/null +++ b/0002-fix-build-error.patch @@ -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" diff --git a/0003-patch-for-5_10.patch b/0003-patch-for-5_10.patch new file mode 100644 index 0000000..2a31afd --- /dev/null +++ b/0003-patch-for-5_10.patch @@ -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 + #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); diff --git a/TCP_option_address.tar.gz b/TCP_option_address.tar.gz new file mode 100644 index 0000000..ec88ef9 Binary files /dev/null and b/TCP_option_address.tar.gz differ diff --git a/toa.spec b/toa.spec new file mode 100644 index 0000000..b098ffc --- /dev/null +++ b/toa.spec @@ -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 elfutils-devel gcc + +%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 - 1.0.0-1 +- Package init