LinuxでNetfilterを使用してIPv 4 DFフラグを強制的にクリア
clear ip df kernel module
このモジュールは比較的簡単である、主な目的はGREトンネルを使用する際にデータメッセージ長>GREトンネルMTUのIPv 4
prepare
source
Makefile
このモジュールは比較的簡単である、主な目的はGREトンネルを使用する際にデータメッセージ長>GREトンネルMTUのIPv 4
DF
フラグのメッセージを強制的に分割することである.Linuxはデフォルトでこのようなメッセージを破棄し、直接スライスするのではなく、PMTUDがICMPメッセージに応答するかどうかに基づいて!このモジュールをロードすると、すべてのデータipv 4メッセージに対してDF
フラグが強制的にクリアする.注意:PMTUD機能が有効になっていません.Linux GREトンネルのデフォルトMTU 1476は、DFフラグが設定されていないすべてのメッセージをスライスしてからENCAPをデフォルトで設定します.prepare
yum install gcc makc perl elfutils-libelf-devel kernel-devel kernel-headers
source
#ifdef MODVERSIONS
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include /* for put_user */
#include /* for put_user */
#include "dbg.h"
#define MTU_DST 1400
#define MKIPV4(a,b,c,d) \
(u32)(((__u8)d & 0xFF) << 24 | ((__u8)c & 0xFF) << 16 | ((__u8)b & 0xFF) << 8 | (a & 0xFF))
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 13, 0)
/*
include/linux/netfilter.h
typedef unsigned int nf_hookfn(const struct nf_hook_ops *ops,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
#ifndef __GENKSYMS__
const struct nf_hook_state *state
#else
int (*okfn)(struct sk_buff *)
#endif
);
*/
static unsigned int
nf_ip_input(const struct nf_hook_ops *ops,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
#ifndef __GENKSYMS__
const struct nf_hook_state *state
#else
int (*okfn)(struct sk_buff *)
#endif
)
#else
/*
typedef unsigned int nf_hookfn(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state);
*/
static unsigned int
nf_ip_input(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
#endif
{
struct iphdr *iph = NULL;
iph = ip_hdr(skb);
if (iph->frag_off & __constant_htons(IP_DF)) {
iph->frag_off &= ~(__constant_htons(IP_DF));
iph->check = 0;
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
}
return NF_ACCEPT;
}
static struct nf_hook_ops nf_hook_ops[] __read_mostly = {
{
.hook = nf_ip_input,
#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 0)
.owner = THIS_MODULE,
#endif
.pf = PF_INET,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_FIRST,
},
};
int nf_ip_df_init( void )
{
int err = 0;
pr_notice( "nf_ip_df_init..
" );
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
err = nf_register_net_hook(&init_net, nf_hook_ops);
#else
err = nf_register_hooks(nf_hook_ops, ARRAY_SIZE(nf_hook_ops));
#endif
if (err < 0) {
pr_notice("nf_ip_df_init: can't register hooks.
");
}
pr_emerg( "INT_MIN = %d
", INT_MIN );
pr_info( "ip_mtu: register hooks success.
" );
return err;
}
void nf_ip_df_fini(void)
{
pr_notice( "nf_ip_df_fini..
" );
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
nf_unregister_net_hook(&init_net, nf_hook_ops);
#else
nf_unregister_hooks(nf_hook_ops, ARRAY_SIZE(nf_hook_ops));
#endif
}
module_init(nf_ip_df_init);
module_exit(nf_ip_df_fini);
MODULE_LICENSE( "GPL" );
Makefile
ARCH := x86
KVER := $(shell uname -r)
KSP ?= /lib/modules/$(KVER)/build
#EXTRA_CFLAGS +=-DTEST
obj-m += ip_df.o
all: clean
make -C $(KSP) M=`pwd` modules
clean:
make -C $(KSP) M=`pwd` clean
rm -f Module.symvers
rm -f modules.order
test:
insmod ip_df.ko