Access Control Lists – ACLs

Table of Contents

1. Configure ACL Tables Using ConfigDB

1.1 Configuration example

2. SONiC CLI commands (how to add and remove rules)

2.1 How to delete rules in SONiC

3. MAC ACL

4. Control Plane ACL

5. Notes

This section describes the commands you use to configure IP Access Control List (ACL) settings. IP ACLs ensure that only authorized users have access to specific resources and block any unwarranted attempts to reach network resources.

Example model & SONiC version:

  • Aurora 721
  • Netberg SONiC: sonic-broadcom-202311.n0

You configure ACLs in SONiC using:

  • The SONiC ConfigDB, defined in /etc/sonic/config_db.json.
  • The SONiC CLI – with limited capabilities.

There is no direct CLI command to add or delete or modify the ACL table and ACL rule. Existing ACL tables and ACL rules can be updated by specifying the ACL rules in json file formats and configure those files using this CLI command.

NoteDifferent platforms have different supported ACL actions.

Configure ACL Tables Using ConfigDB

The following table contains the ConfigDB schema. The schema is defined according to ABNF RFC 5234 syntax; refer to RFC 5234 for more information about the schema definition.

Field

Value

Description

ACL_TABLE

name

The name must be unique within the ACL_TABLE table. The name is used to reference this table from other places in the SONiC configuration database.

POLICY_DESC

1*255VCHAR

The W of the ACL policy table description, user defined description for the table.

TYPE

1*255VCHAR

Type of ACL table, every type of table defines the match/action a specific set of match and actions. See the next table below for details on the type field.

PORTS

[0-INF]*port_name

The list of ports to which this ACL table is applied, this field can be empty.

STAGE

“INGRESS”/”EGRESS”

ACL table stage, either ingress or egress.

SERVICES

[0-INF]*service_name

List of services, valid only for TYPE=CTRLPLANE.

The TYPE field can be one of the following:

Type

Bind Port Types Supported

Match Fields Supported

Supported ACL Rule Actions

L3

PORT, LAG

ETHER_TYPE

IP_TYPE

IP_PROTOCOL

SRC_IP

DST_IP

ICMP_TYPE

ICMP_CODE

L4_SRC_PORT

L4_DST_PORT

TCP_FLAGS

L4_DST_PORT_RANGE

L4_SRC_PORT_RANGE

VLAN_ID

SRC_MAC

DST_MAC

PACKET_ACTION

REDIRECT_ACTION

DO_NOT_NAT_ACTION

MIRROR_INGRESS_ACTION

MIRROR_EGRESS_ACTION

MIRROR_ACTION

L3V6

PORT,LAG

ETHER_TYPE

IP_TYPE

IP_PROTOCOL

SRC_IPV6

DST_IPV6

ICMPV6_TYPE

ICMPV6_CODE

L4_SRC_PORT

L4_DST_PORT

TCP_FLAGS

L4_DST_PORT_RANGE

L4_SRC_PORT_RANGE

VLAN_ID

SRC_MAC

DST_MAC

PACKET_ACTION

REDIRECT_ACTION

DO_NOT_NAT_ACTION

MIRROR

PORT,LAG

ETHER_TYPE

IP_TYPE

IP_PROTOCOL

SRC_IP

DST_IP

ICMP_TYPE

ICMP_CODE

L4_SRC_PORT

L4_DST_PORT

TCP_FLAGS

L4_DST_PORT_RANGE

L4_SRC_PORT_RANGE

MIRROR_INGRESS_ACTION

MIRROR_EGRESS_ACTION

MIRROR_ACTION

MIRRORV6

PORT,LAG

IP_TYPE

IP_PROTOCOL

SRC_IP

DST_IP

ICMP_TYPE

ICMP_CODE

SRC_IPV6 (*)

DST_IPV6 (*)

ICMPV6_TYPE (*)

ICMPV6_CODE (*)

L4_SRC_PORT

L4_DST_PORT

TCP_FLAGS

L4_DST_PORT_RANGE

L4_SRC_PORT_RANGE

MIRROR_INGRESS_ACTION

MIRROR_EGRESS_ACTION

MIRROR_ACTION

MIRROR_DSCP

PORT,LAG

DSCP

MIRROR_INGRESS_ACTION

MIRROR_EGRESS_ACTION

MIRROR_ACTION

DTEL_FLOW_WATCHLIST

SWITCH

DTEL_DROP_WATCHLIST

SWITCH

ACL support table

Interface

Stage

L3

L3V6

MIRROR

MIRRORV6

MIRRORDSCP

EthernetXXX

Ingress

Yes

Yes

Yes

Yes

Yes

EthernetXXX

Egress

Yes

Yes

No

No

No

port channel

Ingress

Yes

Yes

No

No

No

port channel

Egress

No

No

No

No

No

VLAN

Ingress

Yes

Yes

No

No

No

VLAN

Egress

No

No

No

No

No

ETHER_TYPE map

LLDP

VLAN

RoCE

ARP

IPv4

IPv6

MPLS

0x88CC

0x8100

0x8915

0x0806

0x0800

0x86DD

0x8847

IP_PROTOCOL map

TCP

ICMP

UDP

IGMP

PIM

RSVP

GRE

AUTH

ICMPv6

L2TP

6

1

17

2

103

46

47

51

58

115

IP_TYPE map

ANY

IP

IPV4

IPV4ANY

NON_IPv4

IPV6ANY

NON_IPv6

IPv4, IPv6, Ether type

IPv4, IPv6

IPv4 only

IPv4 only

IPv6, Ether type

IPv6 only

IPv4, Ether type

Configuration example

Create a JSON file “acl.json”:

admin@nba721:~$sudo nano acl.json
   {
   "ACL_TABLE": {
           "UPSTREAMS": {
           "policy_desc" : "Block ssh traffic from upstreams",
           "type" : "L3",
           "stage": "ingress",
           "ports" : [
                           "Ethernet0",
                           "Ethernet4",
                           "Ethernet8"
                       ] # physical port names
           }
       },
       "ACL_RULE": {
       "UPSTREAMS|Rule10": {
           "DST_IP": "192.168.1.1/32",
           "IP_TYPE": "IP",
           "L4_DST_PORT": "22",
           "PACKET_ACTION": "DROP",
           "priority": "10"
           }
       }
   }

Apply it by:

admin@nba721:~$ sudo config load acl.json -y
admin@nba721:~$ sudo config save -y

Check ACL:

admin@nba721:~$ show acl table
Name       Type       Binding    Description                       Stage    Status
---------  ---------  ---------  --------------------------------  -------  --------
UPSTREAMS  L3         Ethernet0  Block ssh traffic from upstreams  ingress  Active
                      Ethernet4
                      Ethernet8
admin@nba721:~$ show acl rule
Table      Rule        Priority    Action    Match                    Status
---------  ----------  ----------  --------  -----------------------  --------
UPSTREAMS  Rule10      10          DROP      DST_IP: 192.168.1.1/32   Active
                                             IP_TYPE: IP
                                             L4_DST_PORT: 22

Field

Value

Description

key

ACL_RULE_TABLE:table_name:rule_name

The key of the rule entry in the table, the sequence is the order of the rules when the packet is filtered by the ACL “policy_name”. A rule is always associated with a policy.

priority

1*3DIGIT

The rule priority. Valid values range are platform dependent. You can always check it in logs:

admin@switch:~$ show log / grep ‘Get ACL entry priority values’

Apr 22 16:46:55.967195 switch NOTICE swss#orchagent: :- init: Get ACL entry priority values, min: 0, max: 16381

packet_action

“forward”/”drop”/”mirror”

An action when the fields are matched. Mirror action only available to mirror acl table type)

mirror_action

1*255VCHAR

Refer to the mirror session. By default this is an ingress mirror action.

mirror_ingress_action

1*255VCHAR

Refer to the mirror session.

mirror_egress_action

1*255VCHAR

Refer to the mirror session.

ether_type

h16

Ethernet type field.

ip_type

ip_types

Options for the l2_protocol_type field.

ip_protocol

h8

Options for the l3_protocol_type field.

src_ip

ipv4_prefix

Options for the source IPv4 address (and mask) field.

dst_ip

ipv4_prefix

Options for the destination IPv4 address (and mask) field.

src_ipv6

ipv6_prefix

Options for the source IPv6 address (and mask) field.

dst_ipv6

ipv6_prefix

Options for the destination IPv6 address (and mask) field.

l4_src_port

port_num

The source L4 port.

l4_dst_port

port_num

The destination L4 port.

l4_src_port_range

port_num_L-port_num_H

The source port range of the L4 ports field.

l4_dst_port_range

port_num_L-port_num_H

The destination port range of the L4 ports field.

tcp_flags

h8/h8

TCP flags field and mask.

dscp

h8

The DSCP field, which is only available for mirror table type.

icmp_type

h8/h8

The ICMP type and mask.

icmpv6_type

h8/h8

The ICMPv6 type and mask.

icmp_code

h8/h8

The ICMP code and mask.

icmpv6_code

h8/h8

The ICMPv6 code and mask.

in_ports

string

A comma-separated list of inbound ports to match.

out_ports

string

A comma-separated list of outbound ports to match value annotations.

vlan_id

vlan_num

A VLAN number.

src_mac

mac_address

Options for the source MAC address field.

dst_mac

mac_address

Options for the destination MAC address field.

value annotations
port_num      = 1*5DIGIT   ; a number between 0 and 65535
port_num_L    = 1*5DIGIT   ; a number between 0 and 65535,
                           ; port_num_L < port_num_H
port_num_H    = 1*5DIGIT   ; a number between 0 and 65535,
                           ; port_num_L < port_num_H
ipv6_prefix   =                 6( h16 ":" ) ls32
   /                       "::" 5( h16 ":" ) ls32
   / [               h16 ] "::" 4( h16 ":" ) ls32
   / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
   / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
   / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
   / [ *4( h16 ":" ) h16 ] "::"              ls32
   / [ *5( h16 ":" ) h16 ] "::"              h16
   / [ *6( h16 ":" ) h16 ] "::"
h8          = 1*2HEXDIG
h16         = 1*4HEXDIG
ls32        = ( h16 ":" h16 ) / IPv4address
ipv4_prefix = dec-octet "." dec-octet "." dec-octet "." dec-octet “/” %d1-32
dec-octet   = DIGIT                     ; 0-9
                / %x31-39 DIGIT         ; 10-99
                / "1" 2DIGIT            ; 100-199
                / "2" %x30-34 DIGIT     ; 200-249
TCP_FLAGS example: "TCP_FLAGS": "16/255"
Note:
FIN =   0x01     "TCP_FLAGS": "0x01/63"
SYN = 0x02      "TCP_FLAGS": "0x02/63"
RST = 0x04      "TCP_FLAGS": "0x04/63"
PSH = 0x08      "TCP_FLAGS": "0x08/63"
ACK = 0x10      "TCP_FLAGS": "0x10/63"
URG = 0x20     "TCP_FLAGS": "0x20/63"

VLAN_ID example: "VLAN_ID": "20"

SONiC CLI (how to add and delete rules)

config acl add table

This command is used to create new ACL tables.

Usage:

config acl add table [OPTIONS] <table_name> <table_type> [-d <description>] [-p <ports>] [-s (ingress | egress)]
Parameters:
    table_name: The name of the ACL table to create.
    table_type: The type of ACL table to create (e.g. "L3", "L3V6", "MIRROR")
    description: A description of the table for the user. (default is the table_name)
    ports: A comma-separated list of ports/interfaces to add to the table. The behavior is as follows:
        Physical ports will be bound as physical ports
        Portchannels will be bound as portchannels - passing a portchannel member is invalid
        VLANs will be expanded into their members (e.g. "Vlan1000" will become "Ethernet0,Ethernet2,Ethernet4...")
    stage: The stage this ACL table will be applied to, either ingress or egress. (default is ingress)

Examples:

admin@nba721:~$ sudo config acl add table EXAMPLE_1 L3 -p Ethernet4,Ethernet8 -s ingress
admin@nba721:~$ sudo config acl add table EXAMPLE_2 L3V6 -p Vlan1000,Ethernet124 -s egress
admin@nba721:~$ show acl table
Name       Type    Binding      Description    Stage
---------  ------  -----------  -------------  -------
EXAMPLE    L3      Ethernet4    EXAMPLE_1      ingress
                   Ethernet8
EXAMPLE_2  L3V6    Ethernet0    EXAMPLE_2      egress
                   Ethernet124

config acl update full

This command is to update the rules in all the tables or in one specific table in full. If a table_name is provided, the operation will be restricted in the specified table. All existing rules in the specified table or all tables will be removed. New rules loaded from file will be installed.

If the table_name is specified, only rules within that table will be removed and new rules in that table will be installed. If the table_name is not specified, all rules from all tables will be removed and only the rules present in the input file will be added.

This command updates only the ACL rules, and it does not disturb the ACL tables; i.e., the output of the “show acl table” is not altered by using this command; only the output of the “show acl rule” will be changed after this command.

Notemight be replaced with “acl-loader update full”
admin@nba721:~$ config acl update full [--table_name <table_name>] [--session_name <session_name>] [--mirror_stage (ingress | egress)] [--max_priority <priority_value>] <acl_json_file_name>

Parameters:

“–table_name”: Specify the name of the ACL table to load.

config acl update full "--table_name DT_ACL_T1 /etc/sonic/acl_table_1.json"

“–mirror_stage” optional argument sets the mirror action to ingress/egress based on this parameter. By default, command sets ingress mirror action in case argument is not specified.

“–session_name” optional argument sets the session_name for the ACL table with this mirror session name. It fails if the specified mirror session name does not exist.

config acl update full "--session_name mirror_ses1 /etc/sonic/acl_table_1.json"

“–max_priority” optional argument make each rule’s priority calculation by subtracting its “sequence_id” value from the “max_priority”. If this value is not passed, the default “max_priority 10000” is used.

config acl update full "--max-priority 100 /etc/sonic/acl_table_1.json"
NoteAll these optional parameters should be inside double quotes. If none of the options are provided, double quotes are not required for specifying filename alone.
NoteAny number of optional parameters can be configured in the same command.

Examples:

admin@nba721:~$ sudo config acl update full /etc/sonic/acl_full_snmp_1_2_ssh_4.json
admin@nba721:~$ sudo config acl update full "--table_name UPSTREAMS /etc/sonic/acl_full.json"
admin@nba721:~$ sudo config acl update full "--session_name everflow0 /etc/sonic/acl_full_snmp_1_2_ssh_4.json"

Refer the example file acl_full_snmp_1_2_ssh_4.json that adds two rules for SNMP (Rule1 and Rule2) and one rule for SSH (Rule4).

config acl update incremental

This command is used to perform incremental update of ACL rule table. This command gets existing rules from Config DB and compares with rules specified in input file and performs corresponding modifications.

With respect to DATA ACLs, the command does not assume that new dataplane ACLs can be inserted in between by shifting existing ACLs in all ASICs. Therefore, this command performs a full update on dataplane ACLs. With respect to control plane ACLs, this command performs an incremental update. If we assume that “file1.json” is the already loaded ACL rules file, and if “file2.json” is the input file that is passed as a parameter for this command, the following requirements are valid for the input file.

1. First copy the file1.json to file2.json.
2. Remove the unwanted ACL rules from file2.json
3. Add the newly required ACL rules into file2.json.
4. Modify the existing ACL rules (that require changes) in file2.json.

Notemight be replaced with “acl-loader update incremental”
config acl update incremental [--session_name <session_name>] [--mirror_stage (ingress | egress)] [--max_priority <priority_value>] <acl_json_file_name>

Parameters are the same with the “acl update full” command.

Examples:

admin@nba721:~$ sudo config acl update incremental /etc/sonic/acl_incremental_snmp_1_3_ssh_4.json
admin@nba721:~$ sudo config acl update incremental "--session_name everflow0 /etc/sonic/acl_incremental_snmp_1_3_ssh_4.json"

Refer to the example file acl_incremental_snmp_1_3_ssh_4.json that adds two rules for SNMP (Rule1 and Rule3) and one rule for SSH (Rule4). When this “incremental” command is executed after the”full” command, SNMP Rule2 is removed and SNMP Rule3 is added. File “acl_full_snmp_1_2_ssh_4.json” has got SNMP Rule1, SNMP Rule2, and SSH Rule4. File “acl_incremental_snmp_1_3_ssh_4.json” has got SNMP Rule1, SNMP Rule3 and SSH Rule4. This file is created by copying the file “acl_full_snmp_1_2_ssh_4.json” to “acl_incremental_snmp_1_3_ssh_4.json” and then removing SNMP Rule2 and adding SNMP Rule3.

How to delete rules in SONiC

The same “config acl update full” command can remove unused or obsolete rules.

Omit the unused/obsolete rule from the update file and execute the command.

admin@nba721:~$ sudo config acl update incremental /etc/sonic/netberg_sonic_acl_full_snmp_1_remove_2_ssh_4.json

This example removes SNMP Rule2 by omitting it in the netberg_sonic_acl_full_snmp_1_remove_2_ssh_4.json

A simple example that removes all existing rules – acl_remove_all_rules.json

An alternative method that removes all existing rules:

acl-loader delete

aclshow

This command displays ACL rules, tables and their priority, ACL packet counters, and bytes counters.

Might be bugged in SONiC itself.

admin@nba721:~$ aclshow -h
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
admin@nba721:~$ aclshow -a -vv
Reading ACL info...
Total number of ACL Tables: 4
Total number of ACL Rules: 2
RULE NAME    TABLE NAME      PRIO  PACKETS COUNT    BYTES COUNT
-----------  ------------  ------  ---------------  -------------
ADM_ACCEPT   CTRL               1  N/A              N/A
Rule10       UPSTREAMS         10  N/A              N/A

MAC ACL

Netberg SONiC supports ACL actions based on MAC addresses.

Only PACKET_ACTION actions are supported.

Example:

Create a JSON file “acl_mac.json”:

 admin@nba721:~$sudo nano acl_mac.json
 {
   "ACL_TABLE": {
           "MAC_ACL_IPv4": {
           "policy_desc" : "Block MAC",
           "type" : "L3",
           "stage": "ingress",
           "ports" : [
                           "Ethernet0"
                       ]
           }
       },
       "ACL_RULE": {
       "MAC_ACL_IPv4|Rule101": {
           "PACKET_ACTION": "DROP",
           "PRIORITY": "1",
           "SRC_MAC": "b4:96:91:b3:c7:c9",
           "IP_TYPE": "IP"
           }
       }
   }

Apply it by:

admin@nba721:~$ sudo config load acl_mac.json -y
admin@nba721:~$ sudo config save -y

Check ACL:

 admin@nba721:~$ show acl table
 Name          Type    Binding    Description    Stage    Status
 ------------  ------  ---------  -------------  -------  --------
 MAC_ACL_IPv4  L3      Ethernet0  Block MAC      ingress  Active
 admin@nba721:~$ show acl rule
 Table         Rule     Priority    Action    Match                       Status
 ------------  -------  ----------  --------  --------------------------  --------
 MAC_ACL_IPv4  Rule101  1           DROP      IP_TYPE: IP                 Active
                                              SRC_MAC: b4:96:91:b3:c7:c9

Control Plane ACL

There is no CLI command for that.

First, create a table for the control plane:

admin@nba721:~$sudo nano service_table.json
{
"ACL_TABLE": {
        "CTRL": {
            "policy_desc": "CTRLPLN ACL",
            "services": [
                    "SSH",
                    "SNMP"
            ],
            "type": "CTRLPLANE"
        }
    }
}
admin@nba721:~$ sudo config load service_table.json -y
admin@nba721:~$ show acl table
Name    Type       Binding    Description    Stage    Status
------  ---------  ---------  -------------  -------  --------
CTRL    CTRLPLANE  SNMP       CTRLPLN ACL    ingress  Active
                   SSH

Second, create rules for it:

admin@nba721:~$sudo nano CTRL_ACL.json
{
    "ACL_RULE": {
        "CTRL|ADM_ACCEPT": {
            "PACKET_ACTION": "ACCEPT",
            "PRIORITY": "1",
            "SRC_IP": "192.168.0.10/24"
        }
    }
}
admin@nba721:~$ sudo config load CTRL_ACL.json -y
Running command: /usr/local/bin/sonic-cfggen -j CTRL_ACL.json --write-to-db
admin@nba721:~$ show acl rule
Table    Rule          Priority  Action    Match                    Status
-------  ----------  ----------  --------  -----------------------  --------
CTRL     ADM_ACCEPT           1  ACCEPT    SRC_IP: 192.168.0.10/24  N/A

The N/A value means that the ACL rule is a control plane ACL, and those counters are created in Linux, not in SONiC COUNTERS_DB and the iptables utility should be used to view those counters.

Notes

  1. TCP_FLAGS doesn’t support filtering Congestion Window Reduced (CWR) and ECN-Echo (ECE)
  2. Egress doesn’t support L4_SRC_PORT_RANGE
  3. Egress doesn’t support L4_DST_PORT_RANGE
  4. If any matching field has an IPv6 parameter – the table type should be changed to IPv6
NEWS

Latest news