网络子系统10_inet模块初始化

来源:互联网 发布:偷菜软件 编辑:程序博客网 时间:2024/06/05 05:43
//inet模块初始化//inet功能以模块的形式提供//1.sock_register(inet_family_ops)向socket注册地址族,保存在net_families数组中,socket通过地址族查找对应的inet_family_ops//2.struct inet_protosw 由l4使用,表示地址族(协议族)中某一具体协议的操作,保存在inetsw链表数组中,通过协议类型查找对应的协议操作//3.struct net_protocol 由l3使用,表示l4协议的回调函数,l3通过l3报头中的协议字段,在inet_protos数组中查找对应l4回调函数。static int __init inet_init(void){struct sk_buff *dummy_skb;struct inet_protosw *q;struct list_head *r;int rc = -EINVAL;//如果inet控制块的大小 > skb提供的控制块的大小if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) {printk(KERN_CRIT "%s: panic\n", __FUNCTION__);goto out;}//tcp sock SLAB 缓存rc = sk_alloc_slab(&tcp_prot, "tcp_sock");if (rc) {sk_alloc_slab_error(&tcp_prot);goto out;}//udp sock SLAB 缓存rc = sk_alloc_slab(&udp_prot, "udp_sock");if (rc) {sk_alloc_slab_error(&udp_prot);goto out_tcp_free_slab;}//raw sock SLBA缓存rc = sk_alloc_slab(&raw_prot, "raw_sock");if (rc) {sk_alloc_slab_error(&raw_prot);goto out_udp_free_slab;}//向sock注册af_inet服务  (void)sock_register(&inet_family_ops);  //注册l4协议,l3接收到数据包时,通过协议字段,找到对应的上层协议的回调函数  //xxx_protocol用于向下提供服务if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)//icmpprintk(KERN_CRIT "inet_init: Cannot add ICMP protocol\n");if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0)//udpprintk(KERN_CRIT "inet_init: Cannot add UDP protocol\n");if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0)//tcpprintk(KERN_CRIT "inet_init: Cannot add TCP protocol\n");#ifdef CONFIG_IP_MULTICASTif (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0)//igmpprintk(KERN_CRIT "inet_init: Cannot add IGMP protocol\n");#endif//初始化inetsw数组,其中每一个元素为一个链表头//inetsw用链表的形式组织af_inet地址族中的所有协议//inetsw中的每一个链表头,代表一种套接字类型(type)//链表中的一个元素,对应一个具体的协议(protocal)for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)//SOCK_MAX = 11INIT_LIST_HEAD(r);//inet默认提供的协议,静态编码在inetsw_array数组中,//先通过inet_register_protosw,将其从inetsw_array添加到inetsw中//注册af_inet下不同套接字类型,提供的各种协议,用于向上提供服务for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)inet_register_protosw(q);//arp子系统初始化arp_init();//ip子系统初始化ip_init();//tcp子系统初始化tcp_v4_init(&inet_family_ops);tcp_init();//icmp子系统初始化icmp_init(&inet_family_ops);//ip多播初始化#if defined(CONFIG_IP_MROUTE)ip_mr_init();#endif//snmp的mibs初始化if(init_ipv4_mibs())printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n"); ;//ip在proc中的初始化ipv4_proc_init();//ip分片/合并子系统初始化ipfrag_init();rc = 0;out:return rc;out_tcp_free_slab:sk_free_slab(&tcp_prot);out_udp_free_slab:sk_free_slab(&udp_prot);goto out;}//已模块形式提供ip功能module_init(inet_init);//注册协议族or地址族 //inet为af_inet2.1 int sock_register(struct net_proto_family *ops){int err;//族编号大于最大的族号(32目前)if (ops->family >= NPROTO) {printk(KERN_CRIT "protocol %d >= NPROTO(%d)\n", ops->family, NPROTO);return -ENOBUFS;}net_family_write_lock();err = -EEXIST;//将协议族注册到net_families数组中if (net_families[ops->family] == NULL) {net_families[ops->family]=ops;err = 0;}net_family_write_unlock();printk(KERN_INFO "NET: Registered protocol family %d\n",       ops->family);return err;}2.2 //linux中,协议族等于地址族#define PF_UNSPECAF_UNSPEC#define PF_UNIXAF_UNIX#define PF_LOCALAF_LOCAL#define PF_INETAF_INET#define PF_AX25AF_AX25#define PF_IPXAF_IPX#define PF_APPLETALKAF_APPLETALK#definePF_NETROMAF_NETROM#define PF_BRIDGEAF_BRIDGE#define PF_ATMPVCAF_ATMPVC#define PF_X25AF_X25#define PF_INET6AF_INET6#define PF_ROSEAF_ROSE#define PF_DECnetAF_DECnet#define PF_NETBEUIAF_NETBEUI#define PF_SECURITYAF_SECURITY#define PF_KEYAF_KEY#define PF_NETLINKAF_NETLINK#define PF_ROUTEAF_ROUTE#define PF_PACKETAF_PACKET#define PF_ASHAF_ASH#define PF_ECONETAF_ECONET#define PF_ATMSVCAF_ATMSVC#define PF_SNAAF_SNA#define PF_IRDAAF_IRDA#define PF_PPPOXAF_PPPOX#define PF_WANPIPEAF_WANPIPE#define PF_LLCAF_LLC#define PF_BLUETOOTHAF_BLUETOOTH#define PF_MAXAF_MAX//注册inet协议族特定协议的数据处理handler//在下层接收到数据时,根据协议号,查找指定的处理handler//protocol可取值为;enum {  IPPROTO_IP = 0,/* Dummy protocol for TCP*/  IPPROTO_ICMP = 1,/* Internet Control Message Protocol*/  IPPROTO_IGMP = 2,/* Internet Group Management Protocol*/  IPPROTO_IPIP = 4,/* IPIP tunnels (older KA9Q tunnels use 94) */  IPPROTO_TCP = 6,/* Transmission Control Protocol*/  IPPROTO_EGP = 8,/* Exterior Gateway Protocol*/  IPPROTO_PUP = 12,/* PUP protocol*/  IPPROTO_UDP = 17,/* User Datagram Protocol*/  IPPROTO_IDP = 22,/* XNS IDP protocol*/  IPPROTO_RSVP = 46,/* RSVP protocol*/  IPPROTO_GRE = 47,/* Cisco GRE tunnels (rfc 1701,1702)*/  IPPROTO_IPV6 = 41,/* IPv6-in-IPv4 tunnelling*/  IPPROTO_ESP = 50,            /* Encapsulation Security Payload protocol */  IPPROTO_AH = 51,             /* Authentication Header protocol       */  IPPROTO_PIM    = 103,/* Protocol Independent Multicast*/  IPPROTO_COMP   = 108,                /* Compression Header protocol */  IPPROTO_SCTP   = 132,/* Stream Control Transport Protocol*/  IPPROTO_RAW = 255,/* Raw IP packets*/  IPPROTO_MAX};3.1 int inet_add_protocol(struct net_protocol *prot, unsigned char protocol){int hash, ret;//哈希协议号hash = protocol & (MAX_INET_PROTOS - 1);spin_lock_bh(&inet_proto_lock);//协议号唯一if (inet_protos[hash]) {ret = -1;} else {//将协议处理handler保存到inet_protos数组中inet_protos[hash] = prot;ret = 0;}spin_unlock_bh(&inet_proto_lock);return ret;}//注册特定inet协议与socket interface交互的控制块4.1 void inet_register_protosw(struct inet_protosw *p){struct list_head *lh;struct inet_protosw *answer;int protocol = p->protocol;struct list_head *last_perm;spin_lock_bh(&inetsw_lock);//套接字类型 不应该超过 系统支持的最大类型号(socket type)if (p->type >= SOCK_MAX)goto out_illegal;answer = NULL;//对应套接字类型在inetsw中的列表头last_perm = &inetsw[p->type];//遍历该套接字类型的所有协议控制块list_for_each(lh, &inetsw[p->type]) {answer = list_entry(lh, struct inet_protosw, list);//判断协议是否可移动if (INET_PROTOSW_PERMANENT & answer->flags) {//该类型的套接字下,已存在一个这样协议号的控制块if (protocol == answer->protocol)break;last_perm = lh;}answer = NULL;}//存在此套接字类型的协议号if (answer)goto out_permanent;//添加这种类型套接字下的一个特定协议控制块list_add_rcu(&p->list, last_perm);out:spin_unlock_bh(&inetsw_lock);//同步synchronize_net();return;out_permanent:printk(KERN_ERR "Attempt to override permanent protocol %d.\n",       protocol);goto out;out_illegal:printk(KERN_ERR       "Ignoring attempt to register invalid socket type %d.\n",       p->type);goto out;}

原创粉丝点击