Linux 中添加传输层协议 MyTCP系列

在内核中添加一个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

};



欢迎同有兴趣的人一起交流讨论。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值