精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

圖解eBPF Socket level 重定向的內核實現細節

云計算 云原生
我們可以利用 ebpf 在發送進程端將需要發送的數據跳過本機的底層 TCP/IP 協議棧,直接交給目的進程的 Socket,從而縮短數據在內核的處理路徑和時間。

上一篇《利用eBPF實現socket level重定向》,二哥從整體上介紹了 eBPF 的一個應用場景 socket level redirect:如果一臺機器上有兩個進程需要通過 loopback 設備相互收發數據,我們可以利用 ebpf 在發送進程端將需要發送的數據跳過本機的底層 TCP/IP 協議棧,直接交給目的進程的 socket,從而縮短數據在內核的處理路徑和時間。

這個流程如圖 1 所示。本篇我們來詳細看下圖 1 右側在內核里的實現細節。

圖片

圖 1:利用 ebpf 進行 socket level redirect,從而跳過 TCP/IP 協議棧和 lo 設備

先來一張全局圖,我們再依次剖析這張圖上面的關鍵知識點。

圖片

圖 2:利用 ebpf 進行 socket level redirect 全局細節圖

一、準備階段

1、插入 bpf_sock_ops 到 sock_hash map

我們的故事從圖 3 所示的插入 bpf_sock_ops 到 sock hash map 開始。這里給出一些代碼片段,完整可編譯、可執行的代碼位于 https://github.com/LanceHBZhang/socket-acceleration-with-ebpf 。另外,完整的 ebpf 程序的安裝過程還涉及到 cgroup,我就不展開來講這個話題了。

下面代碼中用到一種特殊的 map 類型:BPF_MAP_TYPE_HASH,也即本文提及的 sock_hash。在它里面存儲的是 KV 類型數據,而 value 實際對應的是數據結構 struct bpf_sock_ops。除了存儲 bpf_sock_ops,在這類 map 上還可以 attach 一個用戶編寫的 sk_msg 類型的 bpf 程序,以便來查找接收數據的 socket,attach 語句請參考 github 代碼。

static inline
void bpf_sock_ops_ipv4(struct bpf_sock_ops *skops)
{
struct sock_key key = {};
int ret;

extract_key4_from_ops(skops, &key);

ret = sock_hash_update(skops, &sock_ops_map, &key, BPF_NOEXIST);
if (ret != 0) {
printk("sock_hash_update() failed, ret: %d\n", ret);
}

printk("sockmap: op %d, port %d --> %d\n",
skops->op, skops->local_port, bpf_ntohl(skops->remote_port));
}

__section("sockops")
int bpf_sockmap(struct bpf_sock_ops *skops)
{
switch (skops->op) {
case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
if (skops->family == 2) { //AF_INET
bpf_sock_ops_ipv4(skops);
}
break;
default:
break;
}
return 0;
}

當我們通過 attach 一種 sock_ops 類型的 bpf 函數,即下面代碼中的 bpf_sockmap(),到 cgroupv2 的根路徑后,當發生一些 socket 事件,如主動建立連接或者被動建立連接等,這個時候 bpf 函數 bpf_sockmap() 將會被調用。這個過程如圖 3 執行點 1 所示,更具體地說 1發生的事情就是三次握手(SYN / SYNC-ACK / ACK),既然是三次握手,當然是與通信雙方都有關系,所以 bpf_sockmap() 函數里 bpf_sock_ops_ipv4(skops) 會被調用兩次 。

bpf_sockmap() 所做的事情非常簡單:以 source ip / source port / dest ip / dest port / family 為 key ,將 struct bpf_sock_ops 對象放入到 sock_hash 中。這個過程如圖 3 執行點 1.2 所示。為了表示 bpf_sockmap() 與 ebpf 有關,我特意在2 處畫出了 ebpf 的 logo。

上述代碼中 sock_hash_update() 函數調用看起來是在更新 sock_has map,其實它在內核中所做的事情更重要:精準動態替換 TCP 協議相關函數。

圖片

圖 3:插入 sock 到 sock_hash map

2、精準動態替換 prot

如果大家關注過內核協議棧相關數據結構的話,一定會碰到如下圖所示的幾個關鍵角色:struct file / struct socket / struct sock / struct proto 。

其中 socket 如同設計模式里常用的轉接器(adaptor),一方面它適配了面向應用層的 struct file ,另一方面又通過引用 struct sock 的方式串聯起網絡協議棧。

仔細看這張圖,我們會發現 struct sock 才是靈魂,你從它所包含的內容就能窺得一二了。struct sock 里有一個非常關鍵地方:對 Networking protocol 的引用,也即你看到的 sk_prot 。為什么說它關鍵呢?因為 sk_prot 作為一個指針所指向的結構體 tcp_prot 包含了一系列對 TCP 協議至關重要的函數,包括本文需要重點關注的 recvmsg 和 sendmsg 。從它們的名字你也能看出來它們的使用場景:用于 TCP 層接收和發送數據。

當然除了 struct tcp_prot ,sk_prot 還可能指向 struct udp_prot / ping_prot / raw_prot 。

圖片

圖 4:file / socket / sock / operations(圖片來源:開發內功修煉公眾號)

那 ebpf 在這里面干了啥事呢?非常的巧妙,它把 struct proto 里面的 recvmsg / sendmsg 等函數動態替換掉了。比如把 recvmsg 由原來的 tcp_recvmsg 替換成了 tcp_bpf_recvmsg ,而把 tcp_sendmsg 替換為 tcp_bpf_sendmsg 。

static void tcp_bpf_rebuild_protos(struct proto prot[TCP_BPF_NUM_CFGS], struct proto *base)
{
prot[TCP_BPF_BASE] = *base;
prot[TCP_BPF_BASE].close = sock_map_close;
prot[TCP_BPF_BASE].recvmsg = tcp_bpf_recvmsg;
prot[TCP_BPF_BASE].sock_is_readable = sk_msg_is_readable;

prot[TCP_BPF_TX] = prot[TCP_BPF_BASE];
prot[TCP_BPF_TX].sendmsg = tcp_bpf_sendmsg;
prot[TCP_BPF_TX].sendpage = tcp_bpf_sendpage;

prot[TCP_BPF_RX] = prot[TCP_BPF_BASE];
prot[TCP_BPF_RX].recvmsg = tcp_bpf_recvmsg_parser;

prot[TCP_BPF_TXRX] = prot[TCP_BPF_TX];
prot[TCP_BPF_TXRX].recvmsg = tcp_bpf_recvmsg_parser;
}

static int __init tcp_bpf_v4_build_proto(void)
{
tcp_bpf_rebuild_protos(tcp_bpf_prots[TCP_BPF_IPV4], &tcp_prot);
return 0;
}
late_initcall(tcp_bpf_v4_build_proto);

int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
{
// ...
/* Pairs with lockless read in sk_clone_lock() */
WRITE_ONCE(sk->sk_prot, &tcp_bpf_prots[family][config]);
return 0;
}

單純的替換其實談不上巧妙,二哥說巧妙是因為這里的替換是“精準動態替換”。首先為啥叫精準替換呢?你想啊,不是每個服務都需要通過 loopback 來進行本機進程間通信的,另外即使進程間通信是通過這種方式,也不是每一種場景都需要使用到我們這里說的 socket level redirect ,所以替換操作不能廣撒網,只能在需要的時候替換。所謂“動態替換”也即不是在編譯內核的時候就直接替換掉了,而是在有需要的時候。

那這個“需要的時候”到底是什么時候呢?

答案是將 bpf_sock_ops 存儲到 sock_hash 的時候,也即圖 3 所涉及到過程。當系統函數 bpf_sock_hash_update 被調用時,內核會調用位于 net/core/sock_map.c 中的 sock_hash_update_common 函數,在它的調用鏈中完成了替換函數 tcp_bpf_update_proto() 的調用。實際的替換結果是 sk->sk_prot 保存了替換后的版本,也即 tcp_bpf_prots[family][config],而 tcp_bpf_prots 則在很早的時候就已經初始化好了。

強調一遍,這里的替換操作僅僅與確實需要用到 socket level redirect 的 sock 有關,不會影響到其它 sock,當然被替換的 sock 其實是一對,你一定猜到了,圖 3 中 envoy 進程和 Process B 各有一個自己的 sock 參與了這次通信過程,故而它們自己的 recvmsg / sendmsg 都需要被替換掉。

二、sk_psock

在圖 3 中,我們還能看到獨立于 TX queue 和 RX queue 的新 queue:ingress_msg。通信雙方的 socket 層都各有一個這樣的 queue 。queue 里面暫存的數據用結構體 struct sk_msg 表示,sk_msg 包含了我們之前非常熟悉的 skb ,我們略過它的具體定義。在下文講述數據發送和接收流程中我們會看到 ingress_msg queue 是如何發揮作用的。

這個 queue 位于結構體 struct sk_psock {} 里面。同樣被包含在 sk_psock 里面的,還有它的小伙伴 sock / eval / cork 等。

內核代碼里面我們會看到大量的 psock->eval 這樣的語句,即為對 sk_psock 的讀寫。另外你看這個結構體里面還有函數指針 psock_update_sk_prot ,它所指向的即為上一節所說的函數 tcp_bpf_update_proto() 。

struct sk_psock {
struct sock *sk;
struct sock *sk_redir;
u32 apply_bytes;
u32 cork_bytes;
u32 eval;
struct sk_msg *cork;
struct sk_psock_progs progs;
#if IS_ENABLED(CONFIG_BPF_STREAM_PARSER)
struct strparser strp;
#endif
struct sk_buff_head ingress_skb;
struct list_head ingress_msg;
spinlock_t ingress_lock;
unsigned long state;
struct list_head link;
spinlock_t link_lock;
refcount_t refcnt;
void (*saved_unhash)(struct sock *sk);
void (*saved_close)(struct sock *sk, long timeout);
void (*saved_write_space)(struct sock *sk);
void (*saved_data_ready)(struct sock *sk);
int (*psock_update_sk_prot)(struct sock *sk, struct sk_psock *psock, bool restore);
struct proto *sk_proto;
struct mutex work_mutex;
struct sk_psock_work_state work_state;
struct work_struct work;
struct rcu_work rwork;
}

三、發送數據

在和 Process B 成功建立起 TCP 連接后,進程 envoy 開始寫數據了,如圖 5 中 2.1 所示。

正常情況下, write() 系統調用所傳遞的數據最終會由 tcp_sendmsg() 來進行 TCP 層的處理。不過還記得在“精準動態替換 prot” 一節我們提到 tcp_sendmsg() 已經被替換成 tcp_bpf_sendmsg() 了嗎?所以這里的主角其實是 tcp_bpf_sendmsg() 。

圖片

圖 5:發送數據流程

我在圖 5 中畫出了 tcp_bpf_sendmsg() 所干的幾件重要的事情:

1、執行點2.3:執行 ebp 程序

ebpf 程序其實需要老早就需要準備好,并 attach 到 sock_hash 上(再一次,這個過程請參考前文所附 github 代碼)。程序的入口非常簡單:bpf_redir()。它同樣從 struct sk_msg_md 里面提取出 source ip / source port / dest ip / dest port / family ,并以其為 key 到 sock_hash 里面找到需要重定向的目標,也即通信對端的 struct sock,并將其存放于 psock->sk_redir 處。

static inline
void extract_key4_from_msg(struct sk_msg_md *msg, struct sock_key *key)
{
key->sip4 = msg->remote_ip4;
key->dip4 = msg->local_ip4;
key->family = 1;

key->dport = (bpf_htonl(msg->local_port) >> 16);
key->sport = FORCE_READ(msg->remote_port) >> 16;
}

__section("sk_msg")
int bpf_redir(struct sk_msg_md *msg)
{
struct sock_key key = {};
extract_key4_from_msg(msg, &key);
msg_redirect_hash(msg, &sock_ops_map, &key, BPF_F_INGRESS);
return SK_PASS;
}

代碼中 msg_redirect_hash() 這個名字有點誤導人。乍一看還以為是在這里就完成了重定向過程。其實它只干了 map 查找和確認是否允許重定向這兩個操作,真正的好戲還在后頭。它的代碼不長,我直接全部貼在這里了。

BPF_CALL_4(bpf_msg_redirect_hash, struct sk_msg *, msg, struct bpf_map *, map, void *, key, u64, flags)
{
struct sock *sk;

if (unlikely(flags & ~(BPF_F_INGRESS)))
return SK_DROP;

sk = __sock_hash_lookup_elem(map, key);
if (unlikely(!sk || !sock_map_redirect_allowed(sk)))
return SK_DROP;

msg->flags = flags;
msg->sk_redir = sk;
return SK_PASS;
}

2、 執行點2.4:enqueue sk_msg

在這里,我們第一次看到 ingress_msg queue 的使用場景。

struct sk_psock {} 里面有一個成員叫 eval ,從這個關鍵詞大概就能猜到它與評估結果有關,那評估的對象是誰呢?就是 2.3 處所需要執行的 ebpf 程序。2.3 處的執行結果會放到 psock->eval 里面供后面使用。

執行結果有三種:__SK_PASS / __SK_REDIRECT / __SK_DROP 。當 psock->eval 等于我們重點關注的 __SK_REDIRECT 時,就開始了執行點 2.4 的過程:將 sk_msg 放到 psock->ingress_msg 這個 queue 里面。

需要注意的是,這個地方的 psock 還是位于發送端,也即它是屬于 envoy 進程的,那自然這個 ingress_msg queue 也是屬于 envoy 進程的。

3、執行點2.5:拉起新的 task

在執行點 2.4 把 sk_msg 放到 psock->ingress_msg 之后,內核沒有繼續往下調用其它函數,而是選擇通過 schedule_work(&psock->work) 拉起了一個異步 task,并結束了發送數據的流程。

這樣的選擇搭配 queue 非常的合理:一是為了效率,不能讓發送端(envoy)一直等待;二是為了解耦,通過 queue 來解開發送端和接收端的耦合;三是為了匹配接收端(Process B)的處理速度,進程 B 可能這個時候正好在處理其它事項來不及消費 skb。

四、接收數據

上一節執行點 2.5 我們說到,發送數據流程最終啟動了一個異步 task 。到這里為止結束了發送數據流程,而從這里也開始了接收數據的流程。整個流程涉及到的關鍵步驟我畫在圖 6 里面了:執行點 3.1 / 3.2 / 4.1 / 4.2 。

圖片

圖 6:接收數據流程

1、 執行點3.1: dequeue sk_mskg

異步 task 的切入口是函數 sk_psock_backlog() ,而它首先做的事情是拿到 envoy 所使用的 psock 指針,進而不斷地從 psock->ingress_skb 里面取出 sk_msg 進行消費。

下面代碼中 struct sk_psock *psock = container_of(work, struct sk_psock, work) 即為通過 work 拿到 psock 的邏輯,一個簡單又不失優雅的過程。

static void sk_psock_backlog(struct work_struct *work)
{
struct sk_psock *psock = container_of(work, struct sk_psock, work);
struct sk_psock_work_state *state = &psock->work_state;
struct sk_buff *skb = NULL;
//...

//...
while ((skb = skb_dequeue(&psock->ingress_skb))) {
//...
start:
ingress = skb_bpf_ingress(skb);
skb_bpf_redirect_clear(skb);
do {
ret = -EIO;
if (!sock_flag(psock->sk, SOCK_DEAD))
ret = sk_psock_handle_skb(psock, skb, off,
len, ingress);
//...
} while (len);

if (!ingress)
kfree_skb(skb);
}
end:
mutex_unlock(&psock->work_mutex);
}

2、 執行點3.2: 再次enqueue sk_msg

我們看上面代碼里面 skb_dequeue(&psock->ingress_skb) 這一行。它其實消費的是發送端 psock 里面的數據,也即 sk_msg,那消費的結果是什么呢?其實非常簡單,在執行點 3.2 把 sk_msg 塞到了接收端的 psock->ingress_msg queue 里面了。

其實你也看出來了,這一步結束后,這個新拉起的 task 也就完成了它的使命。

3、執行點4.1和4.2: 處理 skb

好了,如果你耐心地看到這個地方,大概也能猜到接下來發生什么了。執行點 4.1 處所調用的 read() 操作其實對應到 TCP 協議里面的 recvmsg 函數。recvmsg 只是一個指向函數的指針,真正的函數實現是 tcp_bpf_recvmsg() 。在文首“精準動態替換”那節,二哥已經鋪墊過啦。

五、備胎

你再回頭看下圖 2 ,會發現二哥在圖中從 tcp_bpf_sendmsg() 以及 tcp_bpf_recvmsg() 分別拉了一條虛線到 tcp_sendmsg() 和 tcp_recvmsg()。我管 tcp_sendmsg() 和 tcp_recvmsg() 叫備胎。因為 tcp_bpf_sendmsg() 以及 tcp_bpf_recvmsg() 在處理一些異常情況時就直接走老路了。

static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int nonblock, int flags, int *addr_len)
{
// ...
psock = sk_psock_get(sk);
if (unlikely(!psock))
return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
}

圖片

圖 7:備胎 tcp_sendmsg() 和 tcp_recvmsg()

責任編輯:姜華 來源: 二哥聊云原生
相關推薦

2023-03-11 11:19:07

loopbackSocket

2010-12-14 15:07:15

ICMP路由重定向

2009-11-23 18:39:17

PHP重定向

2011-06-15 14:43:43

301重定向

2009-12-01 11:04:10

PHP重定向網頁

2025-07-14 00:10:01

2014-09-24 11:01:10

多路鏡像流量聚合鏡像流量

2022-08-27 10:53:15

C語言Linux內核

2025-10-14 09:19:21

execveELF內核

2020-12-09 11:10:12

shellLinux管道

2017-01-04 13:42:35

MINIFILTER文件重定向源碼

2017-01-19 19:14:20

Linux重定向命令

2010-03-09 16:11:59

Linux重定向

2022-09-02 08:03:44

IO程序網卡

2010-07-13 14:10:44

ICMP協議

2009-12-03 17:57:35

PHP重定向代碼

2020-06-04 08:36:55

Linux內核線程

2021-03-28 08:32:58

Java

2017-12-06 10:15:27

跳轉機制Chrome

2020-07-27 07:41:23

Linux重定向數據流
點贊
收藏

51CTO技術棧公眾號

亚洲精品不卡在线| 亚洲精品欧美在线| 国产91精品高潮白浆喷水| 精品无码在线视频| 经典三级一区二区| 国产视频一区二区三区在线观看| 国产主播喷水一区二区| 国产亚洲第一页| 久久av超碰| 欧美一级艳片视频免费观看| 777精品久无码人妻蜜桃| 成人免费视频| 国产精品系列在线播放| 欧美精品videosex牲欧美| 国产精久久一区二区三区| 成人综合日日夜夜| 日韩欧美视频一区二区三区| 这里只有精品66| 亚洲人午夜射精精品日韩| 久久电影网站中文字幕| 55夜色66夜色国产精品视频| 亚洲综合图片一区| 日韩精品导航| 日韩欧美色综合网站| 亚洲精品高清无码视频| 大桥未久在线播放| 18欧美亚洲精品| 日本不卡一二三区| 天天操天天操天天干| 国产在线不卡一区| 国产精品久久久久久久久免费看| 日韩三级小视频| 一区二区三区毛片免费| 亚洲最新视频在线| 免费污网站在线观看| 极品一区美女高清| 欧美成人video| 亚洲午夜激情影院| 久久av日韩| 在线视频欧美区| 成人黄色av片| 51精品视频| 一区二区三区在线视频观看58| 亚洲 国产 欧美一区| 国内在线免费高清视频| 99久久精品一区| 国产乱码精品一区二区三区不卡| 国产jzjzjz丝袜老师水多 | 久在线观看视频| 成全电影大全在线观看| 亚洲自拍偷拍网站| 欧美一级免费播放| 成人免费高清观看| 亚洲国产精品一区二区久久恐怖片| 免费看黄色a级片| 性欧美高清come| 一区二区三区小说| 日韩av在线播放不卡| 成人黄色动漫| 欧美视频一二三| 别急慢慢来1978如如2| 在线国产成人影院| 欧美日韩视频在线观看一区二区三区| 999精品视频在线| 国产成人a视频高清在线观看| 欧美无砖专区一中文字| 五月激情婷婷在线| 日本一区影院| 亚洲国产精品一区二区三区| 玖草视频在线观看| 日韩极品一区| 免费成人高清视频| 天天操天天射天天爽| 午夜亚洲一区| 国产精品免费在线免费| 这里只有精品免费视频| 精品亚洲成av人在线观看| 91成人在线看| 精品av中文字幕在线毛片| 中文字幕国产一区| 日韩一级免费看| 天堂√中文最新版在线| 欧美亚洲综合久久| 色哟哟在线观看视频| 啪啪激情综合网| 色老头一区二区三区| 久草视频免费在线| 久久亚洲美女| 97人人模人人爽视频一区二区| 香蕉视频免费看| 亚洲欧洲国产日本综合| 国产 日韩 亚洲 欧美| 日本黄色一区| 精品人在线二区三区| 亚洲人成人无码网www国产| 亚欧美无遮挡hd高清在线视频| 久久久伊人日本| 中文字幕av片| 成人一区二区视频| 五月天久久狠狠| a在线视频v视频| 欧美日韩免费视频| 中文字幕日韩三级片| av中文字幕一区二区| 久久久久久久久久国产| 中文字幕一区二区人妻| av成人动漫在线观看| 裸体裸乳免费看| 92国产精品| 日韩一级大片在线观看| 国产探花视频在线播放| 精品999成人| 成人免费网站在线观看| 天天舔天天干天天操| 亚洲日本va午夜在线影院| 国产精品第12页| 中文字幕一区二区三区中文字幕| 中文字幕一精品亚洲无线一区 | 好看不卡的中文字幕| 国产精品日韩欧美综合| 四虎永久在线观看| 亚洲最新在线观看| a级大片免费看| 成人在线国产| 国产成人欧美在线观看| 日av在线播放| 五月天丁香久久| 四虎永久免费观看| 亚洲一区二区| 成人综合国产精品| 麻豆最新免费在线视频| 欧美丝袜丝交足nylons图片| 四虎永久免费影院| 国产毛片一区| 久久久99爱| 国产欧洲在线| 亚洲国产精品热久久| 久久久精品人妻一区二区三区四| 国产一区二三区| 一区二区三区的久久的视频| 日韩网站中文字幕| 国产一区二区三区在线观看网站| 国产免费av一区| 久久欧美一区二区| 日韩av在线综合| 九九免费精品视频在线观看| 日本精品免费观看| 欧美人体大胆444www| 日韩欧美中文字幕在线播放| 亚洲第一成人网站| 日本欧美一区二区三区乱码| 亚洲成人在线视频网站| 成人免费在线观看视频| 亚洲午夜av久久乱码| 亚洲综合成人av| 中文字幕va一区二区三区| 亚洲福利精品视频| 久久综合99| 51国偷自产一区二区三区的来源| 日本精品600av| 精品国产3级a| 手机看片久久久| 中文字幕乱码亚洲精品一区| 五月婷婷六月丁香激情| 亚洲国产精品成人| 国产精品区二区三区日本| 午夜激情电影在线播放| 国产亚洲欧美日韩美女| 一级黄色小视频| 樱桃国产成人精品视频| 男男做爰猛烈叫床爽爽小说| 新狼窝色av性久久久久久| 色99中文字幕| 日本免费一区二区三区视频| 2019中文在线观看| 在线视频1区2区| 日韩精品一区二区三区中文不卡| 黄色激情视频在线观看| 国产日产欧产精品推荐色| 91插插插影院| 日韩一级精品| 亚洲一区二区三区精品视频| 91精品啪在线观看国产手机| 青青久久av北条麻妃海外网| 米奇777四色精品人人爽| 精品美女在线播放| 波多野结衣人妻| 亚洲乱码中文字幕| 3d动漫精品啪啪一区二区下载 | 日韩一级av毛片| 国产又黄又大久久| 黄色网页免费在线观看| 久久网站免费观看| 久久精品国产理论片免费| 日韩成人一区| 欧美孕妇与黑人孕交| 91网址在线观看| 亚洲天堂免费观看| 国产激情无套内精对白视频| 色老汉一区二区三区| 免费麻豆国产一区二区三区四区| 国产日产欧美一区二区视频| youjizz.com国产| 久久www免费人成看片高清| 久久精品视频16| 欧美激情偷拍| 一区二区三区不卡在线| 国产中文字幕一区二区三区| 国产在线精品一区| 国产精品成人3p一区二区三区| 日本一本a高清免费不卡| 日本资源在线| 久久精品亚洲94久久精品| 加勒比一区二区三区在线| 精品播放一区二区| 国产精品污视频| 欧美系列在线观看| 黄色在线观看国产| 亚洲 欧美综合在线网络| √天堂中文官网8在线| 亚洲国产精品黑人久久久| 国产ts丝袜人妖系列视频| 国产精品一卡二卡在线观看| 岛国av在线免费| 日韩精品乱码免费| 国产精品亚洲αv天堂无码| 亚洲人www| 农民人伦一区二区三区| 国产精品国码视频| 国产日韩欧美大片| 国产精品久久久久无码av| 亚洲精品乱码视频| 欧美日韩第一| 婷婷四房综合激情五月| 国产亚洲电影| 日韩激情视频| 成人久久一区| 亚洲二区三区四区| 成人午夜国产| 亚洲欧洲一二三| 久久激情电影| 亚洲午夜精品久久久中文影院av| 韩日一区二区三区| 日韩中文字幕一区二区| 欧美精品色图| 亚洲免费视频一区| 97国产精品| 99久re热视频精品98| 在线看片不卡| 日韩在线视频在线| 亚洲第一伊人| 免费黄色日本网站| 老**午夜毛片一区二区三区| 天天操天天摸天天爽| 蜜桃av一区二区| 天天操精品视频| 国产aⅴ综合色| 三级视频网站在线观看| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 国产一二在线播放| 欧美中文字幕视频| 色综合天天色| 川上优av一区二区线观看| 人人九九精品视频| 国产在线一区二区三区四区| 免费久久精品| 亚洲图片小说在线| 狠久久av成人天堂| 成熟了的熟妇毛茸茸| 日韩av一区二区三区四区| 亚洲欧美日本一区二区三区| 国产91精品一区二区麻豆亚洲| 亚洲一区二区三区综合| 欧美国产一区视频在线观看| 中文字幕电影av| 亚洲第一成人在线| jizz国产在线| 日韩免费高清视频| 九色视频成人自拍| 欧美成人合集magnet| 天天综合av| 91精品国产综合久久久久久久久| 成人爽a毛片| 日本视频一区在线观看| 欧美在线国产| 欧美日韩在线不卡视频| 狠狠色丁香久久婷婷综合_中| 一级黄色免费视频| 国产嫩草影院久久久久| 久久亚洲成人av| 欧美日韩在线三区| 天天av天天翘| 欧美成人午夜免费视在线看片| 小h片在线观看| 91探花福利精品国产自产在线| 婷婷综合电影| 在线观看18视频网站| 久热精品在线| 日本美女视频网站| 亚洲欧洲日产国码二区| 成人午夜视频在线播放| 日韩一二三区视频| 日本视频在线免费观看| 2020国产精品视频| 涩爱av色老久久精品偷偷鲁| 特级西西444www大精品视频| 99精品国产在热久久| 久久精品国产露脸对白| 久久久影视传媒| 国产精彩视频在线| 91精品国产欧美一区二区| 二区三区在线播放| 欧美一级免费视频| 久久久久观看| youjizz.com在线观看| 极品销魂美女一区二区三区| 亚洲日本精品视频| 欧美视频在线免费| 日本精品999| 欧美大片在线看| 91麻豆精品一二三区在线| 欧美日韩中文国产一区发布| 99在线观看免费视频精品观看| 久久精品无码一区二区三区毛片| 欧美国产精品一区| 精品国产乱子伦| 亚洲精品中文字| 伊人网在线播放| 精品无人区一区二区三区| 精品电影一区| 亚洲图片欧美另类| 亚洲伊人色欲综合网| 国产成人精品a视频| 久久久精品一区二区| 中文成人激情娱乐网| 黄色高清视频网站| 国产在线精品一区二区夜色| 大地资源高清在线视频观看| 欧美日韩国产中文| 麻豆最新免费在线视频| 亚洲一区二区三区xxx视频| 亚洲一区二区三区无吗| 天天色天天干天天色| 亚洲美女精品一区| 亚洲欧美另类综合| 性欧美长视频免费观看不卡| 日本国产精品| 国产精品wwwww| 中文字幕成人在线观看| 91成品人影院| 欧美大胆在线视频| 国产精品久久久网站 | 蜜臀久久99精品久久久久宅男| 高清国产在线观看| 欧美日韩一卡二卡三卡 | 日本午夜人人精品| 欧美色就是色| 日本黄色的视频| 亚洲女爱视频在线| 乱色精品无码一区二区国产盗| 国产69精品99久久久久久宅男| 婷婷国产精品| 中文字幕第38页| 亚洲人成网站影音先锋播放| 亚洲精品无amm毛片| 26uuu日韩精品一区二区| 国产毛片一区二区三区| www.久久91| 亚洲网友自拍偷拍| 国产精品影院在线| 51成人做爰www免费看网站| 在线日本成人| 黄色片网站免费| 欧美一区二区三区在线视频| 色戒汤唯在线观看| 亚洲一区二区三区加勒比 | 高清国产在线一区| 香蕉久久夜色精品| 香蕉久久久久久久| 欧美成人综合网站| 日韩精品一区二区三区| 国产av第一区| 91香蕉国产在线观看软件| 国产九色91回来了| 久久久久久午夜| 欧美日韩中文字幕一区二区三区| 韩国三级丰满少妇高潮| 欧美性猛交视频| 亚洲性图自拍| 日本一区免费| av电影在线观看一区| 中文字幕777| 国产91精品久久久久| 香蕉综合视频| 日本少妇xxxxx| 精品成a人在线观看| 欧美亚洲福利| 国产偷人视频免费| 亚洲精品videosex极品| yiren22综合网成人|