SONiCでVLANを使う

# はじめに

久しく公開記事を書いていなかったので、リハビリを兼ねてSONiCにおけるVLANの設定方法を解説します。

# VLANの基礎

## VLANの基本機能

L2セグメントを分割するのがVLANの基本機能です。

8ポートのスイッチングHUBを思い浮かべてください。8つのポートがそれぞれと通信できます。これをたとえば、1〜4と5〜8の2つに分割して、4ポートのスイッチングHUBが2台あるのと同じような振る舞いにできます。

上記の例のとおり、複数の物理ポートをまたいだL2セグメントとして機能します。

## VLAN ID

IDを付与してVLANを区別します。

- デフォルトのVLANは1
- デフォルト以外のVLANを作成するときは2〜4094のIDを割り当てます。

## ポートVLANとタグVLAN

ポートVLANとタグVLANがあります。

これまで例に挙げてきた、複数ポートを束ねるだけのVLANがポートVLANです。これに対して、通信パケットのヘッダにタグを付与することで、同一ポートにおいて複数のVLANの通信を可能とするものがタグVLANです。

## L3通信はどうなる?

L3通信がサポートされている場合、VLANインタフェースが作成されます。VLANインタフェースにIPアドレスを付与することで、router interfaceとして利用することができます。

# SONiCでのVLAN

ざっくり下記のような制約があります。

- インタフェース名は常に`Vlan` + ID。(例: `Vlan1001`)
    - JSONで命名規則に沿わない名前を指定すると、VLAN作成に失敗します
- VLAN対象となった物理インタフェースはtrunkとなり、物理インタフェースに対してIPアドレス設定などはできなくなります
- 逆に、すでにIPアドレスが付与されている物理インタフェースをVLAN対象にすることは出来ません
- 似て非なるインタフェースとしてサブインタフェースが存在するが、ここでは触れません

# 設定

下記では、次のような設定でVLANを作成しています。
- VLAN ID: 1001
- 対象物理ポートは`Ethernet0` (タグVLAN)、`Ethernet4` (ポートVLAN)
- VLANインタフェースにIPアドレス `10.0.0.1/24`を付与

## CLI

```shell
sudo config vlan add 1001
sudo config vlan member add 1001 Ethernet0
sudo config vlan member add --untagged 1001 Ethernet4
sudo config interface ip add Vlan1001 10.0.0.1/24
```

## JSON

```json
{
    "VLAN": {
        "Vlan1001": {
            "vlanid": "1001"
        }
    },
    "VLAN_MEMBER": {
        "Vlan1001|Ethernet0": {
            "taggineg_mode": "tagged"
        },
        "Vlan1001|Ethernet4": {
            "taggineg_mode": "untagged"
        }
    },
    "VLAN_INTERFACE": {
        "Vlan1001|10.0.0.1/24": {},
        "Vlan1001": {}
    }
}
```

# 状態参照

```shell-session
$ show vlan config
Name        VID  Member     Mode
--------  -----  ---------  ------
Vlan1001   1001  Ethernet0  tagged
Vlan1001   1001  Ethernet4  untagged
```

```shell-session
$ show vlan brief
+-----------+--------------+-----------+----------------+-----------------------+-------------+
|   VLAN ID | IP Address   | Ports     | Port Tagging   | DHCP Helper Address   | Proxy ARP   |
+===========+==============+===========+================+=======================+=============+
|      1001 | 10.0.0.1/24  | Ethernet0 | tagged         |                       | disabled    |
|           |              | Ethernet4 | untagged       |                       +-----------+--------------+-----------+----------------+-----------------------+-------------+
```

```shell-session
$ show ip interfaces
Interface    Master    IPv4 address/mask    Admin/Oper    BGP Neighbor    Neighbor IP
-----------  --------  -------------------  ------------  --------------  -------------
Vlan1001               10.0.0.1/24          up/up         N/A             N/A
docker0                240.127.1.1/24       up/down       N/A             N/A
eth0                   192.168.1.121/24     up/up         N/A             N/A
lo                     127.0.0.1/16         up/up         N/A             N/A
```

```shell-session
$ show interfaces status Ethernet0
  Interface        Lanes    Speed    MTU    FEC         Alias    Vlan    Oper    Admin    Type    Asym PFC
-----------  -----------  -------  -----  -----  ------------  ------  ------  -------  ------  ----------
  Ethernet0  25,26,27,28      40G   9100    N/A  fortyGigE0/0   trunk      up       up     N/A         N/A
$ show interfaces status Ethernet4
  Interface        Lanes    Speed    MTU    FEC         Alias    Vlan    Oper    Admin    Type    Asym PFC
-----------  -----------  -------  -----  -----  ------------  ------  ------  -------  ------  ----------
  Ethernet4  29,30,31,32      40G   9100    N/A  fortyGigE0/4   trunk    down       up     N/A         N/A
```


# 注意点

将来解決されるかもしれませんが現時点では、VLANインタフェースをVRFに割り当てると、SONiCホストあてのIPパケットを受信できないようです。SONiC-VSでも同じ症状だったため、ASIC設定に連動するLinux側の設定に問題があるものと思われます。ご注意ください。

おそらくサブインタフェースでは問題なく動作するものと思われますが、使用するハードウェアによってはSONiCでのサブインタフェースのサポートがないため、合わせてご注意ください。