---
# System prepended metadata

title: 2020-09-16 kernel network stack reading - vrf transfer -

---

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

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


# 2020-09-16 kernel network stack reading - vrf transfer -

- 参加者: hayakawa, kawakami, taguchi
- kernel: 
- ドライバー: taguchi
- 今回のテーマ
    - VRF乗り換え
    - LinuxではVRFをout deviceに指定してルーティングすることによってVRF乗り換えをすることができる。そのデータパスを探索する。



## tinet環境
![](https://i.imgur.com/3pwRgWG.png)
```yaml
---
nodes:
  - name: R1
    image: slankdev/frr
    interfaces:
      - { name: net1, type: direct, args: N1#net0 }
      - { name: net2, type: direct, args: N2#net0 }
  - name: N1
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net1 }
  - name: N2
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net2 }

node_configs:
  - name: R1
    cmds:
      - cmd: ip link add vrf10 type vrf table 10
      - cmd: ip link add vrf20 type vrf table 20
      - cmd: ip link set vrf10 up
      - cmd: ip link set vrf20 up
      - cmd: ip addr add 10.1.0.2/24 dev net1
      - cmd: ip addr add 10.2.0.2/24 dev net2
      - cmd: ip link set net1 vrf vrf10
      - cmd: ip link set net2 vrf vrf20
      - cmd: ip route add 10.1.0.1 dev vrf10 vrf vrf20
      - cmd: ip route add 10.2.0.1 dev vrf20 vrf vrf10


  - name: N1
    cmds:
      - cmd: ip addr add 10.1.0.1/24 dev net0
      - cmd: ip route add default via 10.1.0.2
  - name: N2
    cmds:
      - cmd: ip addr add 10.2.0.1/24 dev net0
      - cmd: ip route add default via 10.2.0.2

```


## iptables

```
iptables -t raw -A PREROUTING -i net1 -j MARK --set-mark 0xdeadbeef
```


## N1からN2にPing

```
ping 10.2.0.1 -c 1
```

## Trace結果
```
===
536089144619 000                    ip_rcv_finish
536089174957 000                       vrf_l3_rcv
536089184803 000                     nf_hook_slow
536089191883 000                 iptable_raw_hook
536089202558 000             ip_route_input_noref
536089212338 000              ip_route_input_slow
536089230157 000              fib_validate_source
536089243655 000            __fib_validate_source
536089256874 000                       ip_forward
536089262887 000                     nf_hook_slow
536089274880 000             selinux_ipv4_forward
536089280597 000               selinux_ip_forward
536089288404 000                ip_forward_finish
536089293446 000                        ip_output
536089297830 000                     nf_hook_slow
536089308358 000           selinux_ipv4_postroute
536089314537 000             selinux_ip_postroute
536089320384 000                 ip_finish_output
536089326866 000               __ip_finish_output
536089333321 000                ip_finish_output2
536089342498 000                   dev_queue_xmit <= vrf20に入る
536089347440 000                 __dev_queue_xmit
536089355142 000              netdev_core_pick_tx
536089364345 000                validate_xmit_skb
536089373074 000               netif_skb_features
536089380225 000             skb_network_protocol
536089385774 000               validate_xmit_xfrm
536089392276 000              dev_hard_start_xmit
536089400047 000                         vrf_xmit
536089408306 000          vrf_process_v4_outbound <= この中で再度lookup
536089419794 000                     nf_hook_slow
536089425830 000                 iptable_raw_hook
536089431510 000              selinux_ipv4_output
536089436375 000                        ip_output
536089441084 000                     nf_hook_slow
536089446385 000           selinux_ipv4_postroute
536089451714 000             selinux_ip_postroute
536089456636 000                 ip_finish_output
536089461476 000               __ip_finish_output
536089465935 000                ip_finish_output2
536089474542 000             neigh_resolve_output
536089483837 000               __neigh_event_send
536089492662 000                       eth_header
536089504288 000                         skb_push
536089509074 000                   dev_queue_xmit
536089514700 000                 __dev_queue_xmit
536089520043 000              netdev_core_pick_tx
536089525739 000                validate_xmit_skb
536089531315 000               netif_skb_features
536089538028 000          passthru_features_check
536089543066 000             skb_network_protocol
536089548024 000               validate_xmit_xfrm
536089553026 000              dev_hard_start_xmit
536089558604 000                        veth_xmit
536089568345 000           skb_clone_tx_timestamp
536089574100 000                __dev_forward_skb
536089580003 000                 skb_scrub_packet
```


## メモ

VRFのソース: http://elixir-referencer.dev.linecorp.com/linux/latest/source/drivers/net/vrf.c

- LinuxのVRF乗り換え == l3mdevへのパケットフォワーディング
- vrf_xmit => vrf_process_v4_outboundで再度ルーティング
- ちなみにip_forwardが挟まるのでttlが1減る

## 参考文献

VRFのドキュメント: https://www.kernel.org/doc/Documentation/networking/vrf.txt