在内核中添加一个MyTCP协议,独立于标准的TCP协议,新的MyTCP协议上下街口与原有系统兼容,上边仍然符合BSD SOCKET接口,下边与标准IP接口进行适配。
实现添加MyTCP协议计划:
1.注册MyTCP协议号,注册MpTCP的传输层协议L3—>L4层之间处理对象structnet_protocol mytcp_ protocol,注册MpTCP的传输层协议L4—>L5层之间处理对象struct proto mytcp_proto,
2.仿照Linux2.6内核中的TCP函数处理代码,把MyTCP对上层对下层的函数接口打通
2.1.学习内核中TCP是如何实现上下连接的。
2.2.为MyTCP设置同样的接口,
2.3.由下层接口向上,上层接口向下,直至实现结合。
3.编写KConfig文件,将MyTCP作为一个内核整体选项编译进入内核。之后可仿照内核设置选项编译。
4.书写Makefile文件。
5.内核编译
6.内核安装运行
7.内核MyTCP接口测试(检测接口是否可以与标准BSDSOCKET接口一致)
协议处理对象涉及数据结构如下:
//L3<->L4
struct net_protocol {
int (*handler)(struct sk_buff*skb);
void (*err_handler)(structsk_buff *skb, u32 info);
int (*gso_send_check)(structsk_buff *skb);
structsk_buff *(*gso_segment)(struct sk_buff *skb,
int features);
structsk_buff **(*gro_receive)(struct sk_buff **head,
struct sk_buff *skb);
int (*gro_complete)(structsk_buff *skb);
unsignedint no_policy:1,
netns_ok:1;
};
static const struct net_protocoltcp_protocol = {
.handler= tcp_v4_rcv,
.err_handler= tcp_v4_err,
.gso_send_check= tcp_v4_gso_send_check,
.gso_segment= tcp_tso_segment,
.gro_receive= tcp4_gro_receive,
.gro_complete= tcp4_gro_complete,
.no_policy= 1,
.netns_ok= 1,
};
//L4<->L5
struct proto {
void (*close)(struct sock *sk,
longtimeout);
int (*connect)(struct sock*sk,
struct sockaddr *uaddr,
intaddr_len);
int (*disconnect)(struct sock*sk, int flags);
structsock * (*accept) (struct sock*sk, int flags, int *err);
int (*ioctl)(struct sock *sk,int cmd,
unsigned long arg);
int (*init)(struct sock *sk);
void (*destroy)(struct sock *sk);
void (*shutdown)(struct sock *sk,int how);
int (*setsockopt)(struct sock*sk, int level,
intoptname, char __user *optval,
unsignedint optlen);
int (*getsockopt)(struct sock*sk, int level,
intoptname, char __user *optval,
int__user *option);
#ifdef CONFIG_COMPAT
int (*compat_setsockopt)(structsock *sk,
intlevel,
intoptname, char __user *optval,
unsignedint optlen);
int (*compat_getsockopt)(structsock *sk,
intlevel,
intoptname, char __user *optval,
int__user *option);
#endif
int (*sendmsg)(struct kiocb*iocb, struct sock *sk,
struct msghdr *msg, size_t len);
int (*recvmsg)(struct kiocb*iocb, struct sock *sk,
struct msghdr *msg,
size_tlen, int noblock, int flags,
int*addr_len);
int (*sendpage)(struct sock*sk, struct page *page,
intoffset, size_t size, int flags);
int (*bind)(struct sock *sk,
structsockaddr *uaddr, int addr_len);
int (*backlog_rcv) (structsock *sk,
structsk_buff *skb);
/*Keeping track of sk's, looking them up, and port selection methods. */
void (*hash)(struct sock *sk);
void (*unhash)(struct sock *sk);
void (*rehash)(struct sock *sk);
int (*get_port)(struct sock*sk, unsigned short snum);
/*Keeping track of sockets in use */
#ifdef CONFIG_PROC_FS
unsignedint inuse_idx;
#endif
/*Memory pressure */
void (*enter_memory_pressure)(structsock *sk);
atomic_long_t *memory_allocated; /* Current allocated memory. */
structpercpu_counter *sockets_allocated; /* Current number of sockets. */
/*
* Pressure flag: try to collapse.
* Technical note: it is used by multiplecontexts non atomically.
* All the __sk_mem_schedule() is of thisnature: accounting
* is strict, actions are advisory and havesome latency.
*/
int *memory_pressure;
long *sysctl_mem;
int *sysctl_wmem;
int *sysctl_rmem;
int max_header;
structkmem_cache *slab;
unsignedint obj_size;
int slab_flags;
structpercpu_counter *orphan_count;
structrequest_sock_ops *rsk_prot;
structtimewait_sock_ops *twsk_prot;
union{
structinet_hashinfo *hashinfo;
structudp_table *udp_table;
structraw_hashinfo *raw_hash;
}h;
structmodule *owner;
char name[32];
structlist_head node;
#ifdef SOCK_REFCNT_DEBUG
atomic_t socks;
#endif
};
struct proto tcp_prot = {
.name = "TCP",
.owner = THIS_MODULE,
.close = tcp_close,
.connect = tcp_v4_connect,
.disconnect = tcp_disconnect,
.accept = inet_csk_accept,
.ioctl = tcp_ioctl,
.init = tcp_v4_init_sock,
.destroy = tcp_v4_destroy_sock,
.shutdown = tcp_shutdown,
.setsockopt = tcp_setsockopt,
.getsockopt = tcp_getsockopt,
.recvmsg = tcp_recvmsg,
.backlog_rcv = tcp_v4_do_rcv,
.hash = inet_hash,
.unhash = inet_unhash,
.get_port = inet_csk_get_port,
.enter_memory_pressure = tcp_enter_memory_pressure,
.sockets_allocated = &tcp_sockets_allocated,
.orphan_count = &tcp_orphan_count,
.memory_allocated = &tcp_memory_allocated,
.memory_pressure = &tcp_memory_pressure,
.sysctl_mem = sysctl_tcp_mem,
.sysctl_wmem = sysctl_tcp_wmem,
.sysctl_rmem = sysctl_tcp_rmem,
.max_header = MAX_TCP_HEADER,
.obj_size = sizeof(struct tcp_sock),
.slab_flags = SLAB_DESTROY_BY_RCU,
.twsk_prot = &tcp_timewait_sock_ops,
.rsk_prot = &tcp_request_sock_ops,
.h.hashinfo = &tcp_hashinfo,
#ifdef CONFIG_COMPAT
.compat_setsockopt = compat_tcp_setsockopt,
.compat_getsockopt = compat_tcp_getsockopt,
#endif
};
static int __init inet_init(void)
{
inet_protosw 数组
proto_register(&tcp_prot, 1);
proto_register(&udp_prot, 1);
proto_register(&raw_prot, 1);
(void)sock_register(&inet_family_ops);
inet_add_protocol(&icmp_protocol,IPPROTO_ICMP);
inet_add_protocol(&udp_protocol,IPPROTO_UDP);
inet_add_protocol(&tcp_protocol,IPPROTO_TCP);
inet_add_protocol(&igmp_protocol,IPPROTO_IGMP);
/* Register the socket-side information forinet_create. */
for (r = &inetsw[0]; r <&inetsw[SOCK_MAX]; ++r)
INIT_LIST_HEAD(r);
for (q = inetsw_array; q <&inetsw_array[INETSW_ARRAY_LEN]; ++q)
inet_register_protosw(q);
arp_init();
ip_init();
tcp_v4_init();
tcp_init();
udp_init();
udplite4_register();
icmp_init();
ip_mr_init();
init_ipv4_mibs();
ipv4_proc_init();
ipfrag_init();
dev_add_pack(&ip_packet_type);
}
const struct proto_ops inet_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
.release =inet_release,
.bind = inet_bind,
.connect =inet_stream_connect,
.socketpair = sock_no_socketpair,
.accept = inet_accept,
.getname =inet_getname,
.poll = tcp_poll,
.ioctl = inet_ioctl,
.listen = inet_listen,
.shutdown = inet_shutdown,
.setsockopt =sock_common_setsockopt,
.getsockopt =sock_common_getsockopt,
.sendmsg =tcp_sendmsg,
.recvmsg =sock_common_recvmsg,
.mmap = sock_no_mmap,
.sendpage = tcp_sendpage,
.splice_read =tcp_splice_read,
#ifdef CONFIG_COMPAT
.compat_setsockopt= compat_sock_common_setsockopt,
.compat_getsockopt= compat_sock_common_getsockopt,
#endif
};
欢迎同有兴趣的人一起交流讨论。