¡¡¡¡
Ò»¡¢ Á´±íÊý¾Ý½á¹¹¼ò½é¡¡¡¡Á´±íÊÇÒ»ÖÖ³£ÓõÄ×éÖ¯ÓÐÐòÊý¾ÝµÄÊý¾Ý½á¹¹£¬Ëüͨ¹ýÖ¸Õ뽫һϵÁÐÊý¾Ý½ÚµãÁ¬½Ó³ÉÒ»ÌõÊý¾ÝÁ´£¬ÊÇÏßÐÔ±íµÄÒ»ÖÖÖØҪʵÏÖ·½Ê½¡£Ïà¶ÔÓÚÊý×飬Á´±í¾ßÓиüºÃµÄ¶¯Ì¬ÐÔ£¬½¨Á¢Á´±íʱÎÞÐèÔ¤ÏÈÖªµÀÊý¾Ý×ÜÁ¿£¬¿ÉÒÔËæ»ú·ÖÅä¿Õ¼ä£¬¿ÉÒÔ¸ßЧµØÔÚÁ´±íÖеÄÈÎÒâλÖÃʵʱ²åÈë»òɾ³ýÊý¾Ý¡£Á´±íµÄ¿ªÏúÖ÷ÒªÊÇ·ÃÎʵÄ˳ÐòÐÔºÍ×éÖ¯Á´µÄ¿Õ¼äËðʧ¡£¡¡¡¡¡¡¡¡Í¨³£Á´±íÊý¾Ý½á¹¹ÖÁÉÙÓ¦°üº¬Á½¸öÓò£ºÊý¾ÝÓòºÍÖ¸ÕëÓò£¬Êý¾ÝÓòÓÃÓÚ´æ´¢Êý¾Ý£¬Ö¸ÕëÓòÓÃÓÚ½¨Á¢ÓëÏÂÒ»¸ö½ÚµãµÄÁªÏµ¡£°´ÕÕÖ¸ÕëÓòµÄ×éÖ¯ÒÔ¼°¸÷¸ö½ÚµãÖ®¼äµÄÁªÏµÐÎʽ£¬Á´±íÓÖ¿ÉÒÔ·ÖΪµ¥Á´±í¡¢Ë«Á´±í¡¢Ñ»·Á´±íµÈ¶àÖÖÀàÐÍ£¬ÏÂÃæ·Ö±ð¸ø³öÕ⼸Àà³£¼ûÁ´±íÀàÐ͵ÄʾÒâͼ£º¡¡¡¡¡¡¡¡1£® µ¥Á´±í¡¡¡¡¡¡¡¡Í¼1 µ¥Á´±í¡¡¡¡¡¡¡¡¡¡µ¥Á´±íÊÇ×î¼òµ¥µÄÒ»ÀàÁ´±í£¬ËüµÄÌصãÊǽöÓÐÒ»¸öÖ¸ÕëÓòÖ¸Ïòºó¼Ì½Úµã£¨next£©£¬Òò´Ë£¬¶Ôµ¥Á´±íµÄ±éÀúÖ»ÄÜ´ÓÍ·ÖÁβ£¨Í¨³£ÊÇNULL¿ÕÖ¸Õ룩˳Ðò½øÐС£¡¡¡¡¡¡¡¡2£® Ë«Á´±í¡¡¡¡¡¡¡¡Í¼2 Ë«Á´±í¡¡¡¡¡¡¡¡¡¡Í¨¹ýÉè¼ÆÇ°ÇýºÍºó¼ÌÁ½¸öÖ¸ÕëÓò£¬Ë«Á´±í¿ÉÒÔ´ÓÁ½¸ö·½Ïò±éÀú£¬ÕâÊÇËüÇø±ðÓÚµ¥Á´±íµÄµØ·½¡£Èç¹û´òÂÒÇ°Çý¡¢ºó¼ÌµÄÒÀÀµ¹Øϵ£¬¾Í¿ÉÒÔ¹¹³É"¶þ²æÊ÷"£»Èç¹ûÔÙÈÃÊ×½ÚµãµÄÇ°ÇýÖ¸ÏòÁ´±íβ½Úµã¡¢Î²½ÚµãµÄºó¼ÌÖ¸ÏòÊ׽ڵ㣨Èçͼ2ÖÐÐéÏß²¿·Ö£©£¬¾Í¹¹³ÉÁËÑ»·Á´±í£»Èç¹ûÉè¼Æ¸ü¶àµÄÖ¸ÕëÓò£¬¾Í¿ÉÒÔ¹¹³É¸÷ÖÖ¸´ÔÓµÄÊ÷×´Êý¾Ý½á¹¹¡£¡¡¡¡¡¡¡¡3£® Ñ»·Á´±í¡¡¡¡Ñ»·Á´±íµÄÌصãÊÇβ½ÚµãµÄºó¼ÌÖ¸ÏòÊ׽ڵ㡣ǰÃæÒѾ¸ø³öÁËË«Ñ»·Á´±íµÄʾÒâͼ£¬ËüµÄÌصãÊÇ´ÓÈÎÒâÒ»¸ö½Úµã³ö·¢£¬ÑØÁ½¸ö·½ÏòµÄÈκÎÒ»¸ö£¬¶¼ÄÜÕÒµ½Á´±íÖеÄÈÎÒâÒ»¸öÊý¾Ý¡£Èç¹ûÈ¥µôÇ°ÇýÖ¸Õ룬¾ÍÊǵ¥Ñ»·Á´±í¡£¡¡¡¡¡¡¡¡ÔÚLinuxÄÚºËÖÐʹÓÃÁË´óÁ¿µÄÁ´±í½á¹¹À´×éÖ¯Êý¾Ý£¬°üÀ¨É豸ÁбíÒÔ¼°¸÷ÖÖ¹¦ÄÜÄ£¿éÖеÄÊý¾Ý×éÖ¯¡£ÕâЩÁ´±í´ó¶à²ÉÓÃÔÚ[include/linux/list.h]ʵÏÖµÄÒ»¸öÏ൱¾«²ÊµÄÁ´±íÊý¾Ý½á¹¹¡£±¾Îĵĺó¼Ì²¿·Ö¾Í½«Í¨¹ýʾÀýÏêϸ½éÉÜÕâÒ»Êý¾Ý½á¹¹µÄ×éÖ¯ºÍʹÓᣡ¡¡¡¡¡¡¡
¶þ¡¢ Linux 2.6ÄÚºËÁ´±íÊý¾Ý½á¹¹µÄʵÏÖ¡¡¡¡¾¡¹ÜÕâÀïʹÓÃ2.6ÄÚºË×÷Ϊ½²½âµÄ»ù´¡£¬µ«Êµ¼ÊÉÏ2.4ÄÚºËÖеÄÁ´±í½á¹¹ºÍ2.6²¢Ã»ÓÐʲôÇø±ð¡£²»Í¬Ö®´¦ÔÚÓÚ2.6À©³äÁËÁ½ÖÖÁ´±íÊý¾Ý½á¹¹£ºÁ´±íµÄ¶Á¿½±´¸üУ¨rcu£©ºÍHASHÁ´±í£¨hlist£©¡£ÕâÁ½ÖÖÀ©Õ¹¶¼ÊÇ»ùÓÚ×î»ù±¾µÄlist½á¹¹£¬Òò´Ë£¬±¾ÎÄÖ÷Òª½éÉÜ»ù±¾Á´±í½á¹¹£¬È»ºóÔÙ¼òÒª½éÉÜÒ»ÏÂrcuºÍhlist¡£¡¡¡¡¡¡¡¡Á´±íÊý¾Ý½á¹¹µÄ¶¨ÒåºÜ¼òµ¥£¨½ÚÑ¡×Ô[include/linux/list.h]£¬ÒÔÏÂËùÓдúÂ룬³ý·Ç¼ÓÒÔ˵Ã÷£¬ÆäÓà¾ùÈ¡×Ô¸ÃÎļþ£©£º¡¡¡¡¡¡¡¡strUCt list_head {¡¡¡¡ struct list_head *next, *prev;¡¡¡¡};¡¡¡¡¡¡¡¡list_head½á¹¹°üº¬Á½¸öÖ¸Ïòlist_head½á¹¹µÄÖ¸ÕëprevºÍnext£¬Óɴ˿ɼû£¬Äں˵ÄÁ´±í¾ß±¸Ë«Á´±í¹¦ÄÜ£¬Êµ¼ÊÉÏ£¬Í¨³£Ëü¶¼×éÖ¯³ÉË«Ñ»·Á´±í¡£¡¡¡¡¡¡¡¡ºÍµÚÒ»½Ú½éÉܵÄË«Á´±í½á¹¹Ä£ÐͲ»Í¬£¬ÕâÀïµÄlist_headûÓÐÊý¾ÝÓò¡£ÔÚLinuxÄÚºËÁ´±íÖУ¬²»ÊÇÔÚÁ´±í½á¹¹Öаüº¬Êý¾Ý£¬¶øÊÇÔÚÊý¾Ý½á¹¹Öаüº¬Á´±í½Úµã¡£¡¡¡¡¡¡¡¡ÔÚÊý¾Ý½á¹¹¿Î±¾ÖУ¬Á´±íµÄ¾µä¶¨Ò巽ʽͨ³£ÊÇÕâÑùµÄ£¨ÒÔµ¥Á´±íΪÀý£©£º¡¡¡¡¡¡¡¡struct list_node {¡¡¡¡ struct list_node *next;¡¡¡¡ ElemType data;¡¡¡¡};¡¡¡¡¡¡¡¡ÒòΪElemTypeµÄÔµ¹Ê£¬¶ÔÿһÖÖÊý¾ÝÏîÀàÐͶ¼ÐèÒª¶¨Òå¸÷×ÔµÄÁ´±í½á¹¹¡£ÓоÑéµÄC++³ÌÐòÔ±Ó¦¸ÃÖªµÀ£¬±ê׼ģ°å¿âÖеIJÉÓõÄÊÇC++ Template£¬ÀûÓÃÄ£°å³éÏó³öºÍÊý¾ÝÏîÀàÐÍÎ޹صÄÁ´±í²Ù×÷½Ó¿Ú¡£¡¡¡¡¡¡¡¡ÔÚLinuxÄÚºËÁ´±íÖУ¬ÐèÒªÓÃÁ´±í×éÖ¯ÆðÀ´µÄÊý¾Ýͨ³£»á°üº¬Ò»¸östruct list_head³ÉÔ±£¬ÀýÈçÔÚ[include/linux/netfilter.h]Öж¨ÒåÁËÒ»¸önf_sockopt_ops½á¹¹À´ÃèÊöNetfilterΪijһÐÒé×å×¼±¸µÄgetsockopt/setsockopt½Ó¿Ú£¬ÆäÖоÍÓÐÒ»¸ö£¨struct list_head list£©³ÉÔ±£¬¸÷¸öÐÒé×åµÄnf_sockopt_ops½á¹¹¶¼Í¨¹ýÕâ¸ölist³ÉÔ±×éÖ¯ÔÚÒ»¸öÁ´±íÖУ¬±íÍ·ÊǶ¨ÒåÔÚ[net/core/netfilter.c]ÖеÄnf_sockopts£¨struct list_head£©¡£´ÓÏÂͼÖÐÎÒÃÇ¿ÉÒÔ¿´µ½£¬ÕâÖÖͨÓõÄÁ´±í½á¹¹±ÜÃâÁËΪÿ¸öÊý¾ÝÏîÀàÐͶ¨Òå×Ô¼ºµÄÁ´±íµÄÂé·³¡£LinuxµÄ¼ò½ÝʵÓᢲ»ÇóÍêÃÀºÍ±ê×¼µÄ·ç¸ñ£¬ÔÚÕâÀïÌåÏÖµÃÏ൱³ä·Ö¡£¡¡¡¡¡¡¡¡Í¼3 nf_sockoptsÁ´±íʾÒâͼ¡¡¡¡¡¡¡¡¡¡
Èý¡¢ Á´±í²Ù×÷½Ó¿Ú¡¡¡¡1. ÉùÃ÷ºÍ³õʼ»¯¡¡¡¡Êµ¼ÊÉÏLinuxÖ»¶¨ÒåÁËÁ´±í½Úµã£¬²¢Ã»ÓÐרÃŶ¨ÒåÁ´±íÍ·£¬ÄÇôһ¸öÁ´±í½á¹¹ÊÇÈçºÎ½¨Á¢ÆðÀ´µÄÄØ£¿ÈÃÎÒÃÇÀ´¿´¿´LIST_HEAD()Õâ¸öºê£º¡¡¡¡¡¡¡¡#define LIST_HEAD_INIT(name) { &(name), &(name) }¡¡¡¡#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)¡¡¡¡¡¡¡¡µ±ÎÒÃÇÓÃLIST_HEAD(nf_sockopts)ÉùÃ÷Ò»¸öÃûΪnf_sockoptsµÄÁ´±íͷʱ£¬ËüµÄnext¡¢prevÖ¸Õ붼³õʼ»¯ÎªÖ¸Ïò×Ô¼º£¬ÕâÑù£¬ÎÒÃǾÍÓÐÁËÒ»¸ö¿ÕÁ´±í£¬ÒòΪLinuxÓÃÍ·Ö¸ÕëµÄnextÊÇ·ñÖ¸Ïò×Ô¼ºÀ´ÅжÏÁ´±íÊÇ·ñΪ¿Õ£º¡¡¡¡¡¡¡¡static inline int list_empty(const struct list_head *head)¡¡¡¡{¡¡¡¡ return head->next == head;¡¡¡¡}¡¡¡¡¡¡¡¡³ýÁËÓÃLIST_HEAD()ºêÔÚÉùÃ÷µÄʱºò³õʼ»¯Ò»¸öÁ´±íÒÔÍ⣬Linux»¹ÌṩÁËÒ»¸öINIT_LIST_HEADºêÓÃÓÚÔËÐÐʱ³õʼ»¯Á´±í£º¡¡¡¡¡¡¡¡#define INIT_LIST_HEAD(ptr) do { (ptr)->next = (ptr); (ptr)->prev = (ptr); } while (0)¡¡¡¡¡¡¡¡ÎÒÃÇÓÃINIT_LIST_HEAD(&nf_sockopts)À´Ê¹ÓÃËü¡£¡¡¡¡¡¡¡¡2. ²åÈë/ɾ³ý/ºÏ²¢¡¡¡¡a) ²åÈë¡¡¡¡¡¡¡¡¶ÔÁ´±íµÄ²åÈë²Ù×÷ÓÐÁ½ÖÖ£ºÔÚ±íÍ·²åÈëºÍÔÚ±íβ²åÈë¡£LinuxΪ´ËÌṩÁËÁ½¸ö½Ó¿Ú£º¡¡¡¡¡¡¡¡static inline void list_add(struct list_head *new, struct list_head *head);¡¡¡¡static inline void list_add_tail(struct list_head *new, struct list_head *head);¡¡¡¡¡¡¡¡ÒòΪLinuxÁ´±íÊÇÑ»·±í£¬ÇÒ±íÍ·µÄnext¡¢prev·Ö±ðÖ¸ÏòÁ´±íÖеĵÚÒ»¸öºÍ×îÄ©Ò»¸ö½Úµã£¬ËùÒÔ£¬list_addºÍlist_add_tailµÄÇø±ð²¢²»´ó£¬Êµ¼ÊÉÏ£¬Linux·Ö±ðÓá¡¡¡¡¡¡¡__list_add(new, head, head->next);¡¡¡¡¡¡¡¡ºÍ¡¡¡¡¡¡¡¡__list_add(new, head->prev, head);¡¡¡¡¡¡¡¡À´ÊµÏÖÁ½¸ö½Ó¿Ú£¬¿É¼û£¬ÔÚ±íÍ·²åÈëÊDzåÈëÔÚheadÖ®ºó£¬¶øÔÚ±íβ²åÈëÊDzåÈëÔÚhead->prevÖ®ºó¡£¡¡¡¡¡¡¡¡¼ÙÉèÓÐÒ»¸öÐÂnf_sockopt_ops½á¹¹±äÁ¿new_sockoptÐèÒªÌí¼Óµ½nf_sockoptsÁ´±íÍ·£¬ÎÒÃÇÓ¦µ±ÕâÑù²Ù×÷£º¡¡¡¡¡¡¡¡list_add(&new_sockopt.list, &nf_sockopts);¡¡¡¡¡¡¡¡´ÓÕâÀïÎÒÃÇ¿´³ö£¬nf_sockoptsÁ´±íÖмǼµÄ²¢²»ÊÇnew_sockoptµÄµØÖ·£¬¶øÊÇÆäÖеÄlistÔªËصĵØÖ·¡£ÈçºÎͨ¹ýÁ´±í·ÃÎʵ½new_sockoptÄØ£¿ÏÂÃæ»áÓÐÏêϸ½éÉÜ¡£¡¡¡¡¡¡¡¡b) ɾ³ý¡¡¡¡¡¡¡¡static inline void list_del(struct list_head *entry);¡¡¡¡¡¡¡¡µ±ÎÒÃÇÐèҪɾ³ýnf_sockoptsÁ´±íÖÐÌí¼ÓµÄnew_sockoptÏîʱ£¬ÎÒÃÇÕâô²Ù×÷£º¡¡¡¡¡¡¡¡list_del(&new_sockopt.list);¡¡¡¡¡¡¡¡±»ÌÞ³ýÏÂÀ´µÄnew_sockopt.list£¬prev¡¢nextÖ¸Õë·Ö±ð±»ÉèΪLIST_POSITION2ºÍLIST_POSITION1Á½¸öÌØÊâÖµ£¬ÕâÑùÉèÖÃÊÇΪÁ˱£Ö¤²»ÔÚÁ´±íÖеĽڵãÏî²»¿É·ÃÎÊ--¶ÔLIST_POSITION1ºÍLIST_POSITION2µÄ·ÃÎʶ¼½«ÒýÆðÒ³¹ÊÕÏ¡£ÓëÖ®Ïà¶ÔÓ¦£¬list_del_init()º¯Êý½«½Úµã´ÓÁ´±íÖнâÏÂÀ´Ö®ºó£¬µ÷ÓÃLIST_INIT_HEAD()½«½ÚµãÖÃΪ¿ÕÁ´×´Ì¬¡£¡¡¡¡¡¡¡¡c) °áÒÆ¡¡¡¡¡¡¡¡LinuxÌṩÁ˽«Ô±¾ÊôÓÚÒ»¸öÁ´±íµÄ½ÚµãÒƶ¯µ½ÁíÒ»¸öÁ´±íµÄ²Ù×÷£¬²¢¸ù¾Ý²åÈëµ½ÐÂÁ´±íµÄλÖ÷ÖΪÁ½Àࣺ¡¡¡¡¡¡¡¡static inline void list_move(struct list_head *list, struct list_head *head);¡¡¡¡static inline void list_move_tail(struct list_head *list, struct list_head *head);¡¡¡¡¡¡¡¡ÀýÈçlist_move(&new_sockopt.list,&nf_sockopts)»á°Ñnew_sockopt´ÓËüËùÔÚµÄÁ´±íÉÏɾ³ý£¬²¢½«ÆäÔÙÁ´Èënf_sockoptsµÄ±íÍ·¡£¡¡¡¡¡¡¡¡d) ºÏ²¢¡¡¡¡¡¡¡¡³ýÁËÕë¶Ô½ÚµãµÄ²åÈ롢ɾ³ý²Ù×÷£¬LinuxÁ´±í»¹ÌṩÁËÕû¸öÁ´±íµÄ²åÈ빦ÄÜ£º¡¡¡¡¡¡¡¡static inline void list_splice(struct list_head *list, struct list_head *head);¡¡¡¡¡¡¡¡¼ÙÉ赱ǰÓÐÁ½¸öÁ´±í£¬±íÍ··Ö±ðÊÇlist1ºÍlist2£¨¶¼ÊÇstruct list_head±äÁ¿£©£¬µ±µ÷ÓÃlist_splice(&list1,&list2)ʱ£¬Ö»Òªlist1·Ç¿Õ£¬list1Á´±íµÄÄÚÈݽ«±»¹Ò½ÓÔÚlist2Á´±íÉÏ£¬Î»ÓÚlist2ºÍlist2.next£¨Ôlist2±íµÄµÚÒ»¸ö½Úµã£©Ö®¼ä¡£ÐÂlist2Á´±í½«ÒÔÔlist1±íµÄµÚÒ»¸ö½ÚµãΪÊ׽ڵ㣬¶øβ½Úµã²»±ä¡£Èçͼ£¨Ðé¼ýͷΪnextÖ¸Õ룩£º¡¡¡¡¡¡¡¡Í¼4 Á´±íºÏ²¢list_splice(&list1,&list2)¡¡¡¡¡¡¡¡¡¡µ±list1±»¹Ò½Óµ½list2Ö®ºó£¬×÷ΪԱíÍ·Ö¸ÕëµÄlist1µÄnext¡¢prevÈÔȻָÏòÔÀ´µÄ½Úµã£¬ÎªÁ˱ÜÃâÒýÆð»ìÂÒ£¬LinuxÌṩÁËÒ»¸ölist_splice_init()º¯Êý£º¡¡¡¡¡¡¡¡ static inline void list_splice_init(struct list_head *list, struct list_head *head);¡¡¡¡ ¡¡¡¡¸Ãº¯ÊýÔÚ½«listºÏ²¢µ½headÁ´±íµÄ»ù´¡ÉÏ£¬µ÷ÓÃINIT_LIST_HEAD(list)½«listÉèÖÃΪ¿ÕÁ´¡£¡¡¡¡¡¡¡¡3. ±éÀú¡¡¡¡±éÀúÊÇÁ´±í×î¾³£µÄ²Ù×÷Ö®Ò»£¬ÎªÁË·½±ãºËÐÄÓ¦ÓñéÀúÁ´±í£¬LinuxÁ´±í½«±éÀú²Ù×÷³éÏó³É¼¸¸öºê¡£ÔÚ½éÉܱéÀúºê֮ǰ£¬ÎÒÃÇÏÈ¿´¿´ÈçºÎ´ÓÁ´±íÖзÃÎʵ½ÎÒÃÇÕæÕýÐèÒªµÄÊý¾ÝÏî¡£¡¡¡¡¡¡¡¡a) ÓÉÁ´±í½Úµãµ½Êý¾ÝÏî±äÁ¿¡¡¡¡¡¡¡¡ÎÒÃÇÖªµÀ£¬LinuxÁ´±íÖнö±£´æÁËÊý¾ÝÏî½á¹¹ÖÐlist_head³ÉÔ±±äÁ¿µÄµØÖ·£¬ÄÇôÎÒÃÇÈçºÎͨ¹ýÕâ¸ölist_head³ÉÔ±·ÃÎʵ½×÷ΪËüµÄËùÓÐÕߵĽڵãÊý¾ÝÄØ£¿LinuxΪ´ËÌṩÁËÒ»¸ölist_entry(ptr,type,member)
[1] [2] ÏÂÒ»Ò³
£¨³ö´¦£ºhttp://www.sheup.com£©
ÉÏÒ»Ò³ [1] [2]