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

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

云計算 云原生
如果一臺機器上有兩個進程需要通過 loopback 設備相互收發數據,我們可以利用 ebpf 在發送進程端將需要發送的數據跳過本機的底層 TCP/IP 協議棧,直接交給目的進程的Socket,從而縮短數據在內核的處理路徑和時間。

大家好,我是二哥。最近一直在研究 eBPF ,隨著研究的深入,我發現之前寫的這篇文章有點問題,所以重新修改了一下。圖也重新畫了,并添加了一些與 sidecar-less 相關的額外內容。

下面是正文。

圖片

上一篇《??利用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、準備階段

(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 所示,更具體地說 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 有關,我特意在 1.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 都需要被替換掉。

2、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; // 當前 sock
struct sock *sk_redir; // 通信對端 sock,也即 redirect target
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;
}

3、發送數據

在和 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 里面。

函數調用鏈如下所示:

tcp_bpf_sendmsg() -> tcp_bpf_send_verdict() -> tcp_bpf_sendmsg_redir(psock->sk_redir) -> bpf_tcp_ingress() -> sk_psock_queue_msg()

需要注意的是,這個過程中 ingress_msg queue 是屬于 ProcessB 進程的。也就是說,在這一步,數據包被直接放入了對端進程的 queue 中去了。

(3)執行點2.5:喚醒 ProcessB

在執行點 2.4 把 sk_msg 放到 Process B 的 psock->ingress_msg 之后,內核沒有繼續往下調用其它函數,直接通過 sk->sk_data_ready() 來喚醒在對端 sock 上等待數據而睡眠的進程 ProcessB。sk_data_ready 其實是個函數指針,真正被調用的函數是 sock_def_readable() 。

4、接收數據

上一節執行點 2.5 我們說到,發送數據流程最終通過 sk_data_ready() 來喚醒 Process B 。那么到這里為止結束了發送數據流程,而從這里也開始了接收數據的流程。整個流程涉及到的關鍵步驟我畫在圖 6 里面了:執行點 3.1 / 3.2 / 3.3 。

(1)執行點3.2:tcp_bpf_recvmsg

3.1 處的 read() 函數最終會使得 tcp_bpf_recvmsg() 被調用,而不是 tcp_recvmsg() 。原因在文首“精準動態替換”那節,二哥已經做過鋪墊過。而 tcp_bpf_recvmsg() 所做的工作其實不復雜,消費 ingress_msg queue 里面的數據。

圖片

圖 6:接收數據流程

5、備胎

你再回頭看下圖 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()

6、sock level 加速 + 跨 network ns = sidecarless

圖片

圖 8:socket level acceleration

講到這里,我們再來看下本篇所描述的對象:socket level redirection。

網絡包直接通過一個新的 queue 就發送到對端去了,中間沒有經過復雜的 TCP 協議棧,更沒有使用到 IP 層的路由表、iptables 等耗時費力的組件。

這樣做帶來了一個非常簡單直接和粗暴的好處:socket level acceleration 。也就是說同一個主機上,進程間通信可以通過 socket level redirection 來使性能得到大幅提升。

如果你熟悉基于 sidecar 的 Service Mesh 的話,一定知道一個 Pod 內部存在基于 loopback 的進程間通信。我們也聊過即使通信雙方是走的 Loopback 這個虛擬的設備,從而省去了與真實網絡設備相關的排隊(Queue Descipline)等待時間,也省去了網絡包離開本機后的網絡延遲,但網絡包在 TCP/IP 協議棧上該走的路可一步都少不了,萬一路由表和 iptables 設置得比較復雜,那依舊需要在路由和 net filter 上面花去很多時間。

socket level acceleration 的出現可以說完美解決了 sidecar 所面臨的網絡剛性開銷難題。

它帶來的好處僅僅如此嗎?不!socket level acceleration 還有一個厲害的地方:它可以跨 network namespace 傳遞網絡包。這表示假如圖 8 里面 envoy 和 Process B 分別處于各自的 network ns 里面,也能充分利用 socket level acceleration 來完成高性能通信。為了突出這一點,圖 8 右側我把 Process B 所屬的 network ns 單獨畫在了一個灰色框里面。

高性能 + 跨 network ns,多么美麗的組合。Cilum 基于它打造出了 sidecarless 的 Service Mesh 。如圖 9 所示。注意看哦,圖中 Layer 7 的 Proxy 是獨立于每個 Pod 的,也是被這個 Work Node 上所有的 Pod 所共享的。

圖片

圖 9:基于 socket level redirection 所實現的 sidecarless Service Mesh

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

2023-01-27 18:08:35

eBPF云原生

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文件重定向源碼

2022-09-02 08:03:44

IO程序網卡

2010-07-13 14:10:44

ICMP協議

2017-01-19 19:14:20

Linux重定向命令

2010-03-09 16:11:59

Linux重定向

2020-06-04 08:36:55

Linux內核線程

2009-12-03 17:57:35

PHP重定向代碼

2020-07-27 07:41:23

Linux重定向數據流

2010-12-31 13:35:25

文件夾重定向

2021-03-28 08:32:58

Java
點贊
收藏

51CTO技術棧公眾號

秋霞午夜av一区二区三区| 偷拍一区二区| 亚洲一区精品在线| 极品日韩久久| 亚洲一级视频在线观看| 欧美在线不卡| 精品视频久久久久久久| 久热精品在线观看视频| 青青青草视频在线| 91久色porny| 91久久久在线| 日本午夜视频在线观看| 色综合久久网| 日韩经典一区二区三区| 免费黄频在线观看| xx欧美xxx| 亚洲精品国产视频| 日韩久久不卡| 天天操天天干天天| 久久99久久精品欧美| 欧美一级电影免费在线观看| 麻豆视频在线免费看| 日韩成人动漫在线观看| 3atv在线一区二区三区| 黄色片久久久久| 毛片网站在线看| 国产精品久久久久久久裸模| 久久艳妇乳肉豪妇荡乳av| 精品国产18久久久久久| 蜜臀av性久久久久蜜臀aⅴ| 午夜精品福利在线观看| 欧美三级在线免费观看| 色婷婷色综合| 一区二区三区精品99久久| 国产 xxxx| 亚洲一区二区三区日本久久九| 欧美三级日韩三级| 黄色免费视频大全| 蜜臀av国内免费精品久久久夜夜| 亚洲天堂2016| 亚洲伊人婷婷| 91sp网站在线观看入口| 久久久精品综合| 欧美激情专区| 亚洲欧美日韩免费| 成人激情黄色小说| 福利视频一区二区三区| 国产99对白在线播放| 久草中文综合在线| 国产精品一区二区三区久久久| 久久精品视频7| 国产精品久久久久9999高清| 国内精品一区二区三区四区| 黄色一级视频免费观看| 午夜精品剧场| 欧美日本高清视频| 青娱乐国产精品| 欧美/亚洲一区| 欧美日韩福利视频| 免看一级a毛片一片成人不卡| 亚洲一区二区三区| 美日韩精品免费视频| 欧美第一页在线观看| 综合天天久久| 欧美激情一区二区三区成人 | 精品国模在线视频| 特黄一区二区三区| 91亚洲一区| 欧美另类极品videosbest最新版本 | 亚洲天堂男人网| 麻豆精品一区二区av白丝在线| 国产精品福利久久久| 最近日韩免费视频| 久久精品国产久精国产| 国产综合福利在线| 精品人妻少妇嫩草av无码专区| 国产精品影音先锋| 国产精品v欧美精品∨日韩| 少妇高潮一区二区三区99小说| 成人午夜av影视| 欧美高清性xxxxhd| 欧洲不卡视频| 亚洲午夜在线电影| 国产精品宾馆在线精品酒店| 456亚洲精品成人影院| 欧美日韩国产天堂| 色综合久久久无码中文字幕波多 | 欧美xxxx黑人又粗又长精品| 国产69精品久久app免费版| 中文字幕日韩一区| 国产精品69久久久| 先锋欧美三级| 欧美一区二区日韩| 大尺度做爰床戏呻吟舒畅| 久久av电影| 欧美大奶子在线| 91porny在线| 狠狠色丁香久久婷婷综合_中| 岛国视频一区| 亚洲s色大片| 亚洲国产一区二区a毛片| 六月丁香婷婷在线| 久久伊人精品| 一区二区日韩精品| 国产一级性生活| 欧美aⅴ一区二区三区视频| 999国产视频| 亚洲精品传媒| 欧美性猛交xxxx免费看| 国产探花在线看| 欧美久久香蕉| 欧美成在线视频| 久久久国产免费| 不卡视频免费播放| 亚洲天堂av免费在线观看| 欧美a级在线观看| 日韩女优制服丝袜电影| 国产精品无码无卡无需播放器| 在线看片日韩| 亚洲aⅴ男人的天堂在线观看| 欧美黄色小说| 亚洲国产欧美日韩另类综合| 一起操在线视频| 国产一区二区三区日韩精品| 欧美激情aaaa| 国产又粗又黄又爽的视频| 久久精品男人的天堂| 男人日女人视频网站| 久久久国产精品入口麻豆| 伊人av综合网| 亚洲天堂视频在线播放| 91视视频在线直接观看在线看网页在线看| 992tv成人免费观看| 福利一区在线| 亚洲视频在线观看网站| 97久久久久久久| 成人黄页在线观看| 波多野结衣av一区二区全免费观看| 全球中文成人在线| 亚洲网站视频福利| 免费的毛片视频| 久久久久99精品国产片| 国产高清精品在线观看| 秋霞综合在线视频| 57pao国产精品一区| 日本波多野结衣在线| 亚洲成人免费影院| 免费成人蒂法网站| 日韩亚洲精品在线| 久久亚洲一区二区| 成人影院网站| 国产亚洲精品日韩| 中文字字幕在线观看| 国产女主播视频一区二区| 激情婷婷综合网| 自拍自偷一区二区三区| 国产精品999999| av午夜在线| 欧美精品123区| 永久久久久久久| 成人黄色网址在线观看| 99视频在线免费播放| 欧美午夜18电影| 国产成人精品综合| 91精品大全| 日韩欧美亚洲国产精品字幕久久久| 亚洲国产精品免费在线观看| 粉嫩绯色av一区二区在线观看| cao在线观看| 一区二区三区日本久久久| 国产成人午夜视频网址| 在线免费黄色| 欧美一区二区播放| 日韩av一区二区在线播放| 91亚洲精华国产精华精华液| 久久久久久久激情| 久久一区91| 99热国产免费| 原纱央莉成人av片| 日韩在线视频免费观看| 亚洲AV无码乱码国产精品牛牛 | 97国产一区二区| 99久久激情视频| 亚洲女同另类| 久久亚洲国产精品日日av夜夜| 九九热这里有精品| 欧美黄色片免费观看| 国产香蕉在线| 日韩一区二区在线播放| www日韩精品| 国产精品福利一区二区三区| 亚洲一二三四五| 日本网站在线观看一区二区三区| 性做爰过程免费播放| 欧美激情15p| 国产日韩欧美综合| 在线观看涩涩| 久久亚洲精品一区二区| 深夜福利在线视频| 在线不卡欧美精品一区二区三区| 国产精品自拍视频一区| 国产精品免费视频一区| 伊人网综合视频| 国产一区啦啦啦在线观看| 国产二区视频在线播放| 一区二区日韩欧美| 欧美在线视频二区| 超碰精品在线观看| 91精品久久久久久综合乱菊 | 91精品久久久久久久久久久久久| √天堂8资源中文在线| 日韩中文字幕在线视频| 亚洲人成色777777老人头| 91精品在线免费| 中文字幕久久熟女蜜桃| 欧美日韩国产页| 久久黄色免费视频| 中文字幕一区二| 制服 丝袜 综合 日韩 欧美| 懂色一区二区三区免费观看| 超碰成人在线播放| 丝袜诱惑亚洲看片| a√天堂在线观看| 激情欧美亚洲| 国产精品自拍合集| 婷婷亚洲综合| 亚洲精品一区二区三区蜜桃久| 欧美午夜18电影| 国内视频一区| 果冻天美麻豆一区二区国产| 91久热免费在线视频| 精品69视频一区二区三区| 欧美专区福利在线| 9765激情中文在线| 欧美激情喷水视频| 性欧美video高清bbw| 久久精品久久精品亚洲人| av大片在线播放| 一区二区三区四区在线观看视频| 欧美在线观看在线观看| 亚洲国产美女精品久久久久∴| 亚洲第一天堂在线观看| 日韩一区二区三区在线视频| 国产原创中文av| 欧美高清性hdvideosex| 国产免费久久久| 欧美一级在线免费| 午夜精品久久久久久久99| 欧美一区二区三区免费视频| 99草在线视频| 日韩女同互慰一区二区| 亚洲av无码乱码国产麻豆| 欧美成人精品3d动漫h| 亚洲精品一区二区三区区别| 亚洲国产91色在线| 青青免费在线视频| 国产一区二区激情| 男人天堂久久久| 欧美日韩xxxxx| √8天堂资源地址中文在线| 欧美一区二区.| 成人在线视频观看| 91久久极品少妇xxxxⅹ软件| 亚洲日本一区二区三区在线| 国产精品v欧美精品v日韩精品| 啪啪激情综合网| 视频一区三区| 在线一区电影| 欧美 日韩 国产在线观看| 久久久天天操| 视频二区在线播放| 国产成人免费高清| 丰满少妇在线观看资源站| 国产丝袜欧美中文另类| frxxee中国xxx麻豆hd| 亚洲精品日产精品乱码不卡| 国产亚洲精品久久久久久打不开| 狠狠躁夜夜躁人人躁婷婷91| 羞羞色院91蜜桃| 日韩写真欧美这视频| 青青国产在线| 日韩在线观看免费| 98色花堂精品视频在线观看| 国产精品www| 欧美1区2区3| 欧美精品久久久| 一本一本久久a久久综合精品| 人人妻人人添人人爽欧美一区| 日韩成人精品在线| 亚洲美女高潮久久久| 亚洲国产精品99久久久久久久久| 国产精品视频一区二区三| 精品久久久视频| 一级片aaaa| 亚洲精品第一国产综合精品| 黄色精品免费看| 538国产精品一区二区在线| 五月天色综合| 欧美一级爱爱| 亚洲精品色图| 天天av天天操| 欧美国产日韩亚洲一区| 久久久久久久99| 欧美精品自拍偷拍动漫精品| 日本精品专区| 欧美黑人xxx| 99精品视频在线免费播放| 麻豆传媒一区| 欧美午夜影院| 欧美视频国产视频| 国产亚洲午夜高清国产拍精品| 久久久精品国产sm调教网站| 欧美日韩一区二区不卡| 四虎在线视频免费观看| 欧美成人午夜免费视在线看片| 日韩欧美精品电影| 精品伦精品一区二区三区视频| 中文字幕亚洲精品乱码| 香港日本韩国三级网站| 久久影院午夜片一区| 久久9999久久免费精品国产| 欧美精品v国产精品v日韩精品| 国产日韩精品在线看| 668精品在线视频| 999国产精品一区| 国产香蕉一区二区三区| 九九国产精品视频| 激情五月深爱五月| 色狠狠一区二区| 免费在线性爱视频| 国产91精品久久久久| 欧美理伦片在线播放| 青草青青在线视频| 成人精品视频一区| 国产亚洲精久久久久久无码77777| 日韩三级av在线播放| www在线免费观看视频| 亚洲xxxx3d| 欧美色图麻豆| 韩国黄色一级片| 亚洲国产精品一区二区尤物区| 精品国产伦一区二区三| 欧美情侣性视频| 日韩中文字幕在线一区| 国产欧美精品aaaaaa片| 高清视频一区二区| 久久综合久久鬼| 亚洲国产99精品国自产| 成人观看网址| 欧美日韩成人一区二区三区| 日韩二区三区四区| 欧美乱大交做爰xxxⅹ小说| 欧美日韩精品一区二区三区蜜桃| 亚洲免费视频一区二区三区| 成人精品视频在线| 欧美在线三级| 日本三级日本三级日本三级极| 午夜精品久久久久久久99水蜜桃| 五月婷婷丁香网| 国产精品99久久久久久白浆小说| 成人情趣视频网站| www,av在线| 亚洲高清视频中文字幕| 青青视频在线观| 国产精品视频最多的网站| 一区二区三区四区日韩| 香蕉视频污视频| 欧美色图在线视频| 夜级特黄日本大片_在线| 99久久精品无码一区二区毛片 | 综合分类小说区另类春色亚洲小说欧美| 国产精品欧美久久久久天天影视 | 欧美日韩视频网站| 一区二区三区四区视频在线观看| 国产乱码精品一品二品| 亚洲精品国产精品乱码| 在线观看视频亚洲| 成人av资源网址| 免费黄色一级网站| 一区二区三区四区在线播放| 天堂а√在线8种子蜜桃视频 | 黄色片久久久久| 国产精品国产a| 天天干在线观看| 国产日韩精品在线播放| 精品福利av| 91ts人妖另类精品系列| 亚洲国产精品资源| 99久久久国产| 国产在线青青草| 亚洲欧美一区二区三区国产精品 | 国产精品污视频| 97在线免费视频| 婷婷久久国产对白刺激五月99| 国产综合内射日韩久| 欧美日韩一二区| 黄色aa久久| 伊人再见免费在线观看高清版| 国产亚洲成aⅴ人片在线观看| 国产av无码专区亚洲av麻豆|