Crystal DPDKでワイヤレートIPアドレスブロッキング

シンタックスハイライト適用されたソースコード

![スクリーンショット 2018-04-25 1.18.07.png](https://qiita-image-store.s3.amazonaws.com/0/109145/c91944d5-fb02-bf1a-87de-6905e90949db.png)

テキストのソースURLはこちら
- https://github.com/s-you/dpdk.cr/blob/master/examples/ip_blocking.cr

```ruby
require "../src/lib/base"

module IpBlockingMethods
  private macro target_addresses?
    src = pkt.u32(IP_SRC_OFS)
    blocking_ips.any? { |x| x == src }
  end

  private macro process_per_type
    mark_drop_and_next if ipv4? && target_addresses?
  end
end

module ProcessPacketsMethods
  private macro process_each_packets
    each_packet do
      process_per_type
    end
  end
end

module MainMethods
  macro main_loop
    until @quit_signal
      rte_eth_rx_burst!
      process_each_packets
      drop_unsupported
      rte_eth_tx_burst?
    end
  end
end

dpdk do
  REQUIRED_CORES = 1
  REQUIRED_PORTS = 1

  include MainMethods
  include ProcessPacketsMethods
  include IpBlockingMethods

  thread ip_blocking do
    blocking_ips = [
      ipv4(10, 0, 0, 2),
      ipv4(10, 0, 0, 4),
      ipv4(10, 0, 0, 6),
    ]
    main_loop
  end

  main do
    rte_lcore_foreach_worker(1) do |lcore_id, worker_id|
      if worker_id == 0
        rte_eal_remote_launch ip_blocking
      end
    end
  end
end

# # Run the program
# # sudo build/ip_blocking -l 1-2 -- -p 1
```

ブロック対象として以下のアドレス３つを設定しています。

```
ipv4(10, 0, 0, 2),
ipv4(10, 0, 0, 4),
ipv4(10, 0, 0, 6),
```

dpdk.crのレポジトリの直下で、以下のコマンとを叩き、起動します。

```shell

% make ip_blocking
% sudo build/ip_blocking -l 1-2 -- -p 1
EAL: Detected 8 lcore(s)
EAL: Multi-process socket /var/run/.rte_unix
EAL: Probing VFIO support...
EAL: PCI device 0000:00:03.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:08.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:09.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:0a.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:10.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:11.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:12.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:13.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100e net_e1000_em
Initializing port 0... done
Port 0 MAC: 3C:FD:FE:A1:3B:F1
Waiting for Link up on all enabled ports ..... done
PERF: ip_blocking() started on lcore 2, port: 0

```

別のVMから10.0.0.1 ~ 10.0.0.10のソースアドレスを利用しパケットを生成し送ります。(pktgen利用)

![スクリーンショット 2018-04-25 1.23.11.png](https://qiita-image-store.s3.amazonaws.com/0/109145/2e8bd3b7-9132-3599-fc57-1c07c76a2f1d.png)

送ったパケット１０個に対して７個しか帰って来ないことが分かります。

Wireshark上からも同じことが確認できます。

![スクリーンショット 2018-04-25 1.25.12.png](https://qiita-image-store.s3.amazonaws.com/0/109145/464fa890-9d97-3dac-c845-bf83b9ff5aa9.png)

今回特に実機での速度は図っていませんが、アセンブリで **rte_eth_rx_burst** から **rte_eth_tx_burst** の間に 69 行しかないのでワイヤレートの 10Gbps 出ない理由がありません。

![スクリーンショット 2018-04-25 1.28.31.png](https://qiita-image-store.s3.amazonaws.com/0/109145/3caf8d63-fcaf-0894-9295-00af84ea8d32.png)

追記：物理マシンでのテスト追加 (10G NIC)

```
% sudo build/ip_blocking -l 1,3 -- -p 1 
```

pktgen luaで10.0.0.1のみに設定

```
pktgen.src_ip("all", "start", "10.0.0.1");
pktgen.src_ip("all", "inc", "0.0.0.1");
pktgen.src_ip("all", "min", "10.0.0.1");
pktgen.src_ip("all", "max", "10.0.0.1");

-
Pktgen:/> start 0
```

RX/TX 14.8Mpps / 9981 Mbps

![スクリーンショット 2018-04-26 10.37.44.png](https://qiita-image-store.s3.amazonaws.com/0/109145/96550087-caff-9f6c-bcd1-acd1be1e80e0.png)

max を 10.0.0.2 に設定

```
pktgen.src_ip("all", "max", "10.0.0.2");
```

RX: 7.4Mpps / 4999 Mpps (半分ドロップされていることを確認, 10.0.0.2がブロック対象なため)

![スクリーンショット 2018-04-26 10.38.38.png](https://qiita-image-store.s3.amazonaws.com/0/109145/a3bc3857-fb98-6554-85dc-fbb9a495c2a3.png)

max を 10.0.0.10 に設定

```
pktgen.src_ip("all", "max", "10.0.0.10");
```

RX 10Mpps / 6999 Mbps (3 割ドロップされていることを確認, 10.0.0.2, 4, 6がブロック対象なため)

![スクリーンショット 2018-04-26 10.40.42.png](https://qiita-image-store.s3.amazonaws.com/0/109145/e61dc9ea-2756-a49a-f2ed-427ad3373cfc.png)

全て想定どおり

以上