はじめに
SONiCのACL(Access Control List)機能は、基本的にスイッチASICに設定を投入してハードウェア処理されます。ACLテーブルを作成し、テーブルごとに対象ポートを指定し、テーブルに設定されたルールを適用します。
テーブルにはタイプが指定できます。公式ドキュメントによるとタイプとして l3 と mirror が指定できると説明があるのですが、テーブルタイプは他にもあり、また自分で独自のタイプを用意することもできます。これらのカスタマイズについて解説します。
既存のACLテーブルタイプ
それぞれ、条件(matches)とアクション(actions)が定義されています。
L3L3V6MIRRORMIRRORV6MIRROR_DSCPPFCWDCTRLPLANEDTEL_FLOW_WATCHLISTMCLAGDROP
以下、具体的にどのような条件とアクションが設定可能かを並べます。説明がないテーブルタイプの多くはL3タイプのサブセットであるため、通常はL3を使えば事足りるようです。なお、ASICによっては受け付けない条件やアクションがありますので、動作するかどうか実際に確認してからご利用ください。
L3
L3ヘッダの指定条件にマッチしたパケットに対してアクションを実行します。
{
"ACL_TABLE": {
"tab": {
"type": "l3",
"stage": "ingress",
"ports": [ "Ethernet0", "Ethernet4" ]
}
}
"ACL_RULE": {
"tab|rule1": {
"PRIORITY": "10",
"SRC_IP": "192.168.0.0/24",
"PACKET_ACTION": "DROP"
}
}
}
matches
ETHER_TYPEVLAN_ID-
IP_TYPEANYIPNON_IPIPV4ANYNON_IPV4IPV6ANYNON_IPV6ARPARP_REQUESTARP_REPLY
SRC_IPDST_IPICMP_TYPEICMP_CODEIP_PROTOCOLL4_SRC_PORTL4_DST_PORTTCP_FLAGS
actions
-
PACKET_ACTIONFORWARDDROPREDIRECT
REDIRECT_ACTION
L3V6
IPv6パケット向けのテーブルタイプです。
matches
VLAN_IDIP_TYPESRC_IPV6DST_IPV6ICMPV6_TYPEICMPV6_CODENEXT_HEADERL4_SRC_PORTL4_DST_PORTTCP_FLAGS
actions
-
PACKET_ACTIONFORWARDDROPREDIRECT
REDIRECT_ACTION
MIRROR
MIRRORタイプは少し特殊で、IPv6をMIRRORタイプでIPv4と同じテーブルで扱うか、MIRRORV6タイプを使いIPv4と分けて使うかがASICによって違います。ここでは分けて使う想定で書きますが、同じテーブルで扱えるASICであれば、後述のMIRRORV6の条件をMIRRORテーブルのルールとして設定します。
-
MIRRORとMIRRORV6で分けるプラットフォームの例- Mellanox
- Marvell
- Broadcom DNX (Jerico系)
-
MIRRORでIPv6条件を書くプラットフォームの例- Broadcom Trident
- Broadcom Tomahawk
- Barefoot
matches
ETHER_TYPEVLAN_IDIP_TYPESRC_IPDST_IPICMP_TYPEICMP_CODEIP_PROTOCOLL4_SRC_PORTL4_DST_PORTTCP_FLAGSIN_PORTSDSCPL4_DST_PORT_RANGE
actions
MIRROR_INGRESSMIRROR_EGRESS
MIRRORV6
MIRRORにIPv6ルールを書かず、分離するタイプのASIC向けです。
matches
VLAN_IDIP_TYPESRC_IPV6DST_IPV6ICMPV6_TYPEICMPV6_CODENEXT_HEADERL4_SRC_PORTL4_DST_PORTTCP_FLAGSDSCPL4_DST_PORT_RANGE
actions
MIRROR_INGRESSMIRROR_EGRESS
MIRROR_DSCP
DSCPを見て特定パケットのみをミラーするタイプです。
matches
DSCP
actions
MIRROR_INGRESSMIRROR_EGRESS
PFCWD
matches
TC
actions
-
PACKET_ACTIONFORWARDDROPREDIRECT
CTRLPLANE
CTRLPLANEテーブルタイプは特殊で、これはASICではなくCPUで処理されます。テーブルにはサービスを指定します。サービスは下記のいずれか。
NTPSNMPSSHEXTERNAL_CLIENTANY
設定に従ってiptablesあるいはipv6tablesを呼び出します。(src/sonic-host-services/scripts/caclmgrd)
DTEL_FLOW_WATCHLIST
Dataplane TELemetry略してDTELはINT(Inbound Network Telemetry)と同じ機能を指します。テレメトリ用というだけあって、アクションが特殊です。
matches
ETHER_TYPESRC_IPDST_IPL4_SRC_PORTL4_DST_PORTIP_PROTOCOLTUNNEL_VNIINNER_ETHER_TYPEINNER_SRC_IPINNER_DST_IPVLAN_IDACL_IP_TYPETCP_FLAGSDSCPSRC_IPV6DST_IPV6ICMP_TYPEICMP_CODEICMPV6_TYPEICMPV6_CODENEXT_HEADER
actions
-
FLOW_OPNOPPOSTCARDINTIOAM
INT_SESSIONDROP_RESPOT_ENABLETAIL_DROP_REPORT_ENABLEREPORT_ALL_PACKETSFLOW_SAMPLE_PERCENT
MCLAG
matches
ETHER_TYPEVLAN_IDIP_TYPESRC_IPDST_IPICMP_TYPEICMP_CODEIP_PROTOCOLL4_SRC_PORTL4_DST_PORTTCP_FLAGSOUT_PORTSL4_DST_PORT_RANGE
actions
-
PACKET_ACTIONFORWARDDROPREDIRECT
DROP
matches
TC
actions
-
PACKET_ACTIONFORWARDDROPREDIRECT
テーブルタイプのカスタマイズ
CLIからは設定できませんが、config DBに書くことでカスタムテーブルタイプを定義できます。
{
"ACL_TABLE_TYPE|name": {
"MATCHES": [
条件1,
条件2,
:
],
"ACTIONS": [
アクション1,
アクション2,
:
],
"BIND_POINTS": [
"PORT",
"PORTCHANNEL",
:
]
}
}
定義したタイプはsudo config acl add table テーブル名 タイプのタイプ部分に指定できます。
MATCHES
ここに並べられた条件が、ルールとして設定可能となります。記述できるものは下記のうちのいずれかです。SAIのヘッダ(saiacl.h)に書かれているものすべてではありません。ここにない条件を使いたい場合、ソースコード(src/sonic-swss/orchagent/aclorch.cppと同ディレクトリのaclorch.h)の変更とイメージのビルドが必要です。ASICによっては受け付けない条件がある点にもご注意ください。
IN_PORTSOUT_PORTSSRC_IPDST_IPSRC_IPV6DST_IPV6L4_SRC_PORTL4_DST_PORTETHER_TYPEVLAN_IDIP_PROTOCOLNEXT_HEADERTCP_FLAGSIP_TYPEDSCPTCICMP_TYPEICMP_CODEICMPV6_TYPEICMPV6_CODEL4_SRC_PORT_RANGEL4_DST_PORT_RANGETUNNEL_VNIINNER_ETHER_TYPEINNER_IP_PROTOCOLINNER_L4_SRC_PORTINNER_L4_DST_PORTL4_SRC_PORT_RANGEL4_DST_PORT_RANGE
ACTIONS
MATCHESと同様に、ここに書かれたアクションが設定可能となります。設定可能アクションは下記になります。これらについてもsaiacl.hに書かれている全てではなく、増やす場合はソースコードの変更とイメージのビルドが必要です。また、ASICによって受け付けないアクションがある点にも注意です。
- L3関連
PACKET_ACTIONREDIRECT_ACTIONDO_NO_NAT_ACTION
- MIRROR関連
MIRROR_INGRESS_ACTIONMIRROR_EGRESS_ACTION
- DTEL関連
FLOW_OPINT_SESSIONDROP_REPORT_ENABLETAIL_DROP_REPORT_ENABLEFLOW_SAMPLE_PACKETREPORT_ALL_PACKETS
- その他
COUNTER
BIND_POINTS
ACLの適用場所の指定です。PORTあるいはPORTCHANNEL、もしくはその両方が指定できます。SAIではその他VLAN, ROUTER_INTERFACE, SWITCHが指定可能なようですが、実際にASICに指定可能なのかは未確認です。VLANはVLAN_IDの条件を指定できればそれで代替できそうです。
カスタマイズ例
VXLAN
TUNNEL_VNIという条件でマッチできるテーブルを作成してみます。
{
"ACL_TABLE_TYPE": {
"vxlan": {
"MATCHES": [
"TUNNEL_VNI"
],
"ACTIONS": [
"PACKET_ACTION"
],
"BIND_POINTS": [
"PORT"
]
}
},
"ACL_TABLE": {
"vxlan_drop": {
"type": "vxlan",
"stage": "ingress",
"ports": [ "Ethernet0", "Ethernet4" ]
}
},
"ACL_RULE": {
"vxlan_drop|testrule1": {
"TUNNEL_VNI": "1000",
"PACKET_ACTION": "DROP"
}
}
}
アクションを追加した場合
アクションを追加したイメージでは、下記のようにカスタムテーブルを定義して従来では設定できないACLルールを追加することができます。できるはずです。
{
"ACL_TABLE_TYPE": {
"NAT": {
"MATCHES": [
"IN_PORTS",
"OUTER_VLAN_ID",
"SRC_IP",
"DST_IP"
],
"ACTIONS": {
"SET_SRC_IP_ACTION",
"SET_DST_IP_ACTION"
],
"BIND_POINTS": [
"PORT"
]
}
},
"ACL_TABLE": {
DNAT": {
"type": "NAT",
"stage": "ingress"
},
"SNAT": {
"type": "NAT",
"stage": "ingress"
}
}
"ACL_RULE": {
"DNAT|rule1": {
"DST_IP": "192.168.0.1",
"SET_DST_IP_ACTION": "10.0.0.1"
},
"SNAT|rule1": {
"SRC_IP": "10.0.0.1",
"SET_SRC_IP_ACTION": "192.168.0.1"
}
}
}
設定できないテーブルタイプを作ろうとするとどうなる?
エラーが出ます。が、ログに記録されるだけなので show loggingで確認してください。なお、このエラーでSONiCの各機能が停止することはないようです。
例: 追加しようとしたテーブルたいぷ定義
"ACL_TABLE_TYPE": {
"NAT": {
"MATCHES": [
"IN_PORTS",
"VLAN_ID",
"SRC_IP",
"DST_IP"
],
"ACTIONS": [
"SET_SRC_IP_ACTION",
"SET_DST_IP_ACTION"
],
"BIND_POINTS": [
"PORT"
]
}
},
エラー (show loggingからエラー箇所を抜粋)
Aug 7 17:49:28.084646 sonic ERR swss#orchagent: :- parseAclTableTypeActions: Unknown action SET_SRC_IP_ACTION
Aug 7 17:49:28.084646 sonic ERR swss#orchagent: :- doAclTableTypeTask: Failed to parse ACL table type configuration NAT
ACLの動作状況を確認する
show aclコマンドでは設定参照しかできません。
aclshowコマンドを使いましょう。
$ aclshow --help
usage: aclshow [-h] [-a] [-c] [-r RULES] [-t TABLES] [-v] [-vv]
Display SONiC switch Acl Rules and Counters
optional arguments:
-h, --help show this help message and exit
-a, --all Show all ACL counters
-c, --clear Clear ACL counters statistics
-r RULES, --rules RULES
action by specific rules list: Rule1_Name,Rule2_Name
-t TABLES, --tables TABLES
action by specific tables list: Table1_Name,Table2_Name
-v, --version show program's version number and exit
-vv, --verbose Verbose output
SONiC-VSでは?
caclmgrd はiptablesを設定しますが、これはコントロールプレーン専用です。また、SONiC-VSのSAI実装であるlibsaivsのACL実装(src/sonic-sairedis/vslib/sai_vs_acl.cpp)ではなにも実装されていません。よって、残念ながらSONiCのACL設定は基本的にSONiC-VSでは利用できません。
おわりに
SAIのヘッダ(saiacl.h)を見ると、SAI_ACTION_TYPE_SET_VRFといった興味深いアクションがあったりするのですが、動くか動かないかは各ASICに用意されたSAI実装次第です(Broadcom Trident3では未実装でした)。複数種類のハードウェアを試せれば条件やアクションの○×表を書けるかもしれません。