999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

支持多線程并發(fā)與消息異步處理的Linux Netlink通信機制研究

2017-11-02 15:50:21熊偉丁涵羅云鋒
軟件導(dǎo)刊 2017年10期

熊偉++丁涵++羅云鋒

摘要:Netlink是Linux操作系統(tǒng)內(nèi)核空間與用戶空間最流行的進程間通信機制之一,但目前在多線程程序中的使用還存在一些問題。介紹了Netlink相對于Linux其它傳統(tǒng)通信手段的優(yōu)點,闡述了使用Netlink進行用戶程序與內(nèi)核模塊通信的實現(xiàn)方法,分析了目前公開資料上Netlink線程并發(fā)支持機制存在的問題,并給出了支持多線程并發(fā)與消息異步處理的正確方法,最后在真實機器上進行了驗證。結(jié)果顯示,該方法能有效支持在多線程Linux應(yīng)用中使用Netlink進行用戶態(tài)與內(nèi)核態(tài)通信。

關(guān)鍵詞:Linux;nelink;進程間通信;多線程并發(fā);異步處理

DOIDOI:10.11907/rjdk.172576

中圖分類號:TP319文獻標識碼:A文章編號:16727800(2017)010009905

0引言

Linux是當今應(yīng)用最廣泛的操作系統(tǒng)之一,其兼容性好,能適應(yīng)從嵌入式設(shè)備、個人用戶終端到高性能服務(wù)器的不同硬件平臺,具有多任務(wù)與多用戶能力。Linux符合POSIX標準,在GNU公共許可權(quán)限下可免費獲得其內(nèi)核源代碼,同時還具備完整的軟件生態(tài)鏈,包含各種開發(fā)工具及第三方軟件庫,非常方便用戶開發(fā)定制自己的應(yīng)用。

Linux采用模塊化單內(nèi)核架構(gòu),支持內(nèi)核模塊動態(tài)加載與卸載,其系統(tǒng)地址空間結(jié)構(gòu)如圖1所示。Linux所有

圖1Linux操作系統(tǒng)結(jié)構(gòu)

內(nèi)核代碼可看作一個整體,運行在一個獨立的地址空間中,通常被稱為內(nèi)核空間[1]。運行于內(nèi)核空間的代碼不受任何限制,能夠自由地訪問任何有效地址以及直接進行設(shè)備訪問。而用戶應(yīng)用運行在內(nèi)核之上,其不能隨意占用系統(tǒng)資源與修改系統(tǒng)配置,從而確保系統(tǒng)安全性與穩(wěn)定性。

在日常應(yīng)用中,應(yīng)用程序通常包括上層用戶界面程序與底層內(nèi)核驅(qū)動模塊兩部分,用戶界面負責接收用戶輸入及顯示最終處理結(jié)果,內(nèi)核驅(qū)動則負責調(diào)用內(nèi)核處理用戶請求。因此內(nèi)核空間與用戶空間進行通信的方法非常重要。

目前,Linux常用的內(nèi)核用戶通信機制有以下幾種[2]:

(1)設(shè)備驅(qū)動接口。設(shè)備節(jié)點位于/dev目錄下。設(shè)備驅(qū)動接口允許用戶訪問設(shè)備節(jié)點[3],利用copy_from_user()與copy_to_user()函數(shù),在用戶態(tài)與內(nèi)核態(tài)間拷貝數(shù)據(jù)。但是這兩個函數(shù)只支持阻塞式調(diào)用,不能在中斷中使用,而且只支持用戶程序主動進行通信,通常用在硬件驅(qū)動中。

(2)Proc與sysfs文件系統(tǒng)。Proc與sysfs是虛擬文件系統(tǒng),用于顯示進程、處理器、內(nèi)存、中斷等信息[4,5]。用戶可以通過讀寫這兩種文件系統(tǒng)與內(nèi)核進行通信。其最大缺點是不支持基于事件的信號機制,數(shù)據(jù)傳輸大小也不能超過一個內(nèi)存頁,可擴展性較差。

(3)內(nèi)存映射。/dev/mem是Linux系統(tǒng)中一種特殊的字符設(shè)備文件[6],應(yīng)用程序通過這個節(jié)點,可以在內(nèi)核地址空間與用戶地址空間進行映射,然后訪問映射后的內(nèi)存區(qū)域,實現(xiàn)用戶空間與內(nèi)核空間的通信。但是對內(nèi)核地址的誤操作將引起嚴重后果,導(dǎo)致系統(tǒng)崩潰。

(4)Netlink套接字。Netlink是一種面向數(shù)據(jù)報的消息系統(tǒng),目前在Linux內(nèi)核中有非常多應(yīng)用可用于通信,包括路由、IPSEC、防火墻、netfilter日志等[710]。Netlink具有以下特點:消息具有較強的擴展能力,用戶可以自定義消息格式,且提供了基于事件的信號機制,允許大數(shù)據(jù)傳輸;支持全雙工傳輸,允許內(nèi)核主動發(fā)起傳輸通信;支持單播與組播兩種通信方式[11]。

如上所述,目前在Linux系統(tǒng)內(nèi)核空間與用戶空間通信方式中:設(shè)備節(jié)點適合于驅(qū)動程序開發(fā),但只支持單工傳輸;Proc與sysfs文件使用方便,但不支持傳輸大數(shù)據(jù);內(nèi)存映射傳輸效率最高,但誤操作時會對系統(tǒng)造成嚴重破壞;Netlink則使用很靈活,能滿足大多數(shù)用戶需求。

本文首先介紹Netlink套接字基本使用方法與通信流程,然后詳細闡述使用Netlink如何實現(xiàn)多線程并發(fā)與消息異步處理通信,最后在真實硬件平臺上對該機制進行驗證。

1Netlink機制概述

Netlink機制包含用戶態(tài)接口與內(nèi)核態(tài)接口,其中用戶態(tài)沿用標準的socket接口,內(nèi)核態(tài)則提供了專用接口。

1.1用戶態(tài)Netlink接口

Netlink用戶態(tài)接口與BSD套接字接口基本一致,包括:socket()、bind()、sendmsg()、recvmsg()、close等常用接口。

1.1.1Netlink套接字創(chuàng)建

int socket(int domain, int type, int protocol)

其中,domain參數(shù)為AF_NETLINK或PF_NETLINK,表示使用Netlink協(xié)議,type參數(shù)是SOCK_RAW或SOCK_DGRAM,代表Netlink面向數(shù)據(jù)報,最后一個參數(shù)指定Netlink協(xié)議類型,除了內(nèi)核中已經(jīng)定義的類型,用戶還可以定義自己的協(xié)議類型。

1.1.2套接字地址綁定

int bind(fd, (struct sockaddr*)&nladdr, sizeof(struct sockaddr_nl))

函數(shù)bind()用于Netlink套接字句柄與Netlink源地址綁定。第一個參數(shù)為創(chuàng)建Netlink套接字時獲取的描述符,第二個為Netlink源地址結(jié)構(gòu)指針,最后一個參數(shù)為Netlink源地址結(jié)構(gòu)大小。

Netlink socket地址定義如下:

struct sockaddr_nl {

_kernel_sa_family_t nl_family;/*AF_NETLINK*/endprint

unsigned short nl_pad; /* zero */

_u32 nl_pid; /* port ID */

_u32 nl_groups; /* multicast groups mask */

};

其中:nl_family代表協(xié)議類型,設(shè)置為AF_NETLINK或者PF_NETLINK;字段nl_pad保留,默認設(shè)置為0;nl_pid代表Netlink socket的本地地址,為確保消息發(fā)送準確性,其設(shè)置非常關(guān)鍵,必須確保唯一性;字段nl_groups用于設(shè)置多播組,如果設(shè)置為0,表示進行單播。

1.1.3Netlink消息發(fā)送

int sendmsg(int sock, struct msghdr *msg, int flags)

Netlink發(fā)送消息前需要填充信息,信息由消息頭與數(shù)據(jù)部分組成,其結(jié)構(gòu)如圖2所示。

圖2Netlink消息頭

消息長度代表Netlink消息的總長度,包括消息頭長度與數(shù)據(jù)部分長度;應(yīng)用內(nèi)部定義消息類型,大部分情況下設(shè)置為0;標志用于設(shè)置消息標志,內(nèi)核讀取與修改這類標志,通常不需修改,默認為0,在一些高級應(yīng)用(如路由daemon)中需要設(shè)置它進行特殊操作;字段序列號與消息端口號用于應(yīng)用追蹤消息來源,分別表示消息發(fā)送順序號與來源端口號。

1.1.4Netlink消息接收

int recvmsg(int sock, struct msghdr *msg, int flags)

應(yīng)用接收消息時,首先需要為消息頭與數(shù)據(jù)部分分配足夠空間,然后填充消息頭。

1.1.5關(guān)閉Netlink套接字

Close函數(shù)用于關(guān)閉套接字,釋放資源。

1.2內(nèi)核態(tài)Netlink接口

Linux內(nèi)核包含一套專門的接口函數(shù),接收用戶程序發(fā)送的數(shù)據(jù)以及將處理完數(shù)據(jù)發(fā)送回用戶程序。

1.2.1內(nèi)核態(tài)Netlink套接字創(chuàng)建

struct sock*netlink_kernel_create(struct net*net, int unit, struct netlink_kernel_cfg*cfg)

netlink_kernel_create函數(shù)在不同內(nèi)核版本間變化非常大,在使用過程中,需要查找與內(nèi)核匹配的函數(shù)定義。在3.0以上版本中,該函數(shù)包含3個參數(shù):第一個參數(shù)指定網(wǎng)絡(luò)名字空間,默認為init_net全局變量;第二個參數(shù)設(shè)置Netlink協(xié)議類型,需要與用戶態(tài)定義一致;第三個參數(shù)用于指定內(nèi)核態(tài)Netlink配置信息。其結(jié)構(gòu)為:

struct netlink_kernel_cfg {

unsigned int groups;

unsigned int flags;

void (*input)(struct sk_buff *skb);

struct mutex *cb_mutex;

int (*bind)(struct net *net, int group);

void (*unbind)(struct net *net, int group);

bool (*compare)(struct net *net, struct sock *sk); }

通常用戶只需設(shè)置groups與input字段:Groups用于設(shè)置單播還是組播;input用于注冊消息回調(diào)處理函數(shù),當內(nèi)核接收到用戶發(fā)來的Netlink信息后會自動調(diào)用它。

1.2.2從內(nèi)核態(tài)向用戶態(tài)發(fā)送數(shù)據(jù)

Netlink支持單播與組播,因此內(nèi)核態(tài)信息發(fā)送函數(shù)包括兩個。

單播:

int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock)

第一個參數(shù)為內(nèi)核Netlink套接字句柄;第二個參數(shù)存放消息結(jié)構(gòu),數(shù)據(jù)字段為發(fā)送的Netlink消息;控制塊則包含消息地址信息;第三個參數(shù)portid為接收對象的Netlink地址,最后一個用于設(shè)置阻塞屬性。

組播:

int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 portid,__u32 group, gfp_t allocation)

前3個參數(shù)與單播一樣,第四個參數(shù)用于指定接收消息的多播組,最后一個參數(shù)則為內(nèi)核內(nèi)存分配類型。

1.3Netlink內(nèi)核態(tài)與用戶態(tài)通信流程

用戶程序通過Netlink機制與內(nèi)核進行通信,流程如圖3所示。

圖3Netlink用戶態(tài)與內(nèi)核態(tài)交互流程

用戶態(tài)Netlink使用流程與常用BSD Socket一樣,首先使用socket函數(shù)創(chuàng)建套接字,然后使用bind函數(shù)綁定地址,封裝并使用sendmsg向內(nèi)核發(fā)送消息,接著使用recvmsg接收消息,最后通過close函數(shù)關(guān)閉套接字,釋放資源。內(nèi)核態(tài)處理過程類似,發(fā)送消息時還可以根據(jù)需要選擇單播或者多播。

2機制設(shè)計

Netlink作為socket的一個變種,本身就支持并發(fā)與異步處理,但是需要針對線程中Netlink socket本地地址設(shè)置與消息接收處理松耦合進行特殊設(shè)計。

2.1線程Netlink本地地址生成方法

Netlink并發(fā)實現(xiàn)的關(guān)鍵點是套接字創(chuàng)建時地址設(shè)置的唯一性。Bind函數(shù)負責給Netlink套接字命名,將本地地址與其相關(guān)聯(lián)。上文已經(jīng)介紹了結(jié)構(gòu)體sockaddr_nl中nl_pid字段用于代表32位本地地址,其在填充時必須保證唯一性才能確保收發(fā)消息的準確性。endprint

如果用戶程序?qū)崿F(xiàn)的是進程級并發(fā),可以采用進程號作為nl_pid的值,進程號在系統(tǒng)中的唯一性確保了Netlink本地地址的唯一性。

但是如果進程中多個線程需要創(chuàng)建各自獨立的Netlink socket,基于線程共享進程號的原因,進程號就不能用于區(qū)分線程創(chuàng)建的Netlink套接字地址。目前流傳最廣泛的線程Netlink中nl_pid創(chuàng)建方法為[12]:

pthread_self() 16 | getpid()

其中,nl_pid由線程自身ID后半部與其所屬進程pid拼接而成,期望由pid在系統(tǒng)的唯一性與pthread_self在進程中的唯一性,保證nl_pid在全系統(tǒng)的唯一性。但在實際使用中,生成的值并不唯一。圖4是在ubuntu 14.04中創(chuàng)建10個線程生成的pid、tid(pthread_self返回值)與nl_pid結(jié)果。如圖4所示,10個樣本中就出現(xiàn)了重復(fù)。

圖4線程地址示例圖

從圖4中可以發(fā)現(xiàn),pthread_self低16位有12位重復(fù),pthread_self()16后只有高4位發(fā)生變化,由于pid一般小于65 536,因此進程中創(chuàng)建n個線程,使用pthread_self()16 | getpid()出現(xiàn)重復(fù)數(shù)據(jù)的概率為:

1-15!(16-n)!×16n-1(1

運行10次出現(xiàn)重復(fù)的概率約為85%,而創(chuàng)建17個以上線程nl_pid重復(fù)概率就已經(jīng)為1。

分析pthread_self實現(xiàn),可以發(fā)現(xiàn)其實際獲取的是線程TCB地址相對于進程數(shù)據(jù)段的偏移,所以低地址一致,造成按上述方法生成nl_pid出現(xiàn)重復(fù)。

因此,為了保證線程中Netlink套接字正常使用,需要重新設(shè)計nl_pid生成公式。考察pthread_self的實現(xiàn),它在進程內(nèi)唯一而且后半部基本一致,因此可以考慮取其前半部與線程pid進行拼接,從而確保生成nl_pid在全系統(tǒng)的唯一性。新生成方法如下:

pthread_self()16 | getpid()16

一個支持多線程并發(fā)的Netlink用戶態(tài)示例用例如下,所有nl_pid設(shè)置都使用新方法:

struct sockaddr_nl src_addr, dest_addr;

struct nlmsghdr* nlh = NULL;

struct iovec iov;

struct msghdr msg;

/**建立用戶空間netlink套接字*/

sock_nl=socket(AF_NETLINK, SOCK_RAW, LinuxV_NL_P_TYPE);

/**填充SRC_ADDR并進行端口綁定*/

memset(&src_addr, 0, sizeof(struct sockaddr_nl));

src_addr.nl_family=AF_NETLINK;

/**按照新公式定義本地地址*/

src_addr.nl_pid=pthread_self()16 | getpid()16;

src_addr.nl_groups = 0;

/**綁定netlink套接字,在nl_pid端口監(jiān)聽*/

bind(sock_nl, (struct sockaddr*)&src_addr, sizeof(struct sockaddr_nl);

/**封裝Netlink消息*/

dest_addr.nl_family=AF_NETLINK;

dest_addr.nl_pid=0; /**to Linux kernel*/

dest_addr.nl_groups=0;

/**填充netlink命令包頭*/

nlh=(struct nlmsghdr*)malloc(NLMSG_LENGTH(MAX_PAYLOAD));

nlh->nlmsg_type=MY_TYPE_0;

/**注意保持和初始化時nl_pid一致,用于確定消息來源*/

nlh->nlmsg_pid=pthread_self()16 | getpid()16;

/**填充發(fā)送命令報內(nèi)容*/

memcpy(NLMSG_DATA(nlh), buf, buflen);

/**構(gòu)造Netlink消息包*/

iov.iov_base=(void*)nlh;

msg.msg_name=(void*)&dest_addr;

msg.msg_iov=&iov;

/**發(fā)送netlink包*/

sendmsg(sock_nl, &msg, 0);

/**接收netlink包*/

recvmsg(sock_nl, &msg, 0);

close(sock_nl)

2.2內(nèi)核Netlink消息異步處理機制

Netlink是BSD套接字的一種,繼承了其異步處理特性,用戶程序發(fā)送消息并把消息保存到接收者的接收隊列后,不需要一直等待內(nèi)核處理完消息。

為了提高異步處理效率,在內(nèi)核態(tài)可以將Netlink信息的接收與處理過程松耦合,這樣內(nèi)核收到用戶發(fā)來的消息后只負責喚醒處理內(nèi)核線程,然后就返回。所有的消息處理工作由處理線程完成,從而可以實現(xiàn)用戶程序持續(xù)快速發(fā)送Netlink消息到內(nèi)核,提高吞吐率。特別是如果應(yīng)用程序發(fā)送信息處理流程不同,就可以創(chuàng)建多個內(nèi)核線程進行并發(fā)處理。在內(nèi)核3.12.11上內(nèi)核態(tài)Netlink創(chuàng)建與消息異步收發(fā)實現(xiàn)代碼如下:

struct netlink_kernel_cfg cfg={

.groups=0,

.input=receive_us_msg,

};

nl_sk=netlink_kernel_create(&init_net,LinuxV_NL_P_TYPE, &cfg);

/**創(chuàng)建netlink消息處理內(nèi)核線程*/

nl_msg_thread=kthread_run(nlmsg_process_thread, NULL, "process");

void receive_us_msg(struct sk_buff* skb)

{

struct sk_buff* nl_skb=NULL;

nl_skb=skb_copy(skb,GFP_ATOMIC);

if(nl_skb)

skb_queue_tail(&(nl_sk->sk_receive_queue),nl_skb);

wake_up_interruptible(sk_sleep(nl_sk));

}

/*nlmsg_process_thread函數(shù)負責處理Netlink消息并回傳用戶程序*/

3實驗平臺與測試方法

為了驗證本文Netlink多線程并發(fā)機制的穩(wěn)定性與擴展性,測試將在32位與64位Linux系統(tǒng)上進行。測試機具體配置如表1、表2所示。

在測試中,檢驗使用上述方法進程能創(chuàng)建包含Netlink連接的線程數(shù)量。如果進程中不同線程生成的nl_pid一致,Netlink將創(chuàng)建失敗。在32位系統(tǒng)上,進程可以使用的虛擬用戶地址空間為3GB,其創(chuàng)建線程分配的線程空間大小總和不能超過這個限制,因此系統(tǒng)中進程能創(chuàng)建的線程數(shù)量取決于線程堆棧大小,在實驗中通過ulimit命令設(shè)置不同的線程堆棧大小,然后記錄進程能創(chuàng)建的最大線程數(shù)量,看其是否與理論值相符。在64位機器上,由于虛擬地址空間可以達到TB級,因此測試時首先設(shè)置系統(tǒng)最大可創(chuàng)建線程數(shù),然后通過測試程序記錄實際能創(chuàng)建的最大線程數(shù)量,看其是否與設(shè)置值相符。

4實驗結(jié)果與分析

在32位操作系統(tǒng)上測試結(jié)果如表3所示。

試驗顯示,在32位操作系統(tǒng)上,線程堆棧為2M時,創(chuàng)建線程數(shù)量為1 449,這個值與理論最大值相符,因為在32位Linux操作系統(tǒng)下進程用戶空間大小為3G(3 072M),用3 072M除以2M得1 536,但實際測試用例中代碼段與數(shù)據(jù)段等占用大概1KB,這個值應(yīng)該為1 400多。同理,內(nèi)核堆棧為4M、8M、16M時,線程數(shù)量與理論最大值相符合。

在64位操作系統(tǒng)上測試結(jié)果如表4所示。

系統(tǒng)中最大線程數(shù)量值設(shè)置為32 768,測試結(jié)果顯示,不同大小線程堆棧情況下創(chuàng)建的線程數(shù)量與系統(tǒng)線程最大值相差不大,符合預(yù)期,完全能夠滿足實際應(yīng)用需求。

5結(jié)語

Netlink socket是Linux系統(tǒng)中用戶程序與內(nèi)核模塊之間一種很靈活的通信方式,它使用方便,提供了全雙工、緩沖I/O、多點傳送及異步通訊等高級特性,應(yīng)用極其廣泛。但是,Netlink在內(nèi)核不同版本中變化非常大,目前公開資料上提供的線程并發(fā)與消息接收處理松耦合方法存在錯誤,也不適應(yīng)當前內(nèi)核版本。本文分析了Netlink socket本地地址nl_pid流行計算公式的錯誤原因,設(shè)計了新的計算公式,并在真實機器上進行了驗證,測試結(jié)果顯示新計算公式能真正支持線程中Netlink的使用。同時,還針對當前內(nèi)核版本,設(shè)計了切實可用的消息接收與處理松耦合流程,實現(xiàn)了上層應(yīng)用程序的快速響應(yīng)。

但是,由于Netlink是基于BSD socket實現(xiàn)的,其通信過程耗時非常大,傳輸效率不高,在今后工作中可以考慮結(jié)合其它傳輸機制,實現(xiàn)快捷高效的內(nèi)核態(tài)與用戶態(tài)數(shù)據(jù)通信。

參考文獻參考文獻:

[1]ROBERT L. Linux內(nèi)核設(shè)計與實現(xiàn)[M].陳莉君,康華,張波,譯.北京:機械工業(yè)出版社,2006.

[2]NEIRA-AYUSO P, GASCA R M, LEFEVRE L. Communicating between the kernel and userspace in Linux using Netlink sockets[J]. Software Practice & Experience,2013,40(9):797–810.

[3]CORBET J, RUBINI A, KROAHHARTMAN G. Linux device drivers[M]. Cambridge :O'Reilly Media, Inc.2005.

[4]郭松,謝維波.Linux視域下Proc文件系統(tǒng)的編程剖析[J].華僑大學學報:自然科學版,2010,31(5):515520.

[5]MOCHEL P. The sysfs filesystem[J]. Proceedings of Annual Linux Symposium,2005(1):313326.

[6]STEVENS W R,RAGO S A. UNIX環(huán)境高級編程[M].尤晉元,譯.北京:人民郵電出版社,2009.

[7]SALIM J, KHOSRAVI H, KLEEN A, et al. Linux Netlink as an IP services protocol[J]. International Journal of Developmental Neuroscience,2003,28(8):94.

[8]KENT S, SEO K. RFC4301: security architecture for internet protocol (IPSec)[M]. Los Angeles: RFC Editor,2005.

[9]PURDY G N. Linux iptablespocket reference: firewalls, nat and accounting[M]. Sebastopol, CA: OReilly Media, Inc,2004.

[10]ROSEN. Netfilter[M]. Berkeley, CA: Linux Kernel Networking Apress,2014.

[11]劉斌,朱程榮.Linux內(nèi)核與用戶空間通信機制研究[J].電腦知識與技術(shù),2012,8(16):38163817.

[12]HE K K. Why and how to use Netlink socket[J]. Linux Journal,2005,11(130):1419.

責任編輯(責任編輯:何麗)endprint

主站蜘蛛池模板: 国产情精品嫩草影院88av| 欧美不卡视频在线观看| 精品无码日韩国产不卡av| 亚洲第一区在线| 99视频在线免费| 亚国产欧美在线人成| 久热这里只有精品6| 九色在线视频导航91| 国产理论一区| 不卡网亚洲无码| 亚洲综合婷婷激情| 在线播放91| 国产亚洲精品无码专| 久久久久国产一级毛片高清板| 久久免费看片| 囯产av无码片毛片一级| 国产精品亚洲一区二区三区z| 国产手机在线观看| 一级毛片中文字幕| 亚洲精品动漫| 国模极品一区二区三区| 中文字幕 91| 久久国产精品77777| 55夜色66夜色国产精品视频| 9999在线视频| 亚洲一级无毛片无码在线免费视频| 三上悠亚精品二区在线观看| 亚洲αv毛片| 日日摸夜夜爽无码| 久久久久国产精品嫩草影院| 色婷婷色丁香| 午夜视频www| 日韩精品中文字幕一区三区| 国产成人精品2021欧美日韩| 国产精品亚洲一区二区在线观看| 成人无码一区二区三区视频在线观看| 国产91小视频在线观看| 免费国产好深啊好涨好硬视频| 97一区二区在线播放| 国产免费羞羞视频| 久久久国产精品免费视频| 四虎永久免费网站| 国产男女免费视频| 伊人国产无码高清视频| 无码专区在线观看| 国产乱人伦精品一区二区| 国产美女免费网站| 无码中文AⅤ在线观看| 亚洲无线国产观看| 99偷拍视频精品一区二区| 亚洲无码视频喷水| 亚洲天堂精品在线| 亚洲中文字幕国产av| 亚洲精品欧美日本中文字幕| 伊人久久大香线蕉成人综合网| 久久鸭综合久久国产| 国产尹人香蕉综合在线电影| 亚洲日本在线免费观看| 国产全黄a一级毛片| 国产真实乱人视频| 亚洲二三区| 国产精品免费电影| 在线免费观看AV| 欧美伦理一区| 久久久波多野结衣av一区二区| 久久久久中文字幕精品视频| 不卡网亚洲无码| 免费一看一级毛片| 国产一区亚洲一区| 在线观看免费人成视频色快速| 国产成人精品高清不卡在线| 久久精品女人天堂aaa| 亚洲精品国产首次亮相| 日韩毛片在线播放| 一级爱做片免费观看久久| 丁香六月综合网| 无码国产偷倩在线播放老年人| 久久伊人色| 一区二区午夜| 国产高清在线精品一区二区三区| 国产精选自拍| 亚洲综合专区|