After the experiment environment is set up on opensuse, continue the experiment of the kernel module. This is a simple network address translation (NAT ).
On the Server Load balancer (LB), change the destination address of the data packet (SKB) whose destination address is 192.168.99.102 to 192.168.99.101.
No connection tracking, no change of the original address returned by 192.168.99.101 to 192.168.99.102, everything is simplified!
Only Ping can be used for experiments.
1. Source Code: simpnat. c
# Include <Linux/kernel. h>
# Include <Linux/tcp. h>/* For tcphdr */
# Include <net/IP. h>
# Include <net/tcp. h>/* For csum_tcpudp_magic */
# Include <net/udp. h>
# Include <net/ICMP. h>/* For icmp_send */
# Include <net/route. h>/* For ip_route_output */
# Include <net/release 6.h>
# Include <net/ip6_route.h>
# Include <Linux/icmpv6.h>
# Include <Linux/netfilter. h>
# Include <Linux/netfilter_00004.h>
# Include <net/ip_vs.h>
Module_license ("GPL ");
/* This is the structure we shall use to register our function */
Static struct nf_hook_ops nfho;
/* IP address we want to Nat */
Static unsigned char * nat_ip = "/xc0/xA8/x63/X65";/* 192.168.99.101 */
Static unsigned char * org_ip = "/xc0/xA8/x63/x66";/* 192.168.99.102 */
/* This is the hook function itself */
Unsigned int hook_func (unsigned int hooknum,
Struct sk_buff * SKB,
Const struct net_device * In,
Const struct net_device * Out,
INT (* okfn) (struct sk_buff *))
{
Struct sk_buff * sb = SKB;
Struct iphdr * IPH;
If (! SB) return nf_accept;
IPH = ip_hdr (SB );
If (! IPH) return nf_accept;
If (IPH-> daddr = * (unsigned int *) org_ip ){
IPH-> daddr = * (unsigned int *) nat_ip;
Ip_send_check (IPH );
SKB-> local_df = 1;
Printk ("NAT: % d. % d to: % d. % d/N ",
* Org_ip, * (org_ip + 1), * (org_ip + 2), * (org_ip + 3 ),
* Nat_ip, * (nat_ip + 1), * (nat_ip + 2), * (nat_ip + 3 ));
Return nf_accept;
} Else {
Printk ("not Nat this IP/N ");
Return nf_accept;
}
}
/* Initialisation routine */
Int init_module ()
{
/* Fill in our hook structure */
Nfho. Hook = hook_func;/* Handler function */
Nfho. hooknum = nf_inet_pre_routing;/* First hook for IPv4 */
Nfho. pF = pf_inet;
Nfho. Priority = nf_ip_pri_first;/* Make Our function first */
Nf_register_hook (& nfho );
Pr_info ("simpnat install into kernel! /N ");
Return 0;
}
/* Cleanup routine */
Void cleanup_module ()
{
Nf_unregister_hook (& nfho );
Pr_info ("simpnat removed from kernel! /N ");
}
2. makefile:
OBJ-M + = simpnat. o
ALL:
Make-C/lib/modules/'uname-R'/build M = 'pwd'
Clean:
Make-C/lib/modules/'uname-R'/build M = 'pwd' clean
Install:
/Sbin/insmod simpnat. Ko
Remove:
/Sbin/rmmod simpnat
3. Compile:
Make
4. Installation module:
Make install
5. test:
5.1 On the client
Ping 192.168.99.102
The following words are returned:
Ping vm02 (192.168.99.102) 56 (84) bytes of data.
64 bytes from vm01 (192.168.99.101): icmp_seq = 1 TTL = 63 time = 3.96 MS
64 bytes from vm01 (192.168.99.101): icmp_seq = 2 TTL = 63 time = 0.286 MS
64 bytes from vm01 (192.168.99.101): icmp_seq = 3 TTL = 63 time = 0.271 MS
64 bytes from vm01 (192.168.99.101): icmp_seq = 4 TTL = 63 time = 0.286 MS
64 bytes from vm01 (192.168.99.101): icmp_seq = 5 TTL = 63 time = 0.300 MS
5.2 view/var/log/messages on the server Load balancer (LB) with the following words:
Feb 25 14:47:42 vmlb kernel: [5700.674794] Nat: 192.168.99.102 to: 192.168.99.101
Feb 25 14:47:42 vmlb kernel: [5700.674951] not Nat this IP
Feb 25 14:47:43 vmlb kernel: [5701.674823] Nat: 192.168.99.102 to: 192.168.99.101
Feb 25 14:47:43 vmlb kernel: [5701.674992] not Nat this IP
6. Uninstall the module:
Make remove