---
# System prepended metadata

title: 2020-09-09 kernel network stack reading - l3mdev as a loopback device -

---

---
lang: ja
breaks: false
---

<style>
.ui-infobar, #doc.markdown-body { max-width: 1100px; }
</style>

# 2020-09-09 kernel network stack reading - l3mdev as a loopback device -

- 参加者: hayakawa, kawakami, taguchi, shirokura
- kernel: `5.6.6`
- ドライバー: hayakawa
- 今回のテーマ
    - VRFをloopbackの代わりに使う


## 使用マシン
- 早川のローカルマシンのVagrant
- fedora/32-cloud-base
- Vagrant環境の構築方法は9/4に記載されている通り
    - https://hackmd.io/iMc0OpUESIWCNSr9DBC_sg?both#tinet%E3%81%A8ipftrace2%E7%92%B0%E5%A2%83%E3%81%AE%E6%A7%8B%E7%AF%89

### 今回新たに分かったVRFの性質

```
ip link add vrf0 type vrf table 10
ip link set vrf0 up
ip addr add 10.0.0.1/24 dev vrf0
ip route replace local 10.0.0.0/24 dev vrf0 table 10
iptables -t raw -A PREROUTING -d 10.0.0.2 -j MARK --set-mark 0xdeadbeef
```

この状態で `ping -I vrf0 10.0.0.2` をすると、`Network Unreabchable` になる. `ip route get 10.0.0.2 vrf vrf0` すると `src 10.0.0.2` になる. loopbackの `127.0.0.0/8` の経路だと `src 127.0.0.1` になる. loopbackの場合は `src` が明示的にルーティングテーブルに書いてある. そこで

```
ip route replace local 10.0.0.0/24 dev vrf0 src 10.0.0.1 table 10
```

にすると `Network Unreabchable` は消えるが、応答がない (送信側はvrf_local_xmit経由になる). トレースしてみると

```
8392437442703 000                    ip_rcv_finish
8392437456354 000                 ip_local_deliver
8392437459706 000                     nf_hook_slow
8392437463169 000              iptable_filter_hook
8392437466985 000          ip_local_deliver_finish
8392437470180 000          ip_protocol_deliver_rcu
8392437473790 000                raw_local_deliver
8392437477304 000                         icmp_rcv
8392437480664 000          __skb_checksum_complete
8392437485716 000                        icmp_echo
8392437489317 000                __ip_options_echo
8392437493250 000             fib_compute_spec_dst
8392437497159 000       security_skb_classify_flow
8392437500769 000      selinux_xfrm_decode_session
8392437504693 000     selinux_xfrm_skb_sid_ingress
8392437508121 000                      consume_skb
8392437511267 000           skb_release_head_state
8392437514560 000                 skb_release_data
8392437517797 000                     kfree_skbmem
```

こうなる. `security_skb_classify_flow` と `consume_skb` の間に `ip_route_output_key` があって、そこで経路のlookupに失敗する.

### 豆知識

```
net.ipv4.fwmark_reflect = 1
```

とすると `skb->mark` が `ICMP Echo Reply` の経路loookup時に使われるようになる (flowi4->mark) にセットされる. トレースに便利.

