DPDK — TestPMD

目錄

前文列表

DPDK — 安裝部署

DPDK APP 的指令行參數

DPDK App 都是可以接受輸入指令行參數的,如下:

./rte-app -c COREMASK [-n NUM] [-b <domain:bus:devid.func>] \
          [--socket-mem=MB,...] [-m MB] [-r NUM] [-v] [--file-prefix] \
          [--proc-type <primary|secondary|auto>] [-- xen-dom0]
  • -c COREMASK:要運行的內核的十六進制掩碼。注意,平臺之間編號可能不同,需要事先確定。
  • -n NUM:每個處理器 Socket 的內存通道數目。
  • -b domain:bus:devid.func:端口(網卡)黑名單,避免 EAL 使用指定的 PCI 設備。
  • –use-device:僅使用指定的以太網設備。使用逗號分隔 [domain:]bus:devid.func 值,不能與 -b 選項一起使用。
  • –socket-mem:從特定的處理器 Socket 上的 hugepage 分配內存。建議使用。
  • -m MB:從 hugepage 分配內存,不考慮處理器 Socket。不建議使用。
  • -r NUM:內存數量。
  • -v:顯示啓動時的版本信息。
  • –huge-dir:掛載 hugetlbfs 的目錄。
  • –file-prefix:用於 hugepage 文件名的前綴文本。
  • –proc-type:App 的類型。
  • –xen-dom0:支持在 Xen Domain0 上運行,但不具有 hugetlbfs 的程序。
  • –vmware-tsc-map:使用 VMware TSC 映射而不是本地 RDTSC。
  • –base-virtaddr:指定基本虛擬地址。
  • –vfio-intr:指定要由 VFIO 使用的中斷類型(如果不支持 VFIO,則配置無效)。

注 1:其中 -c 是強制性的,其他爲可選配置。
注 2:選項 --proc-type 和 --file-prefix 用於運行多個 DPDK 進程。

指定 DPDK App 使用的 lcore(邏輯核)

-c coremask 選項參數可以使用指定的 lcore 來運行 DPDK 應用程序,是一個十六進制的掩碼,掩碼的每個位對應於 Linux 提供的 lcore ID。例如:-c f 表示 1111 對應 lcore 0, 1, 2, 3;-c 1 表示 01 對應 lcore 0;-c 6 標識 110 對應 lcore 1, 2。可以看出,掩碼的二進制和 lcore 的順序是調轉的,這裏需要注意。

在指定 lcpu mask 參數之前,需要了解平臺的 CPU 佈局,可以通過 hwloc 來查看:

yum install hwloc -y

在這裏插入圖片描述
如果沒有圖形化界面則使用指令:

$ lstopo-no-graphics
Machine (9835MB)
  Package L#0 + L3 L#0 (16MB) + L2 L#0 (4096KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0)
  Package L#1 + L3 L#1 (16MB) + L2 L#1 (4096KB) + L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#1)
  Package L#2 + L3 L#2 (16MB) + L2 L#2 (4096KB) + L1d L#2 (32KB) + L1i L#2 (32KB) + Core L#2 + PU L#2 (P#2)
  Package L#3 + L3 L#3 (16MB) + L2 L#3 (4096KB) + L1d L#3 (32KB) + L1i L#3 (32KB) + Core L#3 + PU L#3 (P#3)
  Package L#4 + L3 L#4 (16MB) + L2 L#4 (4096KB) + L1d L#4 (32KB) + L1i L#4 (32KB) + Core L#4 + PU L#4 (P#4)
  Package L#5 + L3 L#5 (16MB) + L2 L#5 (4096KB) + L1d L#5 (32KB) + L1i L#5 (32KB) + Core L#5 + PU L#5 (P#5)
  Misc(MemoryModule)
  HostBridge L#0
    PCI 8086:7010
    PCI 1013:00b8
    PCI 1af4:1000
    PCI 1af4:1001
    3 x { PCI 15b3:1018 }

也可以使用 DPDK 自帶的 CPU layout 工具:

$ cd ${RTE_SDK}/usertools/

$ ./cpu_layout.py
======================================================================
Core and Socket Information (as reported by '/sys/devices/system/cpu')
======================================================================

cores =  [0]
sockets =  [0, 1, 2, 3, 4, 5]

       Socket 0    Socket 1    Socket 2    Socket 3    Socket 4    Socket 5
       --------    --------    --------    --------    --------    --------
Core 0 [0]         [1]         [2]         [3]         [4]         [5]

指定 DPDK App 使用的大頁內存

建議使用 --socket-mem 選項指定 DPDK App 使用的大頁內存與預留的 hugepage 內存一致。例如:–socket-mem=0,512 指定在 Socket0(一般就是 NUMA0)上預留 512MB 內存(從 Socket1 上預留的大頁內存中分配)。

如果沒有指定,則由 DPDK App 在啓動時自動完成確定。如果指定的內存大小超出了預留值,則 DPDK App 啓動失敗。如果指定的內存大小小於預留值,也可能會導致 DPDK App 啓動失敗,尤其是在使用 -m(不建議使用)選項的時候,這裏需要注意。

隔離 DPDK App 使用 lcore

雖然 DPDK App 已經是綁定核心的,但 Linux 調度程序仍然會使用這些 lcore 來運行其他的任務,所以爲了防止在這些核上運行額外的工作負載,可以使用 isolcpus Linux 內核參數來將其與通用的 Linux 調度程序隔離開來。

isolcpus=2,4,6

使用基於 Intel VT-d 的 Linux IOMMU Pass-Through 來運行 DPDK App

要在 Linux 內核中啓用 Intel VT-d 硬件輔助的 IO 技術,必須配置一系列內核選項,包括:

  • IOMMU_SUPPORT
  • IOMMU_API
  • INTEL_IOMMU

要使用 Intel VT-d 來運行 DPDK App,在使用 igb_uio 驅動時,Grub 參數必須攜帶 iommu=pt 參數。 這使得主機可以直接通過 DMA 重映射查找網卡的存儲空間。另外,如果內核中沒有設置 INTEL_IOMMU_DEFAULT_ON 參數,那麼還必須要使用到 intel_iommu=on 參數。這可以確保 Intel IOMMU 被正確初始化。而在使用 vfio-pci 驅動程序時,則直接同時使用 iommu=pt intel_iommu=on

TestPMD

TestPMD 的本質是一個使用 DPDK 庫實現的 DPDK Application,作用是在以太網端口之間轉發數據包。通過 TestPMD 運行時的命令行,我們可用於配置端口(Port)之間的數據包轉發和網卡(Network Interface)支持的其他功能。此外,我們還可以用 TestPMD 來嘗試一些不同的驅動程序的功能,例如:RSS、過濾器和 Intel Ethernet Flow Director(以太網流量控制器)。

TestPMD 支持以下 3 種不同的轉發模式:

  • 輸入/輸出模式(Input/Output mode):通常也被稱爲 IO 模式,是最常用的轉發模式,也是 TestPMD 啓動時的默認模式。在該模式下,CPU 從一個端口接收數據包(Rx),並將其發送到另一個端口(Tx)。如果需要的話,一個端口可同時用於接收和發送。
  • 收包模式(Rx-only mode):在此模式下,TestPMD 會輪詢 Rx 端口的數據包,然後直接釋放而不發送,以這種方式充當數據包接收器。
  • 發包模式(Tx-only mode):在此模式下,TestPMD 生成 64Byte 的 IP 數據包,並從 Tx 端口發送出去。不接收數據包,僅作爲數據包的發送源。

注:後兩種模式在單獨檢查收包或者發包的場景中非常有用。

TestPMD 支持兩種配置場景:

  1. TestPMD 把兩個以太網端口連接到外部的流量發生器。
    在這裏插入圖片描述
  2. TestPMD 把兩個以太網端口連成環回模式,這樣就可以在沒有外部流量發生器的情況下檢查網絡設備的接收和傳輸功能。
    在這裏插入圖片描述

測試 testpmd 是否可用:

$ cd ${RTE_SDK}/${RTE_TARGET}/build/app/test-pmd
$  ./testpmd
EAL: Detected 6 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: No free hugepages reported in hugepages-1048576kB
EAL: Probing VFIO support...
EAL: VFIO support initialized
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: PCI device 0000:00:03.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 1af4:1000 net_virtio
EAL: PCI device 0000:00:05.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 15b3:1018 net_mlx5
EAL: PCI device 0000:00:06.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 15b3:1018 net_mlx5
EAL: PCI device 0000:00:07.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 15b3:1018 net_mlx5
testpmd: create a new mbuf pool <mbuf_pool_socket_0>: n=187456, size=2176, socket=0
testpmd: preferred mempool ops selected: ring_mp_mc


Warning! port-topology=paired and odd forward ports number, the last port will pair with itself.


Configuring Port 0 (socket 0)
Port 0: FA:16:3E:FF:38:D2
Configuring Port 1 (socket 0)
Port 1: FA:16:3E:CD:4A:1D
Configuring Port 2 (socket 0)
Port 2: FA:16:3E:FE:FB:FA
Checking link statuses...
Done
No commandline core given, start packet forwarding
io packet forwarding - ports=3 - cores=1 - streams=3 - NUMA support enabled, MP over anonymous pages disabled
Logical Core 1 (socket 0) forwards packets on 3 streams:
  RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
  RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
  RX P=2/Q=0 (socket 0) -> TX P=2/Q=0 (socket 0) peer=02:00:00:00:00:02


  io packet forwarding packets/burst=32
  nb forwarding cores=1 - nb forwarding ports=3
  port 0: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x1000 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
  port 1: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x1000 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
  port 2: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x1000 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
Press enter to exit

進入 testpmd 交互環境:

$  ./testpmd -l 1,2,3 --socket-mem 1024 -n 4 --log-level=8 -- -i
EAL: Detected 6 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: No free hugepages reported in hugepages-1048576kB
EAL: Probing VFIO support...
EAL: VFIO support initialized
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: PCI device 0000:00:03.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 1af4:1000 net_virtio
EAL: PCI device 0000:00:05.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 15b3:1018 net_mlx5
EAL: PCI device 0000:00:06.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 15b3:1018 net_mlx5
EAL: PCI device 0000:00:07.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 15b3:1018 net_mlx5
Interactive-mode selected
testpmd: create a new mbuf pool <mbuf_pool_socket_0>: n=163456, size=2176, socket=0
testpmd: preferred mempool ops selected: ring_mp_mc


Warning! port-topology=paired and odd forward ports number, the last port will pair with itself.


Configuring Port 0 (socket 0)
Port 0: FA:16:3E:FF:38:D2
Configuring Port 1 (socket 0)
Port 1: FA:16:3E:CD:4A:1D
Configuring Port 2 (socket 0)
Port 2: FA:16:3E:FE:FB:FA
Checking link statuses...
Done
testpmd> 
  • -l:指定運行 TestPMD 的 lcore,Core 1 用於管理命令行,Core 2、3 用於轉發數據包。
  • -n:指定系統的內存通道數。
  • –:用於分開 EAL 參數和應用程序參數。

檢查轉發配置:

testpmd> show config fwd
io packet forwarding - ports=3 - cores=1 - streams=3 - NUMA support enabled, MP over anonymous pages disabled
Logical Core 2 (socket 0) forwards packets on 3 streams:
  RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
  RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
  RX P=2/Q=0 (socket 0) -> TX P=2/Q=0 (socket 0) peer=02:00:00:00:00:02

這表明 TestPMD 正使用默認的 IO 轉發模式,同時也表明 lcore 2(第二個啓用的 Core)將用於輪詢 Port 0 上的數據包並轉發到 Port 1,反之亦然。 lcore 1 用於處理運實時命令行本身。

要開始轉發,並檢查端口之間是否有包正在轉發:

testpmd> start
io packet forwarding - ports=3 - cores=1 - streams=3 - NUMA support enabled, MP over anonymous pages disabled
Logical Core 2 (socket 0) forwards packets on 3 streams:
  RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
  RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
  RX P=2/Q=0 (socket 0) -> TX P=2/Q=0 (socket 0) peer=02:00:00:00:00:02


  io packet forwarding packets/burst=32
  nb forwarding cores=1 - nb forwarding ports=3
  port 0: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x1000 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
  port 1: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x1000 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
  port 2: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x1000 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0

testpmd> show port stats all


  ######################## NIC statistics for port 0  ########################
  RX-packets: 0          RX-missed: 0          RX-bytes:  0
  RX-errors: 0
  RX-nombuf:  0
  TX-packets: 0          TX-errors: 0          TX-bytes:  0


  Throughput (since last show)
  Rx-pps:            0
  Tx-pps:            0
  ############################################################################


  ######################## NIC statistics for port 1  ########################
  RX-packets: 0          RX-missed: 0          RX-bytes:  0
  RX-errors: 0
  RX-nombuf:  0
  TX-packets: 0          TX-errors: 0          TX-bytes:  0


  Throughput (since last show)
  Rx-pps:            0
  Tx-pps:            0
  ############################################################################


  ######################## NIC statistics for port 2  ########################
  RX-packets: 0          RX-missed: 0          RX-bytes:  0
  RX-errors: 0
  RX-nombuf:  0
  TX-packets: 0          TX-errors: 0          TX-bytes:  0


  Throughput (since last show)
  Rx-pps:            0
  Tx-pps:            0
  ############################################################################

此輸出顯示了 TestPMD 開始轉發後的所有數據包總數,包含有這兩個端口接收和發送的數據包數。吞吐率是以數據包每秒來顯示的。在這個例子中,所有端口上都沒有接收到包,是因爲 Port 1、2、3 都沒有連接到網絡環境中。

若要停止轉發,只需輸入 stop,這會停止轉發並顯示兩個端口的累計統計數字以及一個概要:

testpmd> stop
Telling cores to stop...
Waiting for lcores to finish...


  ---------------------- Forward statistics for port 0  ----------------------
  RX-packets: 0              RX-dropped: 0             RX-total: 0
  TX-packets: 0              TX-dropped: 0             TX-total: 0
  ----------------------------------------------------------------------------


  ---------------------- Forward statistics for port 1  ----------------------
  RX-packets: 0              RX-dropped: 0             RX-total: 0
  TX-packets: 0              TX-dropped: 0             TX-total: 0
  ----------------------------------------------------------------------------


  ---------------------- Forward statistics for port 2  ----------------------
  RX-packets: 0              RX-dropped: 0             RX-total: 0
  TX-packets: 0              TX-dropped: 0             TX-total: 0
  ----------------------------------------------------------------------------


  +++++++++++++++ Accumulated forward statistics for all ports+++++++++++++++
  RX-packets: 0              RX-dropped: 0             RX-total: 0
  TX-packets: 0              TX-dropped: 0             TX-total: 0
  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Done.

退出:

testpmd> quit


Shutting down port 0...
Stopping ports...
Done
Closing ports...
Done


Shutting down port 1...
Stopping ports...
Done
Closing ports...
Done


Shutting down port 2...
Stopping ports...
Done
Closing ports...
Done


Bye...


Shutting down port 0...
Stopping ports...
Done
Closing ports...
Port 0 is already closed
Done


Shutting down port 1...
Stopping ports...
Done
Closing ports...
Port 1 is already closed
Done


Shutting down port 2...
Stopping ports...
Done
Closing ports...
Port 2 is already closed
Done


Bye...

使用多核

對於一個核不足以轉發所有收到的包的場景中,多核可以用於處理來自不同端口的數據包。在前面的例子中,Core 2、3 都可用於轉發數據包,但默認情況下只有 Core 2 被用到了。要啓用另一個核,我們可以使用以下命令:

testpmd> set nbcore 2
Number of forwarding cores set to 2

testpmd> show config fwd
txonly packet forwarding - ports=3 - cores=2 - streams=3 - NUMA support enabled, MP over anonymous pages disabled
Logical Core 2 (socket 0) forwards packets on 1 streams:
  RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
Logical Core 3 (socket 0) forwards packets on 2 streams:
  RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
  RX P=2/Q=0 (socket 0) -> TX P=2/Q=0 (socket 0) peer=02:00:00:00:00:02

這樣 Core2 將從 Port 0 接收數據包並轉發到 Port 1 發送數據包,而 Core3 將接收來自 Port 1 的數據包,並從 Port 0 上發送。

切換模式

如上所述,TestPMD 具有不同的轉發模式。若要將轉發模式更改爲發包模式,我們可以使用 set fwd 命令:

testpmd> set fwd txonly
Set txonly packet forwarding mode
testpmd> start
txonly packet forwarding - ports=3 - cores=1 - streams=3 - NUMA support enabled, MP over anonymous pages disabled
Logical Core 2 (socket 0) forwards packets on 3 streams:
  RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
  RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
  RX P=2/Q=0 (socket 0) -> TX P=2/Q=0 (socket 0) peer=02:00:00:00:00:02

  txonly packet forwarding packets/burst=32
  packet len=64 - nb packet segments=1
  nb forwarding cores=1 - nb forwarding ports=3
  port 0: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x1000 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
  port 1: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x1000 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
  port 2: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x1000 Tx offloads=0x0
    RX queue: 0
      RX desc=0 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=0 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
testpmd> show port stats all

  ######################## NIC statistics for port 0  ########################
  RX-packets: 0          RX-missed: 0          RX-bytes:  0
  RX-errors: 0
  RX-nombuf:  0
  TX-packets: 12099712   TX-errors: 0          TX-bytes:  774381568

  Throughput (since last show)
  Rx-pps:            0
  Tx-pps:       561119
  ############################################################################

  ######################## NIC statistics for port 1  ########################
  RX-packets: 0          RX-missed: 0          RX-bytes:  0
  RX-errors: 0
  RX-nombuf:  0
  TX-packets: 12084672   TX-errors: 0          TX-bytes:  773419008

  Throughput (since last show)
  Rx-pps:            0
  Tx-pps:       560421
  ############################################################################

  ######################## NIC statistics for port 2  ########################
  RX-packets: 0          RX-missed: 0          RX-bytes:  0
  RX-errors: 0
  RX-nombuf:  0
  TX-packets: 12086720   TX-errors: 0          TX-bytes:  773550080

  Throughput (since last show)
  Rx-pps:            0
  Tx-pps:       560514
  ############################################################################
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章