# MikroTik RouterOS Manual > Official MikroTik RouterOS documentation: configuration reference, CLI reference, and user guides. This file contains all documentation content in a single document following the llmstxt.org standard. ## Certificates ## Overview **Sub-menu:** `/certificate` The general menu is used to manage certificates, add templates, issue certificates, and manage CRL and SCEP Clients. ### Certificate Template Certificate templates are used to prepare a desired certificate for signing. The Certificate template is deleted right after a certificate is signed or a certificate request command is executed ```ros /certificate add name=CA-Template common-name=CAtemp key-usage=key-cert-sign,crl-sign add name=Server common-name=server add name=Client common-name=client ``` To print out certificates: ```ros [admin@4k11] /certificate> print detail Flags: K - private-key; L - crl; C - smart-card-key; A - authority; I - issued, R - revoked; E - expired; T - trusted 0 name="CA-Template" key-type=rsa common-name="CAtemp" key-size=2048 subject-alt-name="" days-valid=365 key-usage=key-cert-sign,crl-sign 1 name="Server" key-type=rsa common-name="server" key-size=2048 subject-alt-name="" days-valid=365 key-usage=digital-signature,key-encipherment,data-encipherment,key-cert-sign,crl-sign,tls-server,tls-client 2 name="Client" key-type=rsa common-name="client" key-size=2048 subject-alt-name="" days-valid=365 key-usage=digital-signature,key-encipherment,data-encipherment,key-cert-sign,crl-sign,tls-server,tls-client ``` #### Certificate template properties During the certificate template creation process, it is possible to define and configure multiple parameters to meet specific requirements. | Property | Description | | :-- | :-- | | **common-name** (*string*) | Certificate common name | | **copy-from**(*name*) | Certificate name from which to copy general settings | | **country** (*string*) | Certificate issuer country | | **days-valid** (*days* Default: **365**) | Days certificate will be valid after signing | | **digest-algorithm** (*md5 \| sha1 \| sha256 \| sha384 \| sha512* Default: **sha256**) | Hash algorithm used to sign the certificate. | | **key-size** (*1024* \| *1536* \| *2048* \| *4096* \| *8192* \| *prime256v1* \| *secp384r1* \| *secp521r1* Default: **2048**) | Certificate public key size | | **key-usage** (*code-sign* \| *crl-sign* \| *decipher-only* \| *dvcs* \| *encipher-only* \| *key-cert-sign* \| *ocsp-sign* \| *tls-client* \| *content-commitment* \| *data-encipherment* \| *digital-signature* \| *email-protect* \| *key-agreement* \| *key-encipherment* \| *timestamp* \| *tls-server* Default: **digital-signature,key-encipherment,data-encipherment,key-cert-sign,crl-sign,tls-server,tls-client)** | Certificate usage | | **locality** (*string*) | Certificate issuer locality | | **name** (*string*) | Certificate name | | **organization** (*string*) | Certificate issuer organization | | **state** (*string*) | Certificate issuer state | | **subject-alt-name** (*DNS: \| IP: \| email:*) | Certificate subject alternative name | | **trusted** (*no \| yes*) | Whether to trust certificate. If *yes,*certificate will be used for host certificate verification. | | **trust-store**(*all* \| *capsman* \| *dns* \| *email* \| *ipsec* \| *mqtt* \| *openflow* \| *radius* \| *sstp* \| *userman* \| *www* \| *api* \| *container* \| *dot1x* \| *fetch* \| *lora* \| *netwatch* \| *ovpn* \| *tr069* \| *wpa-eap* \| *wiliot* \| *logging* Default: **all**) | Specify the service which can use a specific certificate for certificate verification or trust-chain creation (www, sstp). | | **unit** (*string*) | Certificate issuer organizational unit | ### Certificate properties For a signed certificate, most properties are read-only, with the exception of *name, trusted*, and *trust-store*. | Property | Description | | :-- | :-- | | **acme-status** *(string)* | ACME client status | | **common-name** (*string*) | Certificate common name | | **copy-from**(*name*) | Certificate name from which to copy general settings | | **country** (*string*) | Certificate issuer country | | **days-valid** (*days*) | Days certificate will be valid after signing | | **digest-algorithm** (*md5 \| sha1 \| sha256 \| sha384 \| sha512*) | Hash algorithm used to sign the certificate | | **directory-url** *(string)* | ACME client directory URL | | **domain-names** *(string)* | ACME client used domain names | | **key-size** (*1024* \| *1536* \| *2048* \| *4096* \| *8192* \| *prime256v1* \| *secp384r1* \| *secp521r1*) | Certificate public key size | | **key-usage** (*code-sign* \| *crl-sign* \| *decipher-only* \| *dvcs* \| *encipher-only* \| *key-cert-sign* \| *ocsp-sign* \| *tls-client* \| *content-commitment* \| *data-encipherment* \| *digital-signature* \| *email-protect* \| *key-agreement* \| *key-encipherment* \| *timestamp* \| *tls-server*) | Certificate usage | | **locality** (*string*) | Certificate issuer locality | | **organization** (*string*) | Certificate issuer organization | | **revoked** *(date)* | Certificate revoke time (only for certificates that are signed and revoked in a specific device) | | **state** (*string*) | Certificate issuer state | | **subject-alt-name** (*DNS \| IP \| email*) | Certificate subject alternative name | | **trusted** (*no \| yes*) | Whether to trust the certificate. If *yes*, certificate will be used for host certificate verification. | | **trust-store**(*all* \| *capsman* \| *dns* \| *email* \| *ipsec* \| *mqtt* \| *openflow* \| *radius* \| *sstp* \| *userman* \| *www* \| *api* \| *container* \| *dot1x* \| *fetch* \| *lora* \| *netwatch* \| *ovpn* \| *tr069* \| *wpa-eap* \| *wiliot* \| *logging*) | Specify service which can use a specific certificate for certificate verification or trust-chain creation (www, sstp). | | **unit** (*string*) | Certificate issuer organizational unit | | **serial-number** (*string*) | Certificate serial number | | **fingerprint** (*string*) | Certificate fingerprint | | **akid** (*string*) | Certificate authority ID | | **skid** (*string*) | Certificate subject ID | | **issuer** (*string*) | Certificate Authority | | **invalid-before** *(date)* | Date and time before which the certificate is not yet valid (validity start date). | | **invalid-after** *(date)* | Date and time after which the certificate is no longer valid (expiration date). | | **expires-after** *(time)* | Time left before expiration | | **key-type** (*string*) | Private key type | | **ca** *(string)* | CA certificate name (shown only for certificates that are signed in a specific device) | :::warning If the CA certificate is removed, all issued certificates in the chain are also removed. ::: ### Sign Certificate Certificates should be signed. In the following example, we will sign certificates and add a CRL URL for the server certificate: ```ros /certificate sign CA-Template sign Client sign Server ca-crl-host=192.168.88.1 name=ServerCA ``` Let's check if the certificates are signed: ```ros [admin@MikroTik] /certificate> print Flags: K - private-key; L - crl; A - authority; T - trusted Columns: NAME, COMMON-name, FINGERPRINT # NAME COMMON FINGERPRINT 0 K AT CA-Template CAtemp 0c7aaa7607a4dde1bbf33deaae6be7bac9fe4064ba47d64e8a73dcefad6cfc38 1 K AT Client client b3ff25ecb166ea41e15733a7493003f3ea66310c10390c33e98fe32364c3659f 2 KLAT ServerCA server 152b88c9d81f4b765a59e2302e01efd1fbf11ceeed6e59f4974e87787a5bb980 ``` For a video example, click [here.](http://youtube.com/watch?v=i2A3YIQKfwY) :::warning The time of the key signing process depends on the key size of a specific certificate. With values of 4k and higher, it might take substantial time to sign this specific certificate on less powerful CPU-based devices. ::: ### Export Certificate It is possible to export client certificates with keys and CA certificates in two formats - PEM or PKCS12. | Property | Description | | :-- | :-- | | **export-passphrase** (*string* Default: **none**) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | Passphrase that will be used for exported certificate private key encryption. | | **file-name** (*string* Default: **cert\_export\_[certificate name].crt/key/pkcs12**) | Exported certificate file name. | | **type** (*pem \| pkcs12* Default: **pem**) | Exported certificate type. In case of PEM, certificate will be exported with CRT extension, if export-passphrase is specified, also an encrypted private KEY file will be exported. In case of PKCS12, certificate will be exported with P12 extension, if export-passphrase is specified, exported certificate will contain an encrypted private key. The PKCS12 file is encrypted using AES. | ```ros /certificate export-certificate CA-Template export-certificate ServerCA export-passphrase=yourpassphrase export-certificate Client export-passphrase=yourpassphrase ``` Exported certificates are available under the */file* section: ```ros [admin@MikroTik] > file print Columns: NAME, TYPE, SIZE, CREATION-TIME # NAME TYPE SIZE CREATION-TIME 0 skins directory 2019-01-19 00:00:04 1 flash directory 2019-01-19 01:00:00 2 pub directory 2019-01-19 02:42:16 3 cert_export_CA-Template.crt .crt file 1119 2019-01-19 04:15:21 4 cert_export_ServerCA.crt .crt file 1229 2019-01-19 04:15:42 5 cert_export_ServerCA.key .key file 1858 2019-01-19 04:15:42 6 cert_export_Client.crt .crt file 1164 2019-01-19 04:15:55 7 cert_export_Client.key .key file 1858 2019-01-19 04:15:55 ``` :::warning Exporting certificates requires "sensitive" user policy. ::: ### Import Certificate To import certificates, certificates must be uploaded to a device using one of the file upload methods. Certificates must be imported as a file. Supported are PEM, DER, CRT, PKCS12 formats. PKCS12 import supports AES and 3DES decryption. | Property | Description | | :-- | :-- | | **name** (*string* Default: **file-name\_number**) | A certificate name that will be shown in the certificate manager | | **file-name** (*string*) | A file name that will be imported | | **passphrase** (*string* Default: **none**) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | File passphrase if there is one | | **trusted** (*yes \| no* Default: yes) | Adds *trusted* flag for the imported certificate | | **trust-store**(*all* \| *capsman* \| *dns* \| *email* \| *ipsec* \| *mqtt* \| *openflow* \| *radius* \| *sstp* \| *userman* \| *www* \| *api* \| *container* \| *dot1x* \| *fetch* \| *lora* \| *netwatch* \| *ovpn* \| *tr069* \| *wpa-eap* \| *wiliot* \| *logging* Default: **all**) | Specify the service which can use a specific certificate for certificate verification or trust-chain creation (www, sstp). | ```ros [admin@MikroTik] > /certificate/import file-name=certificate_file_name name=name_example passphrase=file_passphrase certificates-imported: 2 private-keys-imported: 1 files-imported: 1 decryption-failures: 0 keys-with-no-certificate: 0 [admin@MikroTik] > /certificate/print Flags: K - PRIVATE-KEY; T - TRUSTED Columns: NAME, COMMON-NAME # NAME COMMON-NAME 0 KT name_example cert 1 T name_example_1 ca ``` ### CRL RouterOS supports Certificate Revocation List (CRL) checking. By default, CRL is not utilized, and certificates are not verified for revocation status. Enable `crl-use=yes` in [certificate setting](#settings) to have the system verify every certificate in a chain against its CRL, and set `crl-download=yes` to let RouterOS automatically download and update CRLs. CRL can be added manually by providing the CRL URL, or dynamically when importing a certificate that contains a CRL Distribution Point. | Property | Description | | :-- | :-- | | **akid** (*string*) | CRL authority ID | | **cert**(*string*) | Certificate (from certificate store) from which the CRL Distribution Point was added | | **dynamic** (*flag*) | If CRL is dynamically added | | **expired** (*flag*) | If CRL is expired | | **fingerprint** (*string*) | CRL fingerprint | | **Invalid** (*flag*) | If CRL is invalid (not updated) | | **last-update** (*date*) | Date and time of last CRL update | | **next-update** (*date*) | Date and time of next CRL update | | **num** (*integer*) | CRL number | | **removed** (*integer*) | Count of revoced certificates | | **signature** (*string*) | CRL signature | | **url** (*string*) | CRL URL | | **num** (*integer*) | CRL number | ### Settings `/certificate/settings` allows configuring [Certificate Revocation List](#crl) and [built-in trust store](#built-in-trust-store-authorities) settings. | Property | Description | | :-- | :-- | | **builtin-trust-store** (*all* \| *default* \| *capsman* \| *dns* \| *email* \| *ipsec* \| *mqtt* \| *openflow* \| *radius* \| *sstp* \| *userman* \| *www* \| *api* \| *container* \| *dot1x* \| *fetch* \| *lora* \| *netwatch* \| *ovpn* \| *tr069* \| *wpa-eap* \| *wiliot* \| *logging* \| *untrusted* Default: **default**) | Services that can use [built-in trust store authorities](#built-in-trust-store-authorities) for certificate verification. The current defaults: fetchmqttemailnetwatchcontainerloradnswwwreverse-proxy | | **crl-download** (*yes \| no* Default: **no**) | Whether to automatically download/update CRL | | **crl-store** (*ram \| system* Default: **ram**) | Where to store downloaded CRL information CRL will be automatically renewed every hour for certificates which have "trusted=yes" using http protocol (ldap and ftp are currently unsupported) | | **crl-use** (*yes \| no* Default: **no**) | Whether to use CRL | :::warning If *`/certificate/settings/set crl-use`* is set to *`yes`*, RouterOS will check CRL for each certificate in a certificate chain, therefore, an entire certificate chain should be installed into a device - starting from Root CA, intermediate CAs (if there are such), and certificate that is used for a specific service. ::: An [example](http://youtube.com/watch?v=q9oMO3_jvBU) on importing a root certificate. ## ACME client The ACME client automates the acquisition and renewal of multiple TLS certificates via ACME. To add a new ACME client via CLI, use the command `/certificate/add-acme`. Existing ACME clients appear in the Certificates view and are marked with the `a` (acme-manage) flag. Domain names must resolve to the router, and TCP port 80 must be accessible from the WAN (the HTTP-01 challenge is used). For an IP Cloud `.sn.mynetname.net` domain name, the DNS-01 challenge is used instead. Certificates are automatically renewed when 80% of their validity period has elapsed. If the certificate is not retrieved during the initial setup, a new ACME client must be added. ### Properties | Property | Description | | :-- | :-- | | **directory-url** (*string*) | ACME directory URL | | **domain-names** (*string*) | comma-separated list of domain names | | **eab-hmac-key** (*string*) | HMAC key for ACME External Account Binding | | **eab-kid** (*string*) | Key identifier | | **name** (*string*) | ACME client name | ### Manual ACME renewal To manually trigger ACME certificate renewal: ```ros /certificate/acme-renew [name] ``` For example: ```ros /certificate/acme-renew numbers=0 ``` ### Let's Encrypt certificate To retrieve a Let's Encrypt certificate with automatic certificate renewal, you must manually provide a domain name with the `domain-names` parameter: ```ros /certificate/add-acme domain-names=router.example.com ``` To generate a Let's Encrypt certificate for an [IP Cloud](/docs/network-management/cloud#ddns) name (for example, `example.sn.mynetname.net`), provide the `dns-name` from the `/ip/cloud` menu as the domain name, or read it inline with `[/ip/cloud/get dns-name]`: ```ros /certificate/add-acme domain-names=[/ip/cloud/get dns-name] ``` :::info The Let's Encrypt directory is used if `directory-url` is not provided. ::: ## SCEP SCEP is using the HTTP protocol and base64 encoded GET requests. Most of the requests are without authentication and cipher, however, important ones can be protected if necessary (ciphered or signed using a received public key). SCEP client in RouterOS will: - Get CA certificate from CA server or RA (if used). - User should compare the fingerprint of the CA certificate or if it comes from the right server. - Generate a self-signed certificate with a temporary key. - Send a certificate request to the server. - If the server responds with status x, then the client keeps requesting until the server sends an error or approval. The SCEP server supports the issuance of one certificate only. RouterOS also supports renew and next-ca options: - renew - the possibility to renew the old certificate automatically with the same CA. - next-ca - the possibility to change the current CA certificate to the new one. The client polls the server for any changes, if the server advertises that the next-ca is available, then the client may request the next CA or wait until the CA almost expires and then request the next-ca. The RouterOS client by default will try to use POST, AES, and SHA256 if the server advertises that. If the above algorithms are not supported, then the client will try to use 3DES, DES and SHA1, MD5. SCEP certificates are renewed when 3/4 of their validity time has passed. ## Built-in trust store authorities RouterOS contains a list of built-in root certificate authorities that specific services can use for host certificate verification. The list of services that can use built-in root certificate authorities can be found in the [Settings](#settings) section. It is possible to use [DoH](../network-management/dns.md) with certificate validation without the need to manually import the relevant root certificate. The list of built-in root certificate authorities is accessible in System → Certificates → Built In CA --- ## Dot1X Dot1X is an implementation of the IEEE 802.1X standard in RouterOS. The main purpose is to provide port-based network access control using EAP over LAN also known as EAPOL. 802.1X consists of a supplicant (client), an authenticator (server) and an authentication server (RADIUS server). Both authenticator and supplicant sides are supported in RouterOS, as well as the authentication server when [User Manager](./user-manager.md) package is installed. Supported EAP methods for the supplicant are EAP-TLS, EAP-TTLS, EAP-MSCHAPv2 and PEAPv0/EAP-MSCHAPv2. :::warning The feature is not supported on SMIPS devices (hAP lite, hAP lite TC and hAP mini). ::: ## Client Supplicant configuration settings. **Sub-menu:** `/interface/dot1x/client` | Property | Description | | :-- | :-- | | **anon-identity** (*string*; Default: ) | Identity for outer layer EAP authentication. Used only with `eap-ttls` and `eap-peap` methods. If not set, value from `identity` parameter will be used for outer layer EAP authentication. | | **client-certificate** (*string*; Default: ) | Name of a certificate listed in [System/Certificates](./certificates.md). Necessary when `eap-tls` method is used. | | **comment** (*string*; Default: ) | Short description of the entry. | | **disabled** (*yes \| no*; Default: **no**) | Whether client is enabled or not. | | **eap-methods** (*eap-tls \| eap-ttls \| eap-peap \| eap-mschapv2*; Default: ) | Ordered list of EAP methods used for authentication. | | **identity** (*string*; Default: ) | Supplicant identity used for EAP authentication. | | **interface** (*string*; Default: ) | Name of the interface the client will run on. | | **password** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | Cleartext password for supplicant. | ### Read only properties | Property | Description | | :-- | :-- | | **status** (*authenticated \| authenticating \| disabled*) | Possible statuses:authenticated - the client has successfully authenticated.authenticating - the server is reached and the authentication process is ongoing.disabled - the client is disabled.error - an internal error has occurred.interface is down - the parent interface is not running.rejected - the server denied the authentication. | ## Server --- A RouterOS dot1x server acts as an authenticator. An interface where dot1x server is enabled will block all traffic except for EAPOL packets which are used for the authentication. After the client is successfully authenticated, the interface will accept all received traffic on the port. If the interface is connected to a shared medium with multiple hosts, the traffic will be accepted from all hosts when at least one client is successfully authenticated. However, it is possible to [configure dynamic switch rules](./dot1x.md#dynamic-switch-rule-configuration) to accept only the authenticated user source MAC address and drop all other source MAC addresses. In case of failed authentication, it is possible to accept the traffic with a dedicated port VLAN ID. :::warning When a dot1x server is created on a bridge port, the bridge should be running (R/M)STP, otherwise EAP packets from the client will not be correctly accepted. The bridge interface is created with `protocol-mode=rstp` by default. If the bridge port should not send any BPDUs or any received BPDUs should be ignored, use `edge=yes` configuration on bridge ports. ::: **Sub-menu:** `/interface/dot1x/server` | Property | Description | | :-- | :-- | | **accounting** (*yes \| no*; Default: **yes**) | Whether to send RADIUS accounting requests to the authentication server. | | **auth-timeout** (*time*; Default: **1m**) | Total time available for EAP authentication. | | **auth-types** (*dot1x \| mac-auth*; Default: **dot1x**) | Used authentication type on a server interface. When both options are selected at the same time, the server will prefer `dot1x` authentication type and only after 3 `retrans-timeout` periods, the authentication type will fall back to `mac-auth`. In order for `mac-auth` authentication type to work, the server interface should receive at least one frame containing a client's device source MAC address. | | **comment** (*string*; Default: ) | Short description of the entry. | | **disabled** (*yes \| no*; Default: **no**) | Whether server config is enabled or not. | | **guest-vlan-id** (*integer: 1..4094*; Default: **!guest-vlan-id**) | Assigned VLAN when end devices do not support `dot1x` authentication and no `mac-auth` fall back is configured. The setting will apply after 3 `retrans-timeout` periods. Once a dot1x enabled client is created and successful re-authentication has happened, the port is removed from the guest VLAN. This setting is available since RouterOS 7.2 version and has an effect when bridge `vlan-filtering` is enabled. By default, guest VLAN is disabled. | | **interface** (*string*; Default: ) | Name of the interface or interface list the server will run on. | | **interim-update** (*time*; Default: **0s**) | Interval between scheduled RADIUS Interim-Update messages. | | **mac-auth-mode** (*mac-as-username \| mac-as-username-and-password*; Default: **mac-as-username**) | Allows controlling User-Name and User-Password RADIUS attributes when using MAC authentication. | | **radius-mac-format** (*XX-XX-XX-XX-XX-XX \| XX:XX:XX:XX:XX:XX \| XXXXXXXXXXXX \| xx-xx-xx-xx-xx-xx \| xx:xx:xx:xx:xx:xx \| xxxxxxxxxxxx*; Default: **XX:XX:XX:XX:XX:XX**) | Controls how the MAC address of the client is encoded in the User-Name and User-Password attributes when using MAC authentication. | | **reauth-timeout**(*time*; Default: **!reauth-timeout**) | Enables server port re-authentication. When enabled with `dot1x` authentication type, the server will try to re-authenticate a client by sending EAP-Request Identity to the client. When enabled with `mac-auth` authentication type, the server will try to re-authenticate a client with the RADIUS server by using the last seen MAC address. This setting is available since RouterOS 7.2 version. By default, re-authentication is disabled. | | **reject-vlan-id** (*integer: 1..4094*; Default: **!reject-vlan-id**) | Assigned VLAN when authentication failed and a RADIUS server responded with an Access-Reject message. This property will not apply if the RADIUS server is not responding at all, the client authentication will simply timeout and the service will be unavailable. This property only has an effect when bridge `vlan-filtering` is enabled. By default, reject VLAN is disabled. | | **retrans-timeout** (*time*; Default: **30s**) | Time interval between message re-transmissions if no response is received from supplicant. | | **server-fail-vlan-id** (*integer: 1..4094*; Default: **!server-fail-vlan-id**) | Assigned VLAN when the RADIUS server is not responding and the request timeout has elapsed. This setting is available since RouterOS 7.2 version and has an effect when bridge `vlan-filtering` is enabled. By default, server-fail VLAN is disabled. | Currently authenticated clients are listed in the active menu (read-only properties). **Sub-menu:** `/interface/dot1x/server/active` | Property | Description | | :-- | :-- | | **auth-info** (*string*) | Authentication information: dot1xdot1x (guest vlan)dot1x (reject vlan)dot1x (server fail vlan)mac-authmac-auth (reject vlan)mac-auth (server fail vlan) | | **client-mac** (*mac-address*) | MAC Address of the supplicant. | | **interface** (*string*) | Name of the interface. | | **session-id** (*string*) | Unique session identifier. | | **username** (*string*) | Identity of the supplicant. | | **vlan-id** (*string*) | Untagged VLAN ID that is assigned to the interface. VLAN ID filtering must be enabled on bridge. | Statuses of all active dot1x server interfaces are listed in the state menu (read-only properties). **Sub-menu:** `/interface/dot1x/server/state` | Property | Description | | :-- | :-- | | **interface** (*string*) | Name of the interface. | | **status** (*string*) | Possible interface statuses:authorized - access to the interface is granted;iface-down - the interface is not running;rejected-holding - access was rejected by the RADIUS server;un-authorized - access to the interface is not granted. | ## Examples Described below are the most common configuration examples for dot1x server and client. ### RouterOS Authenticator configuration ![](./img/dot1x-01.webp) Start off by adding a new RADIUS client. The authentication server (RADIUS) does not necessarily have to be in the same LAN as authenticator, but it must be reachable from the authenticator, so any firewall limitations must be considered. ```ros /radius add address=10.1.2.3 secret=radiussecret service=dot1x ``` :::warning If RADIUS communication is done over a public network, it is advised to use RadSec for RADIUS communication. More information: [RADIUS](./radius.md) ::: Add new dot1x server instances. ```ros /interface/dot1x/server add interface=ether2 interim-update=30s comment=accounted add interface=ether12 accounting=no comment=notaccounted ``` #### Port based VLAN ID assignment It is possible to assign an authenticated interface to a specific VLAN ID using bridge VLAN filtering. This can be done using RADIUS Tunnel-Type, Tunnel-Medium-Type and Tunnel-Private-Group-ID attributes. Note that only devices with hardware offloaded VLAN filtering will be able to do this in the switch chip. First of all, make sure the interface is added to a bridge which has VLAN filtering enabled. ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=ether12 ``` It is necessary to add static VLAN configuration for tagged VLAN traffic to be sent over the ether1 interface. ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether1 vlan-ids=2 add bridge=bridge1 tagged=ether1 vlan-ids=12 ``` With enabled RADIUS debug logs it is possible to see complete RADIUS message packets with all attributes. In our example, Tunnel attributes are received in the Access-Accept message from the RADIUS server: ```text 09:51:45 radius,debug,packet received Access-Accept with id 64 from 10.1.2.3:1812 09:51:45 radius,debug,packet Tunnel-Type = 13 09:51:45 radius,debug,packet Tunnel-Medium-Type = 6 09:51:45 radius,debug,packet Tunnel-Private-Group-ID = "12" (..) 09:51:45 radius,debug,packet User-Name = "dot1x-user" ``` The VLAN ID is now present in the active session list and untagged ports are added to the previously created static VLAN configuration. ```ros /interface/dot1x/server/active/print 0 interface=ether12 username="dot1x-user" client-mac=00:0C:42:EB:71:F6 session-id="86b00006" vlan-id=12 ``` ```ros /interface/bridge/vlan/print detail Flags: X - disabled, D - dynamic 0 D bridge=bridge1 vlan-ids=1 tagged="" untagged="" current-tagged="" current-untagged=bridge1,ether3 1 bridge=bridge1 vlan-ids=2 tagged=ether1 untagged="" current-tagged=ether1 current-untagged=ether2 2 bridge=bridge1 vlan-ids=12 tagged=ether1 untagged="" current-tagged=ether1 current-untagged=ether12 ``` #### Dynamic switch rule configuration In some network configurations, additional access rules are needed for a particular supplicant to restrict or allow certain network services. This can be done using a Mikrotik-Switching-Filter attribute, please see the [RADIUS vendor dictionary](./radius.md). When a client is successfully authenticated by an authentication server, the server can pass back the Mikrotik-Switching-Filter attribute. Based on the received information, the authenticator will create dynamic access rules on a switch port where the client resides. These rules will be active as long as the client session is active and the interface is running. There are certain orders and restrictions regarding correct switch rule implementation: - The `mac-protocol`, `src-mac-address` (available only since RouterOS 7.2 version), `src-address` (IPv4/mask, available only since RouterOS 7.2 version), `dst-address` (IPv4/mask), `protocol` (IPv4) `src-port` (L4, available only since RouterOS 7.2 version), `dst-port` (L4) conditional parameters are supported. - Hexadecimal or decimal representation can be used for `mac-protocol` and `protocol` parameters (e.g. `protocol 17` or `protocol 0x11`). - The `src-port` and `dst-port` support single or range values (e.g. `src-port 10` or `src-port 10-20`). - The `src-mac-address` supports "xx:xx:xx:xx:xx:xx" or "xxxxxxxxxxxx" formats, and a switch rule without any source MAC address can be set with "none" keyword (e.g.`src-mac-address none`). - The `src-mac-address` (if not already set by the attribute)`, switch` and `ports` conditional parameters are automatically set for each rule - Each rule should end with an action property, supported values are either **drop** or **allow**. If no action property is set, the default **allow** value will be used. - Multiple rules are supported for a single supplicant and they must be separated by a comma ",". Below are some examples of Mikrotik-Switching-Filter attributes and dynamic switch rules they create: ```ros # Drop ARP frames (EtherType: 0x0806 or 2054) Mikrotik-Switching-Filter = "mac-protocol 2054 action drop" /interface/ethernet/switch/rule/print Flags: X - disabled, I - invalid, D - dynamic 0 D ;;; dot1x dynamic switch=switch1 ports=ether1 src-mac-address=CC:2D:E0:11:22:33/FF:FF:FF:FF:FF:FF mac-protocol=arp copy-to-cpu=no redirect-to-cpu=no mirror=no new-dst-ports="" # Allow UDP (IP protocol: 0x11 or 17) destination port 100 and drop all other packets Mikrotik-Switching-Filter = "protocol 17 dst-port 100 action allow, action drop" /interface/ethernet/switch/rule/print Flags: X - disabled, I - invalid, D - dynamic 0 D ;;; dot1x dynamic switch=switch1 ports=ether1 src-mac-address=CC:2D:E0:11:22:33/FF:FF:FF:FF:FF:FF protocol=udp dst-port=100 copy-to-cpu=no redirect-to-cpu=no mirror=no 1 D ;;; dot1x dynamic switch=switch1 ports=ether1 src-mac-address=CC:2D:E0:11:22:33/FF:FF:FF:FF:FF:FF copy-to-cpu=no redirect-to-cpu=no mirror=no new-dst-ports="" # Allow only authenticated source MAC address, drop all other packets Mikrotik-Switching-Filter = "action allow, src-mac-address none action drop" /interface/ethernet/switch/rule/print Flags: X - disabled, I - invalid; D - dynamic 0 D ;;; dot1x dynamic switch=switch1 ports=ether1 src-mac-address=CC:2D:E0:01:6D:EB/FF:FF:FF:FF:FF:FF copy-to-cpu=no redirect-to-cpu=no mirror=no 1 D ;;; dot1x dynamic switch=switch1 ports=ether1 copy-to-cpu=no redirect-to-cpu=no mirror=no new-dst-ports="" ``` In our example, Supplicant2 on ether2 is only allowed to access the 192.168.50.0/24 network with UDP destination port 50; all other traffic should be dropped. First, make sure that hardware offloading is working on bridge ports, otherwise switch rules might not work properly. ```ros /interface/bridge/port/print Flags: X - disabled, I - inactive, D - dynamic, H - hw-offload # INTERFACE BRIDGE HW PVID PRIORITY PATH-COST INTERNAL-PATH-COST HORIZON 0 H ether1 bridge1 yes 1 0x80 10 10 none 1 H ether2 bridge1 yes 1 0x80 10 10 none 2 H ether12 bridge1 yes 1 0x80 10 10 none ``` With enabled RADIUS debug logs it is possible to see complete RADIUS message packets with all attributes. In our example, the Mikrotik-Switching-Filter attribute is received in the Access-Accept message from the Radius server: ```text 02:35:38 radius,debug,packet received Access-Accept with id 121 from 10.1.2.3:1812 (..) 02:35:38 radius,debug,packet MT-Switching-Filter = "mac-protocol 2048 dst-address 192.168.50.0/24 dst-port 50 protocol 17 action allow,action drop" ``` The dynamic switch rules are now present under the switch menu: ```ros /interface/ethernet/switch/rule/print Flags: X - disabled, I - invalid; D - dynamic 0 D ;;; dot1x dynamic switch=switch1 ports=ether2 src-mac-address=CC:2D:E0:11:22:33/FF:FF:FF:FF:FF:FF mac-protocol=ip dst-address=192.168.50.0/24 protocol=udp dst-port=50 copy-to-cpu=no redirect-to-cpu=no mirror=no 1 D ;;; dot1x dynamic switch=switch1 ports=ether2 src-mac-address=CC:2D:E0:11:22:33/FF:FF:FF:FF:FF:FF copy-to-cpu=no redirect-to-cpu=no mirror=no new-dst-ports="" ``` :::warning Dynamic switch rules will only apply to RouterBoards with switch rule support - MikroTik devices with Marvell Prestera switch and devices with QCA8337, Atheros8327 and Atheros8316 switch chips. CRS1xx/2xx series switches do not support this functionality. Take into consideration the maximum number of rules for each device, see [MikroTik devices with Marvell Prestera switch](../bridging-and-switching/marvell-prestera-switch-chip-features.md#models) and [basic switch chip table](../bridging-and-switching/switch-chip-features.md) ::: ### RouterOS Supplicant configuration CA certificates are required for `eap-tls, eap-ttls` and `eap-peap` authentication methods. Additionally a client certificate is required for `eap-tls` method. For this example we have already imported a P12 certificate bundle with self-signed client and CA certificates. For more information on how to import certificates in RouterOS, please visit [System/Certificates](./certificates.md). ```ros /certificate/print Flags: K - private-key, L - crl, C - smart-card-key, A - authority, I - issued, R - revoked, E - expired, T - trusted # NAME COMMON-NAME SUBJECT-ALT-NAME FINGERPRINT 0 K A T dot1x-client ez_dot1x-client IP:10.1.2.34 1 L A T dot1x CA ca ``` Simply add a new dot1x client instance that will initiate the authentication process. ```ros /interface/dot1x/client add anon-identity=anonymous client-certificate=dot1x-client eap-methods=eap-tls identity=dot1x-user interface=ether1 password=dot1xtest ``` If authentication was successful, the interface should have status authenticated. ```ros /interface/dot1x/client/print Flags: I - inactive, X - disabled 0 interface=ether1 eap-methods=eap-tls identity="dot1x-user" password="dot1xtest" anon-identity="anonymous" client-certificate=dot1x-client status="authenticated" ``` --- ## Hotspot customisation #### Introduction You can create a completely different set of servlet pages for each HotSpot server you have, specifying the directory in the "html-directory-override" property of a HotSpot server profile `/ip/hotspot/profile`. The default servlet pages are copied in the "hotspot" directory right after you create the server profile. This directory can be accessed by connecting to the router with an FTP client. You can copy this directory and modify the pages as you like using the information from this section of the manual. Note that it is suggested to edit the files manually, as automated HTML editing tools may corrupt the pages by removing variables or other vital parts. After you are finished with content modification you need to upload this modified content to some custom directory on the hotspot router and point the previously mentioned property "html-directory-override" value as the path to this new custom HTML directory. **Note:** If the "html-directory-override" value path is missing or empty then the hotspot server will revert to default HTML files. #### Available Pages Main HTML servlet pages, which are shown to the user: - **redirect.html** - Redirects the user to another URL (for example, to the login page). - **login.html** - Login page shown to a user to ask for a username and password. This page may take the following parameters: - **username** - Username. - **password** - Either a plain-text password (in case of PAP authentication) or an MD5 hash of the chap-id variable, password, and CHAP challenge (in case of CHAP authentication). This value is used as an e-mail address for trial users. - **dst** - Original URL requested before the redirect. This will be opened on successful login. - **popup** - Whether to pop up a status window on successful login. - **radius\** - Send the attribute identified with \ in text string form to the RADIUS server (in case RADIUS authentication is used; lost otherwise). - **radius\u** - Send the attribute identified with \ in unsigned integer form to the RADIUS server (in case RADIUS authentication is used; lost otherwise). - **radius\-\** - Send the attribute identified with \ and vendor ID \ in text string form to the RADIUS server (in case RADIUS authentication is used; lost otherwise). - **radius\-\u** - Send the attribute identified with \ and vendor ID \ in unsigned integer form to the RADIUS server (in case RADIUS authentication is used; lost otherwise). - **md5.js** - JavaScript for MD5 password hashing. Used together with http-chap login method. - **alogin.html** - Page shown after a client has logged in. It pops up the status page and redirects the browser to the originally requested page (before he/she was redirected to the HotSpot login page). - **status.html** - Status page, shows statistics for the client. It is also able to display advertisements automatically. - **logout.html** - Logout page, shown after a user is logged out. Shows final statistics about the finished session. This page may take the following additional parameters: - **erase-cookie** - Whether to erase cookies from the HotSpot server on logout (makes it impossible to log in with a cookie next time from the same browser, might be useful in multiuser environments). - **error.html** - Error page, shown on fatal errors only. Some other pages are available as well, if more control is needed: - **rlogin.html** - page that redirects the client from some other URL to the login page, if authorization of the client is required to access that URL - **rstatus.html** - similar to rlogin.html, only in case the client is already logged in and the original URL is not known - **radvert.html** - redirects the client to the scheduled advertisement link - **flogin.html** - shown instead of login.html, if some error has happened (invalid username or password, for example) - **fstatus.html** - shown instead of redirect, if a status page is requested, but the client is not logged in - **flogout.html** - shown instead of redirect, if the logout page is requested, but the client is not logged in #### Serving Servlet Pages The HotSpot servlet recognizes 5 different request types: 1. **Request for a remote host** - If the user is logged in and the advertisement is due to be displayed, radvert.html is displayed. This page redirects to the scheduled advertisement page. - If the user is logged in and the advertisement is not scheduled for this user, the requested page is served. - If the user is not logged in, but the destination host is allowed by the walled garden, then the request is also served. - If the user is not logged in, and the destination host is disallowed by the walled garden, rlogin.html is displayed; if rlogin.html is not found, redirect.html is used to redirect to the login page. 2. **Request for "/" on the HotSpot host** - If the user is logged in, rstatus.html is displayed; if rstatus.html is not found, redirect.html is used to redirect to the status page. - If the user is not logged in, rlogin.html is displayed; if rlogin.html is not found, redirect.html is used to redirect to the login page. 3. **Request for "/login" page** - If the user has successfully logged in (or is already logged in), alogin.html is displayed; if alogin.html is not found, redirect.html is used to redirect to the originally requested page or the status page (in case the original destination page was not given). - If the user is not logged in (username was not supplied, no error message appeared), login.html is shown. - If the login procedure has failed (an error message is supplied), flogin.html is displayed; if flogin.html is not found, login.html is used. - In case of fatal errors, error.html is shown. 4. **Request for "/status" page** - If the user is logged in, status.html is displayed. - If the user is not logged in, fstatus.html is displayed; if fstatus.html is not found, redirect.html is used to redirect to the login page. 5. **Request for '/logout' page** - If the user is logged in, logout.html is displayed. - If the user is not logged in, flogout.html is displayed; if flogout.html is not found, redirect.html is used to redirect to the login page. **Note:** If it is not possible to meet a request using the pages stored on the router's FTP server, Error 404 is displayed. There are many ways to customize what the HotSpot authentication pages look like: - The pages are easily modifiable. They are stored on the router's FTP server in the directory you choose for the respective HotSpot server profile. - By changing the variables, which the client sends to the HotSpot servlet, it is possible to reduce the keyword count to one (username or password; for example, the client's MAC address may be used as the other value) or even to zero (License Agreement; some predefined values general for all users or the client's MAC address may be used as username and password). - Registration may occur on a different server (for example, on a server that is able to charge Credit Cards). The client's MAC address may be passed to it, so that this information doesn't have to be entered manually. After the registration, the server should change the RADIUS database enabling the client to log in for some amount of time. To insert a variable in some place in the HTML file, the $(var\_name) syntax is used, where the "var\_name" is the name of the variable (without quotes). This construction may be used in any HotSpot HTML file accessed as '/', '/login', '/status' or '/logout', as well as any text or HTML (.txt, .htm or .html) file stored on the HotSpot server (with the exception of traffic counters, which are available in the status page only, and **error**, **error-orig**, **chap-id**, **chap-challenge** and **popup** variables, which are available in the login page only). For example, to show a link to the login page, the following construction can be used: ``` login ``` #### Variables All of the Servlet HTML pages use variables to show user specific values. Variable names appear only in the HTML source of the servlet pages - they are automatically replaced with the respective values by the HotSpot Servlet. For most variables, there is an example of their possible value included in brackets. All the described variables are valid in all servlet pages, but some of them just might be empty at the time they are accessed (for example, there is no uptime before a user has logged in). ##### List of available variables **Note:** Some of the variables use hard-coded http URLs, if you are using https, you can construct the link in some other way, for example for $link-status, you can use https://$(hostname)/$(target-dir)status **Common server variables:** - **hostname** - DNS name or IP address (if DNS name is not given) of the HotSpot Servlet ("[hotspot.example.net](http://hotspot.example.net)"). - **identity** - RouterOS identity name ("MikroTik"). - **login-by** - Authentication method used by the user. - **plain-passwd** - A "yes/no" representation of whether HTTP-PAP login method is allowed ("no"). - **server-address** - HotSpot server address ("10.5.50.1:80"). - **ssl-login** - A "yes/no" representation of whether HTTPS method was used to access that servlet page ("no"). - **server-name** - HotSpot server name (set in the `/ip/hotspot` menu, as the name property). **Links:** - **link-login** - link to the login page including the original URL requested ("[http://10.5.50.1/login?dst=http://www.example.com/](http://10.5.50.1/login?dst=http://www.example.com/)") - **link-login-only** - link to the login page, not including the original URL requested ("[http://10.5.50.1/login](http://10.5.50.1/login)") - **link-logout** - link to the logout page ("[http://10.5.50.1/logout](http://10.5.50.1/logout)") - **link-status** - link to the status page ("[http://10.5.50.1/status](http://10.5.50.1/status)") - **link-orig** - the original URL requested ("[http://www.example.com/](http://www.example.com/)") **General client information:** - **domain** - Domain name of the user ("[example.com](http://example.com)"). - **interface-name** - Physical HotSpot interface name (in case of bridged interfaces, this will return the actual bridge port name). - **ip** - IP address of the client ("10.5.50.2"). - **logged-in** - "yes" if the user is logged in, otherwise - "no" ("yes"). - **mac** - MAC address of the user ("01:23:45:67:89:AB"). - **trial** - A "yes/no" representation of whether the user has access to trial time. If the user's trial time has expired, the value is "no". - **username** - The name of the user ("John"). - **host-ip** - Client IP address from the `/ip/hotspot/host` table. - **vlan-id** - Represents the ID of a VLAN interface from which the client is connected. **User status information:** - **idle-timeout** - Idle timeout ("20m" or "" if none). - **idle-timeout-secs** - Idle timeout in seconds ("88" or "0" if there is no such timeout). - **limit-bytes-in** - Byte limit for send ("1000000" or "---" if there is no limit). - **limit-bytes-out** - Byte limit for receive ("1000000" or "---" if there is no limit). - **refresh-timeout** - Status page refresh timeout ("1m30s" or "" if none). - **refresh-timeout-secs** - Status page refresh timeout in seconds ("90s" or "0" if none). - **session-timeout** - Session time left for the user ("5h" or "" if none). - **session-timeout-secs** - Session time left for the user, in seconds ("3475" or "0" if there is no such timeout). - **session-time-left** - Session time left for the user ("5h" or "" if none). - **session-time-left-secs** - Session time left for the user, in seconds ("3475" or "0" if there is no such timeout). - **uptime** - Current session uptime ("10h2m33s"). - **uptime-secs** - Current session uptime in seconds ("125"). **Traffic counters, which are available only on the status page:** - **bytes-in** - Number of bytes received from the user ("15423"). - **bytes-in-nice** - User-friendly form of the number of bytes received from the user ("15423"). - **bytes-out** - Number of bytes sent to the user ("11352"). - **bytes-out-nice** - User-friendly form of the number of bytes sent to the user ("11352"). - **packets-in** - Number of packets received from the user ("251"). - **packets-out** - Number of packets sent to the user ("211"). - **remain-bytes-in** - Remaining bytes until limit-bytes-in will be reached ("337465" or "---" if there is no limit). - **remain-bytes-out** - Remaining bytes until limit-bytes-out will be reached ("124455" or "---" if there is no limit). **Miscellaneous variables:** - **session-id** - Value of 'session-id' parameter in the last request. - **var** - Value of 'var' parameter in the last request. - **error** - Error message, if something failed ("invalid username or password"). - **error-orig** - Original error message (without translations retrieved from errors.txt), if something failed ("invalid username or password"). - **chap-id** - Value of chap ID ("\371"). - **chap-challenge** - Value of chap challenge ("\357\015\330\013\021\234\145\245\303\253\142\246\133\175\375\316"). - **popup** - Whether to pop-up checkbox ("true" or "false"). - **advert-pending** - Whether an advertisement is pending to be displayed ("yes" or "no"). - **http-status** - Allows the setting of the http status code and message. - **http-header** - Allows the setting of the http header. **RADIUS-related variables:** - **radius\** - shows the attribute identified with \ in text string form (in case RADIUS authentication was used; "" otherwise) - **radius\u** - shows the attribute identified with \ in unsigned integer form (in case RADIUS authentication was used; "0" otherwise) - **radius\-\** - shows the attribute identified with \ and vendor ID \ in text string form (in case RADIUS authentication was used; "" otherwise) - **radius\-\u** - shows the attribute identified with \ and vendor ID \ in unsigned integer form (in case RADIUS authentication was used; "0" otherwise) ##### Working with variables $(if \) statements can be used in these pages. The following content will be included, if the value of \ will not be an empty string. It is equivalent to $(if \ != "") It is possible to compare on equivalence as well: $(if \ == \) These statements have effect until $(elif \), $(else) or $(endif). In the general case it looks like this: ``` some content, which will always be displayed $(if username == john) Hey, your username is john $(elif username == dizzy) Hello, Dizzy! How are you? Your administrator. $(elif ip == 10.1.2.3) You are sitting at that old computer, which is so slow... $(elif mac == 00:01:02:03:04:05) This is an ethernet card, which was stolen few months ago... $(else) I don't know who you are, so lets live in peace. $(endif) other content, which will always be displayed ``` Only one of those expressions will be shown. Which one depends on the values of those variables for each client. ##### Redirects and custom Headers ``` $(if http-status == 302)Hotspot login required$(endif) $(if http-header == "Location")$(link-redirect)$(endif) ``` **Note:** Although the above appears to use the conditional expression 'if', it is in fact setting the 'http-status' to '302', not testing for it. The same applies to the variable 'http-header'. Once again, even though it uses an 'if', it is in fact setting the variable to 'Location' followed by the URL set from the variable 'link-redirect'. For example, in the case where $(link-redirect) evaluates to "[http://192.168.88.1/login](http://192.168.88.1/login)", then the HTTP response returned to the client will be changed to: ``` HTTP/1.0 302 Hotspot login required Location: http://192.168.88.1/login ``` **http-status syntax**: ``` $(if http-status == XYZ)HTTP_STATUS_MESSAGE$(endif) ``` - *XYZ* - The status code you wish to return. Should be 3 decimal digits, the first one must not be 0. - *HTTP\_STATUS\_MESSAGE* - Any text you wish to return to the client, which will follow the above status code in the HTTP reply. In any HTTP response it will be on the first line and will be as follows: ``` HTTP/1.0 XYZ HTTP_STATUS_MESSAGE ``` **http-header syntax:** ``` $(if http-header == HTTP_HEADER_NAME)HTTP_HEADER_VALUE$(endif) ``` - *HTTP\_HEADER\_NAME* - name of the HTTP header to be sent in the response - *HTTP\_HEADER\_VALUE* - the value of the HTTP header with the name HTTP\_HEADER\_NAME to be sent in the response The HTTP response will appear as: ``` HTTP_HEADER_NAME: HTTP_HEADER_VALUE ``` All variables and conditional expressions within HTTP\_HEADER\_VALUE and HTTP\_STATUS\_MESSAGE are processed as usual. In case multiple headers with the same name are added, only the last one will be used (previous ones will be discarded). It allows the system to override regular HTTP headers (for example, Content-Type and Cache-Control). #### Customizing Error Messages All error messages are stored in the errors.txt file within the respective HotSpot servlet directory. You can change and translate all these messages to your native language. To do so, edit the errors.txt file. You can also use variables in the messages. All instructions are given in that file. #### Multiple Versions of HotSpot Pages Multiple HotSpot page sets for the same HotSpot server are supported. They can be chosen by the user (to select a language) or automatically by JavaScript (to select a PDA/regular version of HTML pages). To utilize this feature, create subdirectories in the HotSpot HTML directory, and place those HTML files, which are different, in that subdirectory. For example, to translate everything in Latvian, the subdirectory "lv" can be created with login.html, logout.html, status.html, alogin.html, radvert.html and errors.txt files, which are translated into Latvian. If the requested HTML page cannot be found in the requested subdirectory, the corresponding HTML file from the main directory will be used. The main login.html file would contain a link to "/lv/login?dst=$(link-orig-esc)", which then displays the Latvian version of the login page: Latviski. And the Latvian version would contain a link to the English version: English Another way of referencing directories is to specify 'target' variable: ``` Latviski English ``` After the preferred directory has been selected (for example, "lv"), all links to local HotSpot pages will contain that path (for example, $(link-status) = "[http://hotspot.mt.lv/lv/status](http://hotspot.mt.lv/lv/status)"). So, if all HotSpot pages reference links using "$(link-xxx)" variables, then no more changes are to be made - each client will stay within the selected directory all the time. #### Misc If you want to use the HTTP-CHAP authentication method, you need to include the **doLogin()** function (which references the **md5.js** which must be already loaded) before the **Submit action** of the login form. Otherwise, CHAP login will fail. The resulting password to be sent to the HotSpot gateway in case of the HTTP-CHAP method is formed by MD5-hashing the concatenation of the following: chap-id, the password of the user, and chap-challenge (in the given order) In case variables are to be used in the link directly, then they must be escaped accordingly. For example, in the login page, **link** will not work as intended, if the username is "123&456=1 2". In this case instead of $(user), its escaped version must be used: $(user-esc): **link**. Now the same username will be converted to "123%26456%3D1+2", which is the valid representation of "123&456=1 2" in the URL. This trick may be used with any variables, not only with $(username). There is a boolean parameter "erase-cookie" to the logout page, which may be either "on" or "true" to delete the user cookie on logout (so that the user would not be automatically logged on when he/she opens a browser next time). #### Examples With basic HTML language knowledge and the examples below, it should be easy to implement the ideas described above: - To provide a predefined value as a username, in login.html change: ``` ``` to this line: ``` ``` (where hsuser is the username you are providing) - To provide a predefined value as a password, change in login.html. ``` ``` to this line: ``` ``` (where hspass is the password you are providing) - To send the client's MAC address to a registration server in the form of: [https://www.example.com/register.html?mac=XX:XX:XX:XX:XX:XX](https://www.example.com/register.html?mac=XX:XX:XX:XX:XX:XX) change the Login button link in login.html to: ``` https://www.example.com/register.html?mac=$(mac) ``` (you should correct the link to point to your server) - To show a banner after user login, in alogin.html after. $(if popup == 'true') add the following line: ``` open('http://www.example.com/your-banner-page.html', 'my-banner-name',''); ``` (you should correct the link to point to the page you want to show) - To choose a different page shown after login, change in login.html: ``` ``` to this line: ``` ``` (you should correct the link to point to your server) - To erase the cookie on logoff, in the page containing a link to the logout (for example, in status.html) change. ``` open('$(link-logout)', 'hotspot_logout', ... ``` to this: ``` open('$(link-logout)?erase-cookie=on', 'hotspot_logout', ... ``` or alternatively add this line: ``` ``` Before this one: ``` ``` ##### External authentication Another example is making HotSpot authenticate on a remote server (which may, for example, perform credit card charging): - Allow direct access to the external server in walled-garden (either HTTP-based or IP-based). - Modify the login page of the HotSpot servlet to redirect to the external authentication server. The external server should modify the RADIUS database as needed. Here is an example of such a login page to put on the HotSpot router (it is redirecting to [https://auth.example.com/login.php](https://auth.example.com/login.php), replace with the actual address of an external authentication server): ``` ...
``` - The external server can log in a HotSpot client by redirecting it back to the original HotSpot servlet login page, specifying the correct username and password. Here is an example of such a page (it is redirecting to [https://hotspot.example.com/login](https://hotspot.example.com/login), replace it with the actual address of a HotSpot router; also, it is displaying [www.mikrotik.com](http://www.mikrotik.com) after successful login, replace it with what is needed): ``` Hotspot login page
``` - Hotspot will ask the RADIUS server whether to allow the login or not. If allowed, the alogin.html page will be displayed (it can be modified to do anything). If not allowed, the flogin.html (or login.html) page will be displayed, which will redirect the client back to the external authentication server. **Note:** as shown in these examples, the HTTPS protocol and the POST method can be used to secure communications. ##### HTTP header detection The Hotspot login pages have access to HTTP headers by using **$(http-header-name);** For example, there exists an ability to check the user agent (or browser), and it will return any other content instead of the regular login page, if so desired. This can be used to disable automatic popups in phones, for example. For example, to output "SUCCESS" for users of a specific Firefox mobile version, instead of the login page, you can add these lines on the top of the **rlogin.html** page in your hotspot directory: ``` $(if user-agent == "Mozilla/5.0 (Android; Mobile; rv:40.0) Gecko/40.0 Firefox/40.0" ) SuccessSuccess $(else) ---- regular content of rlogin.html page ---- $(endif) ``` This will DISABLE the login popup for Android Firefox 40 users. ##### One-click login It is possible to create a modified captive portal for quick one-click login for scenarios where no user or password is required. What you need to do is: - Create a user for this purpose. For example, it is "notsosecretuser" with password "notsosecretpass". - Assign this user to a user profile that allows a specific/unlimited number of simultaneous active users. - Copy the original hotspot directory that is already generated in router's file menu at the root level. - Modify the contents of this copy directory. - Only one file requires modifications for this to work, the "login.html". Original: ``` login password ``` Modified: ``` login password ``` What changed: - - - User and Password "" fields are hidden. - Both User and Password field values contain predefined values. - Changed the "OK" button value(name) to something more fitting. - Now upload this new hotspot folder back to the router, preferably with a different name. - Change settings in the hotspot server profile to use this new html directory. ``` /ip/hotspot/profile/set (profile number or name) html-directory-override=(dir path/name) ``` ### Firewall customizations #### Summary Apart from the obvious dynamic entries in the `/ip/hotspot` submenu itself (like hosts and active users), some additional rules are added in the firewall tables when activating a HotSpot service. #### NAT From the **`/ip/firewall/nat/print` dynamic** command, you can get something like this (comments follow after each of the rules): ``` 0 D chain=dstnat action=jump jump-target=hotspot hotspot=from-client ``` Puts all HotSpot-related tasks for packets from all HotSpot clients into a separate chain. ``` 1 I chain=hotspot action=jump jump-target=pre-hotspot ``` Any actions that should be done before HotSpot rules apply, should be put in the pre-hotspot chain. This chain is under full administrator control and does not contain any rules set by the system, hence the invalid jump rule (as the chain does not have any rules by default). ``` 2 D chain=hotspot action=redirect to-ports=64872 dst-port=53 protocol=udp 3 D chain=hotspot action=redirect to-ports=64872 dst-port=53 protocol=tcp ``` Redirect all DNS requests to the HotSpot service. The 64872 port provides DNS service for all HotSpot users. If you want the HotSpot server to listen on another port, add rules here the same way, changing the dst-port property. ``` 4 D chain=hotspot action=redirect to-ports=64873 hotspot=local-dst dst-port=80 protocol=tcp ``` Redirect all HTTP login requests to the HTTP login servlet. The 64873 is the HotSpot HTTP servlet port. ``` 5 D chain=hotspot action=redirect to-ports=64875 hotspot=local-dst dst-port=443 protocol=tcp ``` Redirect all HTTPS login requests to the HTTPS login servlet. 64875 is the HotSpot HTTPS servlet port. ``` 6 D chain=hotspot action=jump jump-target=hs-unauth hotspot=!auth protocol=tcp ``` All other packets except DNS and login requests from unauthorized clients should pass through the hs-unauth chain. ``` 7 D chain=hotspot action=jump jump-target=hs-auth hotspot=auth protocol=tcp ``` And packets from the authorized clients - through the hs-auth chain. ``` 8 D ;;; www.mikrotik.com chain=hs-unauth action=return dst-address=66.228.113.26 dst-port=80 protocol=tcp ``` First in the **hs-unauth** chain is put everything that affects TCP protocol in the `/ip/hotspot/walled-garden/ip` submenu (i.e., everything where either protocol is not set, or set to TCP). Here we are excluding [www.mikrotik.com](http://www.mikrotik.com) from being redirected to the login page. ``` 9 D chain=hs-unauth action=redirect to-ports=64874 dst-port=80 protocol=tcp ``` All other HTTP requests are redirected to the Walled Garden proxy server which listens on port 64874. If there is an "allow" entry in the `/ip/hotspot/walled-garden` menu for an HTTP request, it is being forwarded to the destination. Otherwise, the request will be automatically redirected to the HotSpot login servlet (port 64873). ``` 10 D chain=hs-unauth action=redirect to-ports=64874 dst-port=3128 protocol=tcp 11 D chain=hs-unauth action=redirect to-ports=64874 dst-port=8080 protocol=tcp ``` HotSpot by default assumes that only these ports may be used for HTTP proxy requests. These two entries are used to "catch" client requests to unknown proxies (you can add more rules here for other ports), i.e., to make it possible for the clients with unknown proxy settings to work with the HotSpot system. This feature is called "Universal Proxy". If it is detected that a client is using some proxy server, the system will automatically mark those packets with the HTTP hotspot mark to work around the unknown proxy problem, as we will see later on. Note that the port used (64874) is the same as for HTTP requests in rule #9 (so both HTTP and HTTP proxy requests are processed by the same code). ``` 12 D chain=hs-unauth action=redirect to-ports=64875 dst-port=443 protocol=tcp ``` HTTPS proxy is listening on port 64875. ``` 13 I chain=hs-unauth action=jump jump-target=hs-smtp dst-port=25 protocol=tcp ``` Redirect for the SMTP protocol may also be defined in the HotSpot configuration. In case it is, a redirect rule will be put in the hs-smtp chain. This is done so that users with an unknown SMTP configuration would be able to send their mail through the service provider's (your) SMTP server instead of going to the [possibly unavailable outside their network of origin] SMTP server users have configured on their computers. The chain is empty by default, hence the invalid jump rule. ``` 14 D chain=hs-auth action=redirect to-ports=64874 hotspot=http protocol=tcp ``` Providing HTTP proxy service for authorized users. Authenticated user requests may need to be subject to transparent proxying (the "Universal Proxy" technique and advertisement feature). This HTTP mark is put automatically on the HTTP proxy requests to the servers detected by the HotSpot HTTP proxy (the one that is listening on port 64874) as HTTP proxy requests for unknown proxy servers. This is done so that users that have some proxy settings would use the HotSpot gateway instead of the [possibly unavailable outside their network of origin] proxy server users have configured on their computers. This mark is also applied when an advertisement is due to be shown to the user, as well as on any HTTP requests from the users whose profile is configured to transparently proxy their requests. ``` 15 I chain=hs-auth action=jump jump-target=hs-smtp dst-port=25 protocol=tcp ``` Providing an SMTP proxy for authorized users (the same as in rule #13). #### Packet Filtering From the **`/ip/firewall/filter/print` dynamic** command, you can get something like this (comments follow after each of the rules): ``` 0 D chain=forward action=jump jump-target=hs-unauth hotspot=from-client,!auth ``` Any packet that traverses the router from an unauthorized client will be sent to the **hs-unauth** chain. The hs-unauth implements the IP-based Walled Garden filter. ``` 1 D chain=forward action=jump jump-target=hs-unauth-to hotspot=to-client,!auth ``` Everything that comes to clients through the router gets redirected to another chain, called **hs-unauth-to**. This chain should reject unauthorized requests to the clients. ``` 2 D chain=input action=jump jump-target=hs-input hotspot=from-client ``` Everything that comes from clients to the router itself gets to yet another chain, called **hs-input**. ``` 3 I chain=hs-input action=jump jump-target=pre-hs-input ``` Before proceeding with [predefined] dynamic rules, the packet gets to the administratively controlled **pre-hs-input** chain, which is empty by default, hence the invalid state of the jump rule. ``` 4 D chain=hs-input action=accept dst-port=64872 protocol=udp 5 D chain=hs-input action=accept dst-port=64872-64875 protocol=tcp ``` Allow client access to the local authentication and proxy services (as described earlier). ``` 6 D chain=hs-input action=jump jump-target=hs-unauth hotspot=!auth ``` All other traffic from unauthorized clients to the router itself will be treated the same way as the traffic traversing the router. ``` 7 D chain=hs-unauth action=return protocol=icmp 8 D ;;; www.mikrotik.com chain=hs-unauth action=return dst-address=66.228.113.26 dst-port=80 protocol=tcp ``` Unlike the NAT table where only TCP-protocol related Walled Garden entries were added, in the packet filter, the **hs-unauth** chain is added to everything you have set in the `/ip/hotspot/walled-garden/ip` menu. That is why although you have seen only one entry in the NAT table, there are two rules here. ``` 9 D chain=hs-unauth action=reject reject-with=tcp-reset protocol=tcp 10 D chain=hs-unauth action=reject reject-with=icmp-net-prohibited ``` Everything else that has not been white-listed by the Walled Garden will be rejected. Note the usage of TCP Reset for rejecting TCP connections. ``` 11 D chain=hs-unauth-to action=return protocol=icmp 12 D ;;; www.mikrotik.com chain=hs-unauth-to action=return src-address=66.228.113.26 src-port=80 protocol=tcp ``` The same action as in rules #7 and #8 is performed for the packets destined to the clients (chain **hs-unauth-to**) as well. ``` 13 D chain=hs-unauth-to action=reject reject-with=icmp-host-prohibited ``` Reject all packets to the clients with an ICMP reject message. --- ## HotSpot - Captive portal The MikroTik HotSpot Gateway provides authentication for clients before access to public networks. :::warning Hotspot (captive portal) - uses web-proxy and it is capable of using only the default routing table, at the moment, making the PCC(per connection-classifier) not a valid method, due to the multiple routing tables used. ::: :::warning HotSpot functionality could be blocked by the device-mode. Prior to configuring HotSpot, make sure that it is enabled in `/system/device-mode` ([more info](../../system-information-and-utilities/device-mode.md). ::: ### HotSpot Properties | Property | Description | | :--- | :--- | | **name** | Descriptive name for the HotSpot server instance. | | **interface** | The specific local interface (physical or virtual) where the HotSpot service will listen for client requests. | | **address-pool** | The IP address pool from which HotSpot clients will receive their IP addresses via DHCP. | | **profile** | Reference to the HotSpot Server Profile containing common settings like login methods and HTML directory. | | **idle-timeout** | The period of inactivity after which a client is automatically logged out if no traffic is detected. | | **keepalive-timeout** | The time interval used to check if the client is still reachable; if the client does not respond, the session is terminated. | | **login-timeout** | The maximum duration allowed for a client to complete the authentication process after the login page is displayed. | | **addresses-per-mac** | Limits the number of IP addresses that can be associated with a single MAC address. | | **proxy-status** | Indicates the current operational state of the internal web-proxy used by the HotSpot system. | ### HotSpot Gateway features - Different authentication methods of clients, using a local client database on the router, or a remote RADIUS server. - User accounting in a local database on the router, or on a remote RADIUS server. - A walled-garden system, access to some web pages without authorization. - Login page modification, where you can put information about the company. - Automatic and transparent change of any IP address of a client to a valid address. - HotSpot can inform DHCP clients that they are behind a captive portal (RFC7710). A hotspot can work reliably only when IPv4 is used. Hotspot relies on Firewall NAT rules which currently are not supported for IPv6. ## Example ```ros [admin@MikroTik] /ip/hotspot> setup Select interface to run HotSpot on hotspot interface: ether3 Set HotSpot address for interface local address of network: 10.5.50.1/24 masquerade network: yes Set pool for HotSpot addresses address pool of network: 10.5.50.2-10.5.50.254 Select hotspot SSL certificate select certificate: none Select SMTP server ip address of smtp server: 0.0.0.0 Setup DNS configuration dns servers: 10.1.101.1 DNS name of local hotspot server dns name: myhotspot Create local hotspot user name of local hotspot user: admin password for the user: [admin@MikroTik] /ip/hotspot> ``` ## Verify HotSpot configuration ```ros [admin@MikroTik] /ip/hotspot> print Flags: X - disabled, I - invalid, S - HTTPS # NAME INTERFACE ADDRESS-POOL PROFILE IDLE-TIMEOUT 0 hotspot1 ether3 hs-pool-3 hsprof1 5m [admin@MikroTik] /ip/hotspot> [admin@MikroTik] /ip/pool> print # NAME RANGES 0 hs-pool-3 10.5.50.2-10.5.50.254 [admin@MikroTik] /ip/pool> /ip/dhcp-server [admin@MikroTik] /ip/dhcp-server> print Flags: X - disabled, I - invalid # NAME INTERFACE RELAY ADDRESS-POOL LEASE-TIME ADD-ARP 0 dhcp1 ether3 hs-pool-3 1h [admin@MikroTik] /ip/dhcp-server> /ip/firewall/nat [admin@MikroTik] /ip/firewall/nat> print Flags: X - disabled, I - invalid, D - dynamic 0 X ;;; place hotspot rules here chain=unused-hs-chain action=passthrough 1 ;;; masquerade hotspot network chain=srcnat action=masquerade src-address=10.5.50.0/24 [admin@MikroTik] /ip/firewall/nat> ``` ### **Parameters asked during the setup process** | Parameter | Description | | :-- | :-- | | **hotspot interface** (*string*; Default: **allow**) | Interface name on which to run HotSpot. To run HotSpot on a bridge interface, make sure public interfaces are not included in the bridge ports. | | **local address of network** (*IP*; Default: **10.5.50.1/24**) | HotSpot gateway address | | **masquerade network** (*yes \| no*; Default: **yes**) | Whether to masquerade HotSpot network, when **yes**, a rule is added to *`/ip/firewall/nat`* with *action=masquerade* | | **address pool of network** (*string*; Default: **yes**) | Address pool for HotSpot network, which is used to change user IP address to a valid address. Useful if providing network access to mobile clients that are not willing to change their networking settings. | | **select certificate** (*none \| import-other-certificate*; Default: ) | Choose an SSL certificate, when the HTTPS authorization method is required. | | **ip address of smtp server** (*IP*; Default: **0.0.0.0**) | The IP address of the SMTP server, where to redirect HotSpot's network SMTP requests (TCP port 25) | | **dns servers** (*IP*; Default: **0.0.0.0**) | DNS server addresses used for HotSpot clients, configuration is taken from *`/ip/dns`* menu of the HotSpot gateway | | **dns name** (*string*; Default: **""**) | The domain name of the HotSpot server, a fully qualified domain name is required, for example, [www.example.com](http://www.example.com) | | **name of local hotspot user** (*string*; Default: **"admin"**) | username of one automatically created HotSpot user, added to *`/ip/hotspot/user`* | | **password for the user** (*string*; Default: ) | Password for automatically created HotSpot user | ## HotSpot **Sub-menu:** `/ip/hotspot` The menu is designed to manage the HotSpot servers of the router. It is possible to run HotSpot on Ethernet, wireless, VLAN, and bridge interfaces. One HotSpot server is allowed per interface. When HotSpot is configured on the bridge interface, set the HotSpot interface as the bridge interface, not as a bridge port, do not add public interfaces to bridge ports. You can add HotSpot servers manually to the *`/ip/hotspot`* menu, but it is advised to run *`/ip/hotspot/setup`*, which adds all necessary settings. | Parameters | Description | | :-- | :-- | | **name** (text) | HotSpot server's name or identifier | | **address-pool** (name/none; default: *none*) | address space used to change any HotSpot client IP address to a valid address. Useful for providing public network access to mobile clients that are not willing to change their networking settings | | **idle-timeout** (time/none; default: *5m*) | period of inactivity for unauthorized clients. When there is no traffic from this client (literally, the client computer should be switched off), once the timeout is reached, a user is dropped from the HotSpot host list, its used address becomes available | | **keepalive-timeout** (time/none; default: *none*) | Value of how long the host can stay out of reach to be removed from the HotSpot | | **login-timeout** (time/none; default: *none*) | Period of time after which if a host hasn't been authorized with the system the host entry gets deleted from the host table. Loop repeats until the host logs in to the system. Enable if there are situations where a host cannot log in after being too long in the host table unauthorized. | | **interface** (name of an interface) | Interface to run HotSpot on | | **addresses-per-mac** (integer**/**unlimited; default: 2) | Number of IP addresses allowed to be bound with the MAC address, when multiple HotSpot clients are connected with one MAC-address | | **profile** (name; default: ***default*)** | HotSpot server default HotSpot profile, which is located in *`/ip/hotspot/profile`* | ## Read-only | Parameters | Description | | :-- | :-- | | keepalive-timeout (read-only; time) | The exact value of the keepalive-timeout that is applied to the user. The value shows how long the host can stay out of reach to be removed from the HotSpot | ## HotSpot Profile This submenu contains a list of Hotspot server profiles. There may be various different HotSpot systems, defined as Server Profiles, on the same gateway machine. One or more interfaces can be grouped into one server profile. There are very few settings for the servers on particular interfaces - most of the configuration is set in the server profiles. For example, it is possible to make a completely different set of servlet pages for each server profile, and define different RADIUS servers for authentication. | Property | Description | | :-- | :-- | | **dns-name** (*string*; Default: **""**) | DNS name of the HotSpot server. This is the DNS name used as the name of the HotSpot server (i.e., it appears as the location of the login page). This name will automatically be added as a static DNS entry in the DNS cache. | | **hotspot-address** (*IP*; Default: **0.0.0.0**) | IP address of HotSpot service. | | **html-directory** (*string*; Default: **hotspot**) | Directory name in which HotSpot HTML pages are stored (by default *hotspot* directory). It is possible to specify a different directory with modified HTML pages. To change the HotSpot login page, get HotSpot files from your router, change and upload them back to the same location. Full path must be typed in the html-directory field, including "/flash/(hotspot\_dir)" | | **html-directory-override** (*string*; Default: **none**) | Alternative path for hotspot html files. It should be used only when customized hotspot html files are stored on external storage. | | **http-cookie-lifetime** (*time*; Default: **3d**) | HTTP cookie validity time, the option is related to *cookie* HotSpot login method | | **http-proxy** (*IP:Port*; Default: **0.0.0.0:0**) | Address and port of the proxy server for HotSpot service, when the default value is used all requests are resolved by the local `/ip/proxy` | | **https-redirect** (*yes \| no*; Default: **yes**) | Whether to redirect the unauthenticated user to the hotspot login page, if the user is visiting an https:// url. Since the certificate domain name will mismatch, often this leads to errors, so you can set this parameter to "no" and all https requests will simply be rejected and user will have to visit an http page. | | **login-by** (*cookie\|http-chap\|http-pap\|https\|mac\|trial\|mac-cookie*; Default: **http-chap, cookie**) | The HotSpot authentication method usedmac-cookie - enables login by mac cookie methodcookie - may only be used with another HTTP authentication method. HTTP cookie is generated, when the user authenticates in HotSpot for the first time. User is not asked for the login/password and is authenticated automatically, until cookie-lifetime is activehttp-chap - login/password is required for the user to authenticate in HotSpot. CHAP challenge-response method with MD5 hashing algorithm is used for protecting passwords.http-pap - login/password is required for user to authenticate in HotSpot. Username and password are sent over network in plain text.https - login/password is required for user to authenticate in HotSpot. Client login/password exchange between client and server is encrypted with SSL tunnel. mac - client is authenticated without asking for a login form. Client MAC-address is added to `/ip/hotspot/user` database, client is authenticated as soon as connected to the HotSpottrial - client is allowed to use the internet without HotSpot login for the specified amount of time | | **mac-auth-password** (*string*; Default: ) *[sensitive](../../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | Used together with MAC authentication, the field is used to specify password for the users to be authenticated by their MAC addresses. The following option is required, when a specific RADIUS server rejects authentication for the clients with a blank password | | **name** (*string*; Default: ) | Descriptive name of the profile | | **nas-port-type** (*string*; Default: **wireless-802.11**) | NAS-Port-Type value to be sent to RADIUS server, NAS-Port-Type values are described in the RADIUS RFC 2865. This optional value attribute indicates the type of the physical port of the HotSpot server. | | **radius-accounting** (*yes \| no*; Default: **yes**) | Send RADIUS server accounting information for each user, when yes is used | | **radius-default-domain** (*string*; Default: ) | Default domain to use for RADIUS requests. Allows using separate RADIUS server per *`/ip/hotspot/profile`*. If used, same domain name should be specified under /radius domain value. | | **radius-interim-update** (*time \| received*; Default: **received**) | How often to send accounting updates. When *received* is set, interim-time from the RADIUS server is used. **0s** is the same as *received*. | | **radius-location-name** (*string*; Default: ) | RADIUS-Location-Id to be sent to RADIUS server. Used to identify location of the HotSpot server during the communication with RADIUS server. Value is optional and used together with RADIUS server. | | **radius-mac-format** (*"XX XX XX XX XX XX"\|XX:XX:XX:XX:XX:XX\|XXXXXX-XXXXXX\|XXXXXXXXXXXX\|XX-XX-XX-XX-XX-XX\|XXXX:XXXX:XXXX\|XXXXXX:XXXXXX*; Default: **XX:XX:XX:XX:XX:XX**) | Option to set format of user mac-address, that is sent to RADIUS server during AAA session. | | **rate-limit** (*string*; Default: **""**) | Rate limitation in the form of **rx-rate[/tx-rate] [rx-burst-rate[/tx-burst-rate] [rx-burst-threshold[/tx-burst-threshold] [rx-burst-time[/tx-burst-time]]]] [priority] [rx-rate-min[/tx-rate-min]]** from the point of view of the router (so "rx" is client upload, and "tx" is client download). All rates should be numbers with optional 'k' (1,000s) or 'M' (1,000,000s). If tx-rate is not specified, rx-rate is as tx-rate too. Same goes for tx-burst-rate and tx-burst-threshold and tx-burst-time. If both rx-burst-threshold and tx-burst-threshold are not specified (but burst-rate is specified), rx-rate and tx-rate are used as burst thresholds. If both rx-burst-time and tx-burst-time are not specified, 1s is used as the default. rx-rate-min and tx-rate min are the values of limit-at properties | | **smtp-server** (*IP*; Default: **0.0.0.0**) | SMTP server address to be used to redirect HotSpot users' SMTP requests. | | **split-user-domain** (*yes \| no*; Default: **no**) | Split username from domain name when the username is given in "user@domain" or in "domain\user" format from RADIUS server | | **ssl-certificate** (*string \| none*; Default: **none**) | Name of the SSL certificate on the router to use only for HTTPS authentication. | | **trial-uptime** (*time/time*; Default: **30m/1d**) | Used only with *trial* authentication method. First time value specifies how long trial user identified by MAC address can use access to public networks without HotSpot authentication. Second time value specifies the amount of time, that has to pass until the user is allowed to use trial again. | | **trial-user-profile** (*string*; Default: **default**) | Specifies **hotspot user profile** for trial users. | | **use-radius** (*yes \| no*; Default: **no**) | Use RADIUS to authenticate HotSpot users. | ## HotSpot User Profiles **Sub-menu:** `/ip/hotspot/user/profile` User profile menu is used for common HotSpot client settings. Profiles are like User groups with the same set of settings, rate-limit, filter chain name, etc. | Property | Description | | :-- | :-- | | **add-mac-cookie** (*yes\|no*; Default: **yes**) | Allows adding a mac cookie for users. | | **address-list** (*string*; Default: ) | Name of the address list in which the user's IP address will be added. Useful to mark traffic per user group for queue tree configurations. | | **address-pool** (*string \|none*; Default: **none**) | IP pool name from which the user will get an IP. When the user has improper network settings configuration on the computer, the HotSpot server makes a translation and assigns the correct IP address from the pool instead of the incorrect one | | **advertise** (*yes \| no*; Default: **no**) | Enable forced advertisement popups. After a certain interval, a specific web-page is being displayed for HotSpot users. The advertisement page might be blocked by browser popup blockers. | | **advertise-interval** (*time[,time[,..]]*; Default: **30m,10m**) | Set of intervals between advertisement popups. After the list is done, the last value is used for all further advertisements, 10 minutes | | **advertise-timeout** (*time \| immediately \| never*; Default: **1m**) | How long the advertisement is shown, before blocking network access for the HotSpot client. Connection to the Internet is not allowed when the advertisement is not shown. | | **advertise-url** (*string[,string[,..]]*; Default: ) | List of URLs that are shown for advertisement popups. After the last URL is used, the list starts from the beginning. | | **idle-timeout** (*time \| none*; Default: **none**) | Maximal period of inactivity for authorized HotSpot clients. The timer counts when there is no traffic coming from that client and going through the router, for example, the computer is switched off. The user is logged out, dropped from the host list, and the address used by the user is freed when the timeout is reached. | | **incoming-filter** (*string*; Default: ) | Name of the firewall chain applied to incoming packets from the users of this profile. A jump rule is required from the built-in chain (input, forward, output) to chain=hotspot | | **incoming-packet-mark** (*string*; Default: ) | Packet mark put on incoming packets from every user of this profile | | **keepalive-timeout** (*time \| none*; Default: ) | Keepalive timeout for authorized HotSpot clients. Used to detect that the computer of the client is alive and reachable. The user is logged out when the timeout value is reached | | **mac-cookie-timeout** (*time*; Default: **3d**) | Selects the mac-cookie timeout from the last login or logout. | | **name** (*string*; Default: ) | Descriptive name of the profile | | **on-login** (*string*; Default: **""**) | Script name to be executed when the user logs in to the HotSpot from the particular profile. It is possible to get the username from internal **user** and **interface** variables. For example, *:log info "User $user logged in!"*. If the hotspot is set on a bridge interface, then the **interface** variable will show the bridge as the actual interface unless **use-ip-firewall** is set in the bridge settings. List of available variables: $user$username (alternative var name for $user)$address$"mac-address"$interface | | **on-logout** (*string*; Default: **""**) | Script name to be executed when the user logs out from the HotSpot. It is possible to get the username from internal **user** and **interface** variables. For example, *:log info "User $user logged in!"* . If the hotspot is set on a bridge interface, then the **interface** variable will show the bridge as the actual interface unless **use-ip-firewall** is set in the bridge settings. List of available variables: $user$username (alternative var name for $user)$address$"mac-address"$interface$cause Starting with v6.34rc11 some additional variables are available: $uptime-secs - final session time in seconds$bytes-in - bytes uploaded$bytes-out - bytes downloaded$bytes-total - bytes up + bytes down$packets-in - packets uploaded$packets-out - packets downloaded$packets-total - packets up + packets down | | **open-status-page** (*always \| http-login*; Default: **always**) | Option to show status page for a user authenticated with the mac login method. For example, to show advertisement on the status page (alogin.html)http-login - open the status page only for HTTP login (includes cookie and HTTPS)always - open the HTTP status page in case of mac login as well | | **outgoing-filter** (*string*; Default: ) | Name of the firewall chain applied to outgoing packets from the users of this profile. A jump rule is required from the built-in chain (input, forward, output) to chain=hotspot | | **outgoing-packet-mark** (*string*; Default: ) | Packet mark put on outgoing packets from every user of this profile | | **rate-limit** (*string*; Default: **""**) | A simple dynamic queue is created for the user once the user logs in to the HotSpot. Rate-limitation is configured in the following form **[rx-rate[/tx-rate] [rx-burst-rate[/tx-burst-rate] [rx-burst-threshold[/tx-burst-threshold] [rx-burst-time[/tx-burst-time] [priority] [rx-rate-min[/tx-rate-min]]]]**. For example, to set 1M download, 512k upload for the client, rate-limit=512k/1M | | **session-timeout** (*time*; Default: **0s**) | Allowed session time for the client. After this time, the user is logged out unconditionally | | **shared-users** (*integer*; Default: **1**) | Allowed number of simultaneously logged-in users with the same HotSpot username | | **status-autorefresh** (*time \| none*; Default: **none**) | HotSpot status page autorefresh interval | | **transparent-proxy** (*yes \|*; Default: **yes**) | Use a transparent HTTP proxy for the authorized users of this profile | ## HotSpot Users This is the menu, where client's user/password information is actually added. Additional configuration options for HotSpot users are configured here as well. | Property | Description | | :-- | :-- | | **address** (*IP*; Default: **0.0.0.0**) | IP address, when specified, the client will get the address from the HotSpot one-to-one NAT translations. Address does not restrict HotSpot login only from this address | | **comment** (*string*; Default: ) | descriptive information for the HotSpot user. It might be used for scripts to change parameters for specific clients | | **email** (*string*; Default: ) | HotSpot client's e-mail, informational value for the HotSpot user | | **limit-bytes-in** (*integer*; Default: **0**) | Maximal amount of bytes that can be received from the user. The user is disconnected from HotSpot after the limit is reached. | | **limit-bytes-out** (*integer*; Default: **0**) | Maximal amount of bytes that can be transmitted from the user. The user is disconnected from HotSpot after the limit is reached. | | **limit-bytes-total** (*integer*; Default: **0**) | (limit-bytes-in+limit-bytes-out). The user is disconnected from HotSpot after the limit is reached. | | **limit-uptime** (*time*; Default: **0**) | Uptime limit for the HotSpot client. The user is disconnected from HotSpot as soon as the uptime is reached. | | **mac-address** (*MAC*; Default: **00:00:00:00:00:00**) | The client is allowed to log in only from the specified MAC-address. If the value is *00:00:00:00:00:00*, any mac address is allowed. | | **name** (*string*; Default: ) | HotSpot login page username. When MAC-address authentication is used, the name is configured as the client's MAC-address | | **password** (*string*; Default: ) *[sensitive](../../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | User password | | **profile** (*string*; Default: **default**) | User profile configured in *`/ip/hotspot/user/profile`* | | **routes** (*string*; Default: ) | Routes added to HotSpot gateway when the client is connected. The route format is **dst-address gateway metric** (for example, *192.168.1.0/24 192.168.0.1 1*) | | **server** (*string \| all*; Default: **all**) | HotSpot server's name to which the user is allowed to log in | | **otp-secret** (*string*; Default: ) *[sensitive](../../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | A one-time password token that is used for HotSpot user authorization. It could be used as a separate "password" for HotSpot user authentication. | ## Read-only properties | Property | Description | | :-- | :-- | | **bytes-in** (*integer*) | Total amount of data bytes received from the client. | | **bytes-out** (*integer*) | Total amount of data bytes sent to the client. | | **packets-in** (*integer*) | Total number of packets received from the client. | | **packets-out** (*integer*) | Total number of packets sent to the client. | | **uptime** (*time*) | Current session duration since the client was authenticated. | ## HotSpot Active **Sub-menu:** `/ip/hotspot/active` HotSpot active menu shows all clients authenticated in HotSpot, the menu is informational (read-only). It is not possible to change anything here, except the user can be logged out with the remove command. | Parameters | Description | | :-- | :-- | | **server** (read-only; name) | HotSpot server name client is logged in | | **user** (read-only; name) | name of the HotSpot user | | **domain** (read-only; text) | the domain of the user (if split from the username), the parameter is used only with RADIUS authentication | | **address** (read-only; IP address) | The IP address of the HotSpot user | | **mac-address** (read-only; MAC-address) | MAC-address of the HotSpot user | | **login-by** (read-only; multiple-choice: cookie **/** http-chap **/** http-pap **/** https **/** mac **/** mac-cookie **/** trial) | the authentication method used by the HotSpot client | | **uptime** (read-only; time) | current session time of the user, it is showing how long the user has been logged in | | **idle-time** (read-only; time) | the amount of time the user has been idle | | **session-time-left** (read-only; time) | the exact value of session-time, that is applied for the user. Value shows how long user is allowed to be online to be logged off automatically by **uptime** reached | | **idle-timeout** (read-only; time) | the exact value of the user's idle-timeout | | **keepalive-timeout** (read-only; time) | the exact value of the keepalive-timeout, that is applied for the user. Value shows how long the host can stay out of reach to be removed from the HotSpot | | **limit-bytes-in** (read-only; integer) | value shows how many bytes received from the client, the option is active when the appropriate parameter is configured for HotSpot user | | **limit-bytes-out** (read-only; integer) | value shows how many bytes sent to the client, the option is active when the appropriate parameter is configured for HotSpot user | | **limit-bytes-total** (read-only; integer) | value shows how many bytes total were sent/received from the client, the option is active when the appropriate parameter is configured for HotSpot user | ## HotSpot Host **Sub-menu:** `/ip/hotspot/host` The host table lists all computers connected to the HotSpot server. The host table is informational and it is not possible to change any value there: | Parameters | Description | | :-- | :-- | | **mac-address** (read-only; MAC-address) | HotSpot user MAC-address | | **address** (read-only; IP address) | HotSpot client's original IP address | | **to-address** (read-only; IP address) | The new client address assigned by HotSpot might be the same as the original **address** | | **server** (read-only; name) | HotSpot server name the client is connected to | | **bridge-port** (read-only; name) | *`/interface/bridge/port`* the client is connected to, value is unknown when HotSpot is not configured on the bridge | | **uptime** (read-only; time) | value shows how long the user is online (connected to the HotSpot) | | **idle-time** (read-only; time) | time the user has been idle | | **idle-timeout** (read-only; time) | value of the client idle-timeout (unauthorized client) | | **keepalive-timeout** (read-only; time) | keepalive-timeout value of the unauthorized client | | **bytes-in** (read-only; integer) | amount of bytes received from an unauthorized client | | **packet-in** (read-only; integer) | amount of packets received from an unauthorized client | | **bytes-out** (read-only; integer) | amount of bytes sent to an unauthorized client | | **packet-out** (read-only; integer) | amount of packets sent to an unauthorized client | ## HotSpot walled-garden A Walled garden is a system which allows unauthorized use of some resources, but requires authorization to access other resources. This is useful, for example, to give access to some general information about the HotSpot service provider or billing options. The menu only manages Walled Garden for HTTP and HTTPs protocols. Other protocols can also be included in Walled Garden, but that is configured elsewhere (in `/ip/hotspot/walled-garden/ip`). | Property | Description | | :-- | :-- | | **action** (*allow \| deny*; Default: **allow**) | Action to perform, when packet matches the ruleallow - allow access to the web-page without authorizationdeny - authorization is required to access the web-page | | **server** (*string*; Default: ) | Name of the HotSpot server the rule is applied to. | | **src-address** (*IP*; Default: ) | Source address of the user, usually the IP address of the HotSpot client | | **method** (*string*; Default: ) | HTTP method of the request | | **dst-host** (*string*; Default: ) | Domain name of the destination web-server | | **dst-port** (*integer*; Default: ) | TCP port number the client sends request to | | **path** (*string*; Default: ) | The path of the request. Path comes after '''http://dst\_host' | # Read-only properties | Property | Description | | :-- | :-- | | **dst-address** (*IP*) | | | **hits** (*integer*) | | Wildcard properties (dst-host and path) match a complete string (i.e., they will not match "[example.com](http://example.com)" if they are set to "example"). Available wildcards are '\*' (match any number of any characters) and '?' (match any one character). Regular expressions are also accepted here, but if the property should be treated as a regular expression, it should start with a colon (':'). To show that no symbols are allowed before the given pattern, we use the ^ symbol at the beginning of the pattern. To specify that no symbols are allowed after the given pattern, we use the $ symbol at the end of the pattern. ### Example To only permit bypassed access in the walled garden to "[www.example.com/test](http://www.example.com/test)" but not to "[www.example.com/test/test.php](http://www.example.com/test/test.php)" : ``` /ip/hotspot/walled-garden add dst-host=:^www.example.com path=":/test\$" ``` ## HotSpot walled-garden ip To bypass HotSpot authentication for other protocols and different src/dst addresses (or address-lists). Used for different services (Winbox, SSH, Telnet, SIP, etc.) | Property | Description | | :-- | :-- | | **action** (*accept \|drop\|reject*; Default: **allow**) | Action to perform, when the packet matches the ruleallow - allow access to the opened service without authorizationdrop - the authorization is required to access the servicereject - the authorization is required to access the service, when the service is accessed, an ICMP reject message host-unreachable will be generated | | **server** (*string*; Default: ) | Name of the HotSpot server, rule is applied to. | | **src-address** (*IP*; Default: ) | Source address of the user, usually the IP address of the HotSpot client | | **dst-address** (*IP*; Default: ) | Destination IP address, the IP address of the WEB-server. Ignored if **dst-host** is already specified. | | **src-address-list** (*string*; Default: ) | Source address list name | | **dst-address-list** (*string*; Default: ) | Destination address list. Ignored if **dst-host** is already specified. | | **dst-host** (*string*; Default: ) | Domain name of the destination web-server. When this parameter is specified, a dynamic entry is added to Walled Garden | | **dst-port** (*integer*; Default: ) | TCP port number, client sends request to | | **protocol** (*integer \| string*; Default: ) | IP protocol | ## IP Binding **Sub-menu:** `/ip/hotspot/ip-binding` IP-Binding HotSpot menu allows the setup of static One-to-One NAT translations, allows bypassing specific HotSpot clients without any authentication, and also allows blocking specific hosts and subnets from the HotSpot network | Property | Description | | :-- | :-- | | **address** (*IP Range*; Default: **""**) | The original IP address of the client | | **mac-address** (*MAC*; Default: **""**) | MAC address of the client | | **server** (*string \| all*; Default: **"all"**) | Name of the HotSpot server.all - will be applied to all hotspot servers | | **to-address** (*IP*; Default: **""**) | New IP address of the client, translation occurs on the router (client does not know anything about the translation) | | **type** (*blocked \| bypassed \| regular*; Default: **""**) | Type of the IP-binding actionregular - performs One-to-One NAT according to the rule, translates the address to to-addressbypassed - performs the translation, but excludes the client from login to the HotSpotblocked - translation is not performed and packets from a host are dropped | ## Cookies The menu contains all cookies sent to the HotSpot clients, which are authorized by the cookie method. All the entries are read-only. **Sub-menu:** `/ip/hotspot/cookie` | Property | Description | | :-- | :-- | | **domain** (*string*) | The domain name (if split from the username) | | **expires-in** (*time*) | How long the cookie is valid | | **mac-address** (*MAC*) | Client's MAC-address | | **user** (*string*) | HotSpot username | ## MAC Cookie MAC cookie is a hotspot feature, designed to improve accessibility for smartphones, laptops and other mobile devices. When the MAC cookie feature is enabled (**login-by**=mac-cookie, **add-mac-cookie**=yes set in user profile), the following actions are taken: - **First successful login**. Mac cookie keeps a record of username and password for the MAC address if there is only one host with such a MAC. Cookie timeout is set to a value equal to mac-cookie-timeout. - **New host appears**. Hotspot checks if there is a mac cookie record for the MAC address and logs in the host using the recorded username and password. If there is more than one host with the same MAC address, the user will not be logged in and the MAC cookie record for this address will be deleted. When **a user logs out** mac cookie is removed in the following cases: - user-request - User clicked on the logout button. - admin-reset - Disconnected from the radius server or the user is removed from the hotspot active menu. - nas-request - Traffic limit reached. - session-timeout. To debug problems with mac-cookies you will need to enable hotspot debug logs and look for reasons why mac-cookie login didn't work for a certain host. ### Reasons when mac cookie is removed by server - `/ip/hotspot/cookie/remove [number]`. - Radius server sends Disconnect-Request. - End-User has logged out himself via hotspot status page. - End user has reached his data cap ("traffic limit reached"). - Session-Timeout. - If mac-cookie login fails. - If the server detects that in the host table there is more than one entry with the same mac-address. ### Properties of the HotSpot API JSON (RFC 7710) Based on the `api.json` template provided in the documentation, here are the descriptions for each property used to communicate captive portal status to client devices: - **captive**: A boolean value (`true` or `false`) that informs the client device whether it is currently restricted by the captive portal. If the user is already authenticated, it returns `false`. - **user-portal-url**: The specific URL where the user can access the login page or manage their current session. In MikroTik RouterOS, this is dynamically populated by the `$(link-login-only)` variable. - **seconds-remaining**: (Optional) An integer representing the number of seconds left before the current session expires. This is only included if a session timeout is configured. - **bytes-remaining**: (Optional) An integer representing the remaining data quota in bytes available to the user. This is only included if data limits are applied to the HotSpot user. - **can-extend-session**: A boolean value indicating whether the user has the ability to extend their current session or purchase/request more time/data via the portal. ## Load balancing with mangle on Hotspot server In a multi-uplink Hotspot setup (for example, [PCC](../../high-availability-solutions/load-balancing/per-connection-classifier.md), default routing often might fail to work as expected because the router prioritises mangle rules over the local destination check. To fix this, ensure traffic destined for the Hotspot server is routed via the **local** table before the **mangle** chain is evaluated. You can achieve this by: 1. Adjusting the "`/routing/settings"` ([Routing table lookup](../../user-guides/routing-and-networking-protocols/routing-decision.md#routing-table-lookup). 2. Or, adding specific "`/routing/rule"` entries to force the Hotspot server's traffic to use the local table first (including HTTP 80 traffic which is used to detect the Hotspot server). --- ## AAA and User Management import DocCardList from '@theme/DocCardList'; This section covers RouterOS authentication, authorization, accounting, and user-management features, including local users, certificates, RADIUS, 802.1X, PPP AAA, User Manager, and HotSpot captive portal access. Use these pages to configure identity, access control, and centralized accounting services. --- ## PPP AAA ## Summary **Sub-menu:** `/ppp` The MikroTik RouterOS provides scalable Authentication, Authorization, and Accounting (AAA) functionality. Local authentication is performed using the User Database and the Profile Database. The actual configuration for the given user is composed using the respective user record from the User Database, the associated item from the Profile Database, and the item in the Profile database which is set as default for a given service the user is authenticating to. Default profile settings from the Profile database have the lowest priority while the user access record settings from the User Database have the highest priority with the only exception being that particular IP addresses take precedence over IP pools in the local-address and remote-address settings, which are described later on. Support for RADIUS authentication gives the ISP or network administrator the ability to manage PPP user access and accounting from one server throughout a large network. The MikroTik RouterOS has a [RADIUS client](./radius.md) that can authenticate for PPP, [PPPoE](../virtual-private-networks/pppoe/index.md), [PPTP](../virtual-private-networks/pptp.md), [L2TP](../virtual-private-networks/l2tp/index.md), [OpenVPN](../virtual-private-networks/openvpn.md), and ISDN connections. The attributes received from the RADIUS server override the ones set in the default profile, but if some parameters are not received, they are taken from the respective default profile. ## User Profiles **Sub-menu:** `/ppp/profile` PPP profiles are used to define default values for user access records stored under `/ppp/secret` submenu. Settings in `/ppp/secret` User Database override corresponding `/ppp/profile` settings except that single IP addresses always take precedence over IP pools when specified as local-address or remote-address parameters. ### Properties | Property | Description | | :-- | :-- | | **address-list** (*string*; Default: ) | [Address list](../firewall-and-quality-of-service/firewall/address-lists.md) name to which ppp assigned (on server) or received (on client) address will be added. | | **remote-ipv6-prefix-reuse** (*no \| yes*; Default: **no**) | If "remote-ipv6-prefix-pool" is specified and includes a single "/64" prefix, then prefix can be used only for a single PPP client for RADVD configuration. When this option is set to value "yes", the same prefix can be reused among all the clients using this PPP profile. | | **bridge** (*string*; Default: ) | Name of the [bridge](../bridging-and-switching/index.md) interface to which the ppp interface will be added as a slave port. Both tunnel endpoints (server and client) must be in the bridge to make this work, see more details in the bridging manual. | | **bridge-horizon** (*integer 0..429496729*; Default: ) | Used split-horizon value for the dynamically created bridge port. Can be used to prevent bridging loops and isolate traffic. Set the same value for a group of ports, to prevent them from sending data to ports with the same horizon value. | | **bridge-learning** (*default \| no \| yes*; Default: **default**) | Changes MAC learning behavior on the dynamically created bridge port:yes - enables MAC learningno - disables MAC learningdefault - derive this value from the interface default profile; same as yes if this is the interface default profile | | **bridge-path-cost** (*integer 1..200000000*; Default: ) | Used path cost for the dynamically created bridge port, used by STP/RSTP to determine the best path, used by MSTR to determine the best path between regions. This property has no effect when a bridge protocol-mode is set to none. | | **bridge-port-priority** (*integer 0..240*; Default: ) | Used priority for the dynamically created bridge port, used by STP/RSTP to determine the root port, used by MSTP to determine the root port between regions. This property has no effect when a bridge protocol-mode is set to none. | | **bridge-port-vid** (*integer 1..4094*; Default: **1**) | Used to assign PVID parameter for dynamically created interface. This property only has an effect when bridge vlan-filtering is set to yes. | | **bridge-port-trusted**(*no \| yes*;Default: **no**) | Used to set the dynamically created interface as DHCP trusted. | | **change-tcp-mss** (*yes \| no \| default*; Default: **no**) | Modifies connection MSS settings (applies only for IPv4):yes - adjust connection MSS valueno - do not adjust connection MSS valuedefault - derive this value from the interface default profile; same as no if this is the interface default profile | | **comment** (*string*; Default: ) | Profile comment | | **dhcpv6-lease-time** (*string*; Default: ) | Lease time can be set starting from 7.20ab202, by default the time is set to 1d. | | **dhcpv6-pd-pool** (*string*; Default: ) | Name of the [IPv6 pool](../cli-reference/ipv6/pool.md) which will be used by dynamically created [DHCPv6 server](../network-management/dhcp.md#dhcpv6-server) when client connects. [`Read more >>`](../virtual-private-networks/pppoe/ipv6-pd-over-ppp.md) | | **dhcpv6-use-radius** (*no \| yes*; Default: **no**) | Specifies value for "use-radius" option selected for dynamically generated DHCPv6 PD servers. | | **dns-server** (*IP*; Default: ) | IP address of the DNS server that is supplied to PPP clients | | **idle-timeout** (*time*; Default: ) | Specifies the amount of time after which the link will be terminated if there is no activity present. Timeout is not set by default | | **incoming-filter** (*string*; Default: ) | Firewall chain name for incoming packets. The specified chain gets control of each packet coming from the client. The ppp chain should be manually added and rules with action=jump jump-target=ppp should be added to other relevant chains for this feature to work. For more information look at the Examples section. | | **insert-queue-before** (*bottom \| first \| queue name* ; Default: ) | Inserts new queue as the last, first, or before a specified queue | | **interface-list** (*interface list name*; Default: ) | Specifies interface list to which profile interfaces will be added | | **local-address** (*IP address \| pool*; Default: ) | Tunnel address or name of the [pool](../cli-reference/ip/pool.md) from which the address is assigned to ppp interface locally | | **name** (*string*; Default: ) | PPP profile name | | **on-up** (*script*; Default: ) | Execute script on the user login-event. These are available variables that are accessible for the event script:userlocal-addressremote-addresscaller-idcalled-idinterface The *interface* variable will return interface id value, not interface name. | | **on-down** (*script*; Default: ) | Execute script on the user logging off. See ***on-up*** for more details | | **only-one** (*yes \| no \| default*; Default: **default**) | Defines whether a user is allowed to have more than one ppp session at a timeyes - a user is not allowed to have more than one ppp session at a timeno - the user is allowed to have more than one ppp session at a timedefault - derive this value from the interface default profile; same as no if this is the interface default profile | | **outgoing-filter** (*string*; Default: ) | Firewall chain name for outgoing packets. The specified chain gets control for each packet going to the client. The PPP chain should be manually added and rules with action=jump jump-target=ppp should be added to other relevant chains for this feature to work. For more information look at the Examples section. | | **parent-queue** (*none* \| *queue name*; Default: ) | Specifies parent queue | | **queue-type** (*default \| ethernet-default \| wireless-default \| synchronous-default \|* *hotspot-default \| pcq-upload-default \| pcq-download-default \| only-hardware-queue \| multi-queue-ethernet-default \| default-small \| custom queue type name* ; Default: ) | Specifies queue type. Starting from 7.19 it is possible to specify queue type for rx/tx separately for clients "upload" and "download". Use / to configure separate queue type, first is rx queue type, and then tx queue type. | | **rate-limit** (*string*; Default: ) | Rate limitation in the form of **rx-rate[/tx-rate] [rx-burst-rate[/tx-burst-rate] [rx-burst-threshold[/tx-burst-threshold] [rx-burst-time[/tx-burst-time] [priority] [rx-rate-min[/tx-rate-min]]]]** from the point of view of the router (so "rx" is client upload, and "tx" is client download). All rates are measured in bits per second, unless followed by an optional 'k' suffix (kilobits per second) or 'M' suffix (megabits per second). If tx-rate is not specified, rx-rate serves as tx-rate too. The same applies to tx-burst-rate, tx-burst-threshold and tx-burst-time. If both rx-burst-threshold and tx-burst-threshold are not specified (but burst-rate is specified), rx-rate and tx-rate are used as burst thresholds. If both rx-burst-time and tx-burst-time are not specified, 1s is used as default. Priority takes values 1..8, where 1 implies the highest priority, but 8 - the lowest. If rx-rate-min and tx-rate-min are not specified rx-rate and tx-rate values are used. The rx-rate-min and tx-rate-min values can not exceed rx-rate and tx-rate values. | | **remote-address** (*IP*; Default: ) | Tunnel address or name of the [pool](../cli-reference/ip/pool.md) from which address is assigned to the remote ppp interface. | | **remote-ipv6-prefix-pool** (*string \| none*; Default: **none**) | Assign a prefix from the IPv6 pool to the client and install the corresponding IPv6 route. | | **session-timeout** (*time*; Default: ) | Maximum time the connection can stay up. By default, no time limit is set. | | **use-compression** (*yes \| no \| default*; Default: **default**) | Specifies whether to use data compression or not.yes - enable data compressionno - disable data compressiondefault - derive this value from the interface default profile; same as no if this is the interface default profileThis setting does not affect OVPN tunnels. | | **use-encryption** (*yes \| no \| default \| require*; Default: **default**) | Specifies whether to use data encryption or not.yes - enable data encryptionno - disable data encryptiondefault - derive this value from the interface default profile; same as no if this is the interface default profilerequire - explicitly requires encryptionThis setting does not work on OVPN and SSTP tunnels. | | **use-ipv6** (*yes \| no \| default \| require*; Default: **default**) | Specifies whether to allow IPv6. By default, it is enabled if IPv6 package is installed.yes - enable IPv6 supportno - disable IPv6 supportdefault - derive this value from the interface default profile; same as no if this is the interface default profilerequire - explicitly requires IPv6 support | | **use-mpls** (*yes \| no \| default \| require*; Default: **default**) | Specifies whether to allow MPLS over PPP.yes - enable MPLS supportno - disable MPLS supportdefault - derive this value from the interface default profile; same as no if this is the interface default profilerequire - explicitly requires MPLS support | | **use-upnp** (*yes \| no \| default*; Default: **default**) | Specifies whether to allow UPnP:yes - enable UPnP.no - disable UPnP.default - derive this value from the interface default profile; same as no if this is the interface default profile. | | **wins-server** (*IP address*; Default: ) | IP address of the WINS server to supply to Windows clients | ### Notes The two default profiles cannot be removed: ```ros [admin@rb13] /ppp/profile> print Flags: * - default 0 * name="default" use-compression=no use-encryption=no only-one=no change-tcp-mss=yes 1 * name="default-encryption" use-compression=default use-encryption=yes only-one=default change-tcp-mss=default [admin@rb13] /ppp/profile> ``` *incoming-filter* and *outgoing-filter* arguments add dynamic jump rules to chain *ppp*, where the jump-target argument will be equal to the *incoming-filter* or *outgoing-filter* argument in the profile. Therefore, chain *ppp* should be manually added before changing these arguments. Only-one parameter is ignored if RADIUS authentication is used. PPP tunnels use LCP protocol for MTU negotiation, it happens right when connection is established. Framed MTU attribute is not supported, as it is sent only after authentication with Radius. ## User Database **Sub-menu:** `/ppp/secret` PPP User Database stores PPP user access records with PPP user profile assigned to each user. ## Properties | Property | Description | | :-- | :-- | | **caller-id** (*string*; Default: ) | For [PPTP](../virtual-private-networks/pptp.md) and [L2TP](../virtual-private-networks/l2tp/index.md) it is the IP address a client must connect from. For [PPPoE](../virtual-private-networks/pppoe/index.md) it is the MAC address (written in CAPITAL letters) a client must connect from. For ISDN it is the caller's number (that may or may not be provided by the operator) the client may dial in from | | **comment** (*string*; Default: ) | Short description of the user. | | **disabled** (*yes \| no*; Default: **no**) | Whether secret will be used. | | **limit-bytes-in** (*integer*; Default: **0**) | The maximum amount of bytes for a session that the client can upload. | | **limit-bytes-out** (*integer*; Default: **0**) | The maximum amount of bytes for a session that the client can download. | | **local-address** (*IP address*; Default: ) | IP address that will be set locally on the ppp interface. | | **name** (*string*; Default: ) | Name used for authentication | | **password** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | Password used for authentication | | **profile** (*string*; Default: **default**) | Which [user profile](#user-profiles) to use | | **remote-address** (*IP*; Default: ) | IP address that will be assigned to the remote ppp interface. | | **remote-ipv6-prefix** (*IPv6 prefix*; Default: ) | IPv6 prefix assigned to the ppp client. Prefix is added to [ND prefix list](../system-information-and-utilities/neighbor-discovery.md) enabling [stateless](../getting-started/networking-fundamentals/ipv6-neighbor-discovery.md#stateless-address-autoconfiguration) address auto-configuration on the ppp interface. | | **routes** (*string*; Default: ) | Routes that appear on the server when the client is connected. The route format is: dst-address gateway metric (for example, 10.1.0.0/ 24 10.0.0.1 1). Other syntax is not acceptable since it can be represented incorrectly. Several routes may be specified and separated with commas. This parameter will be ignored for [OpenVPN](../virtual-private-networks/openvpn.md). | | **service** (*any \| async \| isdn \| l2tp \| pppoe \| pptp \| ovpn \| sstp*; Default: **any**) | Specifies the services that a particular user will be able to use. | ## Active Users **Sub-menu:** `/ppp/active` This submenu allows monitoring active (connected) users. The `/ppp/active/print` command will show all currently connected users. The `/ppp/active/print stats` command will show received/sent bytes and packets ## Properties | Property | Description | | :-- | :-- | | **address** (*IP address*) | The IP address the client got from the server | | **bytes** (*integer*) | Number of bytes transferred through this connection. The first figure represents the amount of transmitted traffic from the router's point of view, while the second one shows the amount of received traffic. | | **caller-id** (*string*) | For [PPTP](../virtual-private-networks/pptp.md) and [L2TP](../virtual-private-networks/l2tp/index.md) it is the IP address the client connected from. For [PPPoE](../virtual-private-networks/pppoe/index.md), it is the MAC address the client connected from. | | **encoding** (*string*) | Shows encryption and encoding (separated with '/' if asymmetric) being used in this connection | | **limit-bytes-in** (*integer*) | The maximum number of bytes the user is allowed to send to the router. | | **limit-bytes-out** (*integer*) | The maximum number of bytes the user is allowed to send to the client. | | **name** (*string*) | User name supplied at the authentication stage | | **packets** (*integer/integer*) | Number of packets transferred through this connection. The first figure represents the amount of transmitted traffic from the router's point of view, while the second one shows the amount of received traffic | | **service** (*async \| isdn \| l2tp \| pppoe \| pptp \| ovpn \| sstp*) | Type of service the user is using. | | **session-id** (*string*) | Shows the unique client identifier. | | **uptime** (*time*) | User's uptime | ## Remote AAA **Sub-menu:** `/ppp/aaa` Settings in this submenu allow setting RADIUS accounting and authentication. Note that the RADIUS user database is consulted only if the required username is not found in the local user database. ## Properties | Property | Description | | :-- | :-- | | **accounting** (*yes \| no*; Default: **yes**) | Enable RADIUS accounting | | **interim-update** (*time*; Default: **0s**) | Interim-Update time interval | | **use-radius** (*yes \| no*; Default: **no**) | Enable user authentication via RADIUS. If an entry in the local secret database is not found, then the client will be authenticated via RADIUS. | | **enable-ipv6-accounting** (*yes \| no*; Default: **no**) | Enable IPv6 separate accounting. PPP service counts Layer2, IPv4 and IPv6 data all together when reporting network usage statistics to the RADIUS server by default. If it is required to differentiate between IPv4 and IPv6 traffic, then this option can be enabled. Prerequisites for it to work are that the prefix must be assigned to the client through PPP service and also rate-limit must be provided. Dynamically created queue statistics will be used as counters for IPv6 data, which then will be included in accounting packets as separate IPv6 statistics attributes. This will not work for prefixes assigned by a dynamically created DHCPv6 server due to the provided prefix pool or PPP/Profile configuration. Then prefix assignment is handled by DHCP service, not PPP, thus accounting can not be managed by PPP service. | ## Examples #### Add new profile To add the profile ex that assigns the router itself the 10.0.0.1 address, and the addresses from the ex pool to the clients, filtering traffic coming from clients through mypppclients chain: ```ros [admin@rb13] /ppp/profile> add name=ex local-address=10.0.0.1 remote-address=ex incoming-filter=mypppclients [admin@rb13] /ppp/profile> print Flags: * - default 0 * name="default" use-compression=no use-vj-compression=no use-encryption=no only-one=no change-tcp-mss=yes 1 name="ex" local-address=10.0.0.1 remote-address=ex use-compression=default use-vj-compression=default use-encryption=default only-one=default change-tcp-mss=default incoming-filter=mypppclients 2 * name="default-encryption" use-compression=default use-vj-compression=default use-encryption=yes only-one=default change-tcp-mss=default [admin@rb13] /ppp/profile> ``` #### Add new user To add the user "ex" with password "lkjrht" and profile "ex" available for PPTP service only, enter the following command: ```ros [admin@rb13] /ppp/secret> add name=ex password=lkjrht service=pptp profile=ex [admin@rb13] /ppp/secret> print Flags: X - disabled # NAME SERVICE CALLER-ID PASSWORD PROFILE REMOTE-ADDRESS 0 ex pptp lkjrht ex 0.0.0.0 [admin@rb13] /ppp/secret> ``` --- ## RADIUS RADIUS, short for Remote Authentication Dial-In User Service, is a remote server that provides authentication and accounting facilities to various network appliances. RADIUS authentication and accounting allows the ISP or network administrator to manage PPP user access and accounting from one server throughout a large network. The MikroTik RouterOS has a RADIUS client that can authenticate [router's local](./user.md) [users](./user.md), [HotSpot](./hotspot-captive-portal/index.md), [PPP](../mobile-networking/ppp.md) and ISDN connections. The attributes received from the RADIUS server override the ones set in the default profile, but if some parameters are not received they are taken from the respective default profile. The RADIUS server database is consulted only if no matching user access record is found in the router's local database. If RADIUS accounting is enabled, accounting information is also sent to the default RADIUS server for that service. ## RADIUS Client **Sub-menu:** `/radius` This sub-menu allows adding and removing RADIUS clients. :::warning The order of added items in this list is significant. ::: ### Properties | Property | Description | | :-- | :-- | | **accounting-backup** (*yes \| no*; Default: **no**) | Whether the configuration is for the backup RADIUS server | | **accounting-port** (*integer [1..65535]*; Default: **1813**) | RADIUS server port used for accounting | | **address** (*IPv4/IPv6 address*; Default: **0.0.0.0**) | IPv4 or IPv6 address of RADIUS server. The following formats are accepted: - *ipv4* - *ipv4*`@`*vrf* - *ipv6* - *ipv6*`@`*vrf* | | **authentication-port** (*integer [1..65535]*; Default: **1812**) | RADIUS server port used for authentication. | | **called-id** (*string*; Default: ) | Value depends on Point-to-Point protocol: PPPoE - service name, PPTP - server's IP address, L2TP - server's IP address. | | **certificate** (*string*; Default: ) | Certificate file to use for communicating with RADIUS Server with RadSec enabled. | | **comment** (*string*; Default: ) | | | **disabled** (*yes \| no*; Default: **no**) | | | **domain** (*string*; Default: ) | Microsoft Windows domain of client passed to RADIUS servers that require domain validation. | | **protocol** (*radsec \| udp*; Default: **udp**) | Specifies the protocol to use when communicating with the RADIUS Server. | | **radsec-timeout**(*time,* Default: **3300ms**) | Timeout after which the request should be resent over RadSec protocol. | | **require-message-auth** (*no \| yes-for-request-resp* Default: **yes-for-request-resp**) | Specifies if Message-Authenticator attributes are required. | | **realm** (*string*; Default: ) | Explicitly stated realm (user domain), so the users do not have to provide proper ISP domain name in the user name. | | **secret** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | The shared secret used to access the RADIUS server. | | **service** (*ppp\|login\|hotspot\|wireless\|dhcp\|ipsec\|dot1x*; Default: ) | Router services that will use this RADIUS server:hotspot - HotSpot authentication servicelogin - router's local user authenticationppp - Point-to-Point clients authenticationwireless - wireless client authenticationdhcp - DHCP protocol client authentication (client's MAC address is sent as User-Name)ipsec - ipsec client authenticationdot1x - dot1x authentication | | **src-address** (*ipv4/ipv6 address*; Default: **0.0.0.0**) | Source IP/IPv6 address of the packets sent to the RADIUS server | | **timeout** (*time*; Default: **1100ms**) | Timeout after which the request should be resent. | :::warning When the RADIUS server is authenticating the user with CHAP, MS-CHAPv1, MS-CHAPv2, it is not using a shared secret; the secret is used only in the authentication reply, and the router (RADIUS client) verifies it.So if you have the wrong shared secret, the RADIUS server will accept a request, but the router won't accept the reply. You can see that with the "*`/radius/monitor`*" command, the "bad-replies" number should increase whenever somebody tries to connect. ::: :::danger If RadSec is enabled, make sure your RADIUS Server is using "**radsec**" as the shared secret, otherwise, the RADIUS Server will not be able to decrypt data correctly (unprintable characters).With RadSec, RouterOS forces the shared secret to "radsec" regardless of what has been set manually.For more details see RFC6614. ::: :::info If RadSec is used, RouterOS will override to use TCP port 2083 ::: ### Example To set up a RADIUS Client for HotSpot and PPP services that will authenticate against a RADIUS Server (10.0.0.3), you need to do the following: ```ros [admin@MikroTik] > /radius/add service=hotspot,ppp address=10.0.0.3 secret=ex [admin@MikroTik] > /radius/print Flags: X - disabled # SERVICE CALLED-ID DOMAIN ADDRESS SECRET 0 ppp,hotspot ``` To set up a RADIUS Client with RadSec, you need to do the following: ```ros [admin@MikroTik] > /radius/add service=hotspot,ppp address=10.0.0.3 secret=radsec protocol=radsec certificate=client.crt [admin@MikroTik] > /radius/print Flags: X - disabled # SERVICE CALLED-ID DOMAIN ADDRESS SECRET 0 ppp,hotspot 10.0.0.3 radsec ``` :::warning Make sure the specified certificate is trusted and common-name verification on both ends will work properly. ::: Here is a trivial example of certificates that can be used for RADIUS RadSec configuration: ```ros On server: #CN should be RADIUS server IP /certificate/add name=radsec_server common-name=10.155.114.91 /certificate/sign radsec_server #CN should be RADIUS client IP /certificate/add name=radsec_client1 common-name=10.155.114.92 /certificate/sign radsec_client1 /user-manager/set radsec-certificate=radsec_server #Export certificates on the server in order to apply them on client /certificate/export-certificate type=pkcs12 export-passphrase=verystrongpassword radsec_client1 /certificate/export-certificate type=pkcs12 radsec_server On client: #Download both files and upload them to the client /certificate/import file-name=cert_export_radsec_client1.p12 passphrase=verystrongpassword /certificate/import file-name=cert_export_radsec_server.p12 /radius/set certificate=cert_export_radsec_client1.p12_0 #After that when RADIUS client tries to connect to the server you should see on status fileld: status="TLS connected". ``` To view RADIUS Client statistics, you need to do the following: ```ros [admin@MikroTik] > /radius/monitor 0 pending: 0 requests: 10 accepts: 4 rejects: 1 resends: 15 timeouts: 5 bad-replies: 0 last-request-rtt: 0s ``` Make sure you enable RADIUS authentication for the desired services: ```ros /ppp/aaa/set use-radius=yes /ip/hotspot/profile/set default use-radius=yes ``` ## Connection Terminating from RADIUS **Sub-menu:** `/radius/incoming` This facility supports unsolicited messages sent from the RADIUS server. Unsolicited messages extend RADIUS protocol commands that allow terminating a session that has already been connected from the RADIUS server. For this purpose, DM (Disconnect-Messages) is used. Disconnect messages cause a user session to be terminated immediately. :::warning RouterOS doesn't support POD (Packet of Disconnect), the other RADIUS access request packet that performs a similar function to Disconnect Messages ::: ### Properties | Property | Description | | :-- | :-- | | **accept** (*yes \| no*; Default: **no**) | Whether to accept unsolicited messages | | **port** (*integer*; Default: **1700**) | The port number to listen for the requests on | | **vrf** (*VRF name*; default value: **main**) | Set VRF on which the service is listening for incoming connections | ## Supported RADIUS Attributes Here you can download the [RADIUS reference dictionary.txt](pathname:///assets/319783010_RADIUS_reference_dictionary.txt), that includes all supported RADIUS attributes by MikroTik device. This file is designed for FreeRADIUS, but may also be used by other RADIUS servers. Note, it may conflict with the default configuration file of your RADIUS server. Correct the configuration, not the dictionary, as no other attributes are supported by MikroTik RouterOS. There is also the [MikroTik Vendor attributes.txt](pathname:///assets/319783011_MikroTik_Vendor_attributes.txt) that can be included in an existing dictionary to support MikroTik vendor-specific attributes. Below you will find a description about attributes and how they are used on MikroTik devices during communication with RADIUS. ### Definitions - **PPPs** - PPP, PPTP, PPPoE - **default configuration** - settings in default profile (for PPPs) or HotSpot server settings (for HotSpot) ### Access-Request packet - **Service-Type** - Always is "Framed" (only for PPPs). - **Framed-Protocol** - Always is "PPP" (only for PPPs). - **NAS-Identifier** - Router's identity name. - **NAS-IP-Address** - IP address of the router itself. - **NAS-Port** - This Attribute indicates the physical port number of the NAS which is authenticating the user. - **Acct-Session-Id** - Unique session ID. The first two symbols of session ID represent service (PPP, Hotspot, etc.). The next symbol is incremented on each reboot. The last group of symbols is incremented on each new session. This means, that you can not get the same ID for 1 million re-connects on the same boot for the same RADIUS type service. If you lose the session stop message and RADIUS server does still keep the session open, but then receives another session start message, then it must be aware that the stop message was lost, close the old session and start a new session. - **NAS-Port-Type** - Async PPP - "Async"; PPTP and L2TP - "Virtual"; PPPoE - "Ethernet"; ISDN - "ISDN Sync"; HotSpot - "Ethernet | Cable | Wireless-802.11" (according to the value of the nas-port-type parameter in `/ip/hotspot/profile`). - **Calling-Station-Id** - PPPoE and HotSpot- client MAC address in capital letters; PPTP and L2TP - client public IP address. - **Called-Station-Id** - PPPoE - service name; PPTP and L2TP - server IP address; HotSpot - name of the HotSpot server. - **NAS-Port-Id** - Async PPP - serial port name; PPPoE - ethernet interface name on which server is running; HotSpot - name of the physical HotSpot interface (if bridged, the bridge port name is shown here); not present for ISDN, PPTP and L2TP. - **Framed-IP-Address** - IP address of HotSpot client after Universal Client translation. - **Mikrotik-Host-IP** - IP address of HotSpot client before Universal Client translation (the original IP address of the client). - **User-Name** - Client login name. - **MS-CHAP-Domain** - User domain, if present. - **Mikrotik-Realm** - If it is set in /radius menu, it is included in every RADIUS request as the Mikrotik-Realm attribute. If it is not set, the same value is sent as in the MS-CHAP-Domain attribute (if MS-CHAP-Domain is missing, Realm is not included either). - **WISPr-Location-ID** - Text string specified in the radius-location-id property of the HotSpot server. - **WISPr-Location-Name** - Text string specified in the radius-location-name property of the HotSpot server. - **WISPr-Logoff-URL** - Full link to the logout page (for example, **[](http://10.48.0.1/lv/logout)**). Depending on authentication methods (NOTE: HotSpot uses CHAP by default and may also use PAP if unencrypted passwords are enabled, it cannot use MSCHAP): - **User-Password** - Encrypted password (used with PAP authentication). - **CHAP-Password**, **CHAP-Challenge** - Encrypted password and challenge (used with CHAP authentication). - **MS-CHAP-Response**, MS-CHAP-Challenge - Encrypted password and challenge (used with MS-CHAPv1 authentication). - **MS-CHAP2-Response**, **MS-CHAP-Challenge** - Encrypted password and challenge (used with MS-CHAPv2 authentication). ### Access-Accepts packet - **Framed-IP-Address** - IP address given to the client. If the address belongs to 127.0.0.0/8 or 224.0.0.0/3 networks, IP pool is used from the default profile to allocate a client IP address. If Framed-IP-Address is specified, Framed-Pool is ignored. - **Framed-IP-Netmask** - Client netmask. PPPs - if specified, a route will be created to the network Framed-IP-Address belongs to via the Framed-IP-Address gateway; HotSpot - ignored by HotSpot. - **Framed-Pool** - IP pool name (on the router) from which to get an IP address for the client. If Framed-IP-Address is specified, this attribute is ignored. - **Framed-IPv6-Prefix** - IPv6 prefix assigned to the client. - **Mikrotik-Delegated-IPv6-Pool** - IPv6 pool used for Prefix Delegation. - **Delegated-IPv6-Prefix** - IPv6 Prefix. - **Delegated-IPv6-Prefix-Pool** - IPv6 Prefix pool used for Prefix Delegation. NOTE: if Framed-IP-Address or Framed-Pool is specified, it overrides remote-address in the default configuration. - **Idle-Timeout** - Overrides idle-timeout in the default configuration. - **Session-Timeout** - Overrides session-timeout in the default configuration. - **Port-Limit** - Maximal number of simultaneous connections using the same username (overrides the shared-users property of the HotSpot user profile). - **Class** - Cookie. Will be included in Accounting-Request unchanged. - **Framed-Route** - Routes to add on the server. Format is specified in RFC 2865 (Ch. 5.22). Can be specified as many times as needed. - **Filter-Id** - Firewall filter chain name. It is used to make a dynamic firewall rule. Firewall chain name can have suffix .in or .out, that will install rule only for incoming or outgoing traffic. Multiple Filter-id can be provided, but only last ones for incoming and outgoing are used. For PPPs - filter rules in ppp chain that will jump to the specified chain, if a packet has come to/from the client (that means that you should first create a ppp chain and make jump rules that would put actual traffic to this chain). The same applies for HotSpot, but the rules will be created in hotspot chain. - **Mikrotik-Mark-Id** - Firewall mangle chain name (HotSpot only). The MikroTik RADIUS client upon receiving this attribute creates a dynamic firewall mangle rule with action=jump chain=hotspot and jump-target equal to the attribute value. Mangle chain name can have suffixes .in or .out, that will install rule only for incoming or outgoing traffic. Multiple Mark-id attributes can be provided, but only last ones for incoming and outgoing is used. - **Acct-Interim-Interval** - Interim-update for RADIUS client. PPP - if 0 uses the one specified in RADIUS client. HotSpot - only respected if radius-interim-update=received in HotSpot server profile. - **MS-MPPE-Encryption-Policy** - Require-encryption property (PPPs only). - **MS-MPPE-Encryption-Types** - Use-encryption property. Non-zero value means to use encryption (PPPs only). - **Ascend-Data-Rate** - Tx/rx data rate limitation if multiple attributes are provided, first limits tx data rate, second - rx data rate. If used together with Ascend-Xmit-Rate, specifies rx rate. 0 if unlimited. Ignored if Rate-Limit attribute is present. - **Ascend-Xmit-Rate** - Tx data rate limitation. It may be used to specify tx limit only instead of sending two sequential Ascend-Data-Rate attributes (in that case Ascend-Data-Rate will specify the receive rate). 0 if unlimited. Ignored if Rate-Limit attribute is present. - **MS-CHAP2-Success** - Auth. response if MS-CHAPv2 was used (for PPPs only). - **MS-MPPE-Send-Key, MS-MPPE-Recv-Key** - Encryption keys for encrypted PPPs provided by RADIUS server only if MS-CHAPv2 was used as authentication (for PPPs only). - **Ascend-Client-Gateway** - Client gateway for DHCP-pool HotSpot login method (HotSpot only). - **Mikrotik-Recv-Limit** - Total receive limit in bytes for the client. - **Mikrotik-Recv-Limit-Gigawords** - 4G (2^32) bytes of total receive limit (bits 32..63, when bits 0..31 are delivered in Mikrotik-Recv-Limit). - **Mikrotik-Xmit-Limit** - Total transmit limit in bytes for the client. - **Mikrotik-Xmit-Limit-Gigawords** - 4G (2^32) bytes of total transmit limit (bits 32..63, when bits 0..31 are delivered in Mikrotik-Xmit-Limit). - **Mikrotik-Wireless-Forward** - Does not forward the client's frames back to the wireless infrastructure if this attribute is set to "0" (Wireless only). - **Mikrotik-Wireless-Skip-Dot1x** - Disables 802.1x authentication for the particular wireless client if set to non-zero value (Wireless only). - **Mikrotik-Wireless-Enc-Algo** - WEP encryption algorithm: 0 - no encryption, 1 - 40-bit WEP, 2 - 104-bit WEP (Wireless only). - **Mikrotik-Wireless-Enc-Key** - WEP encryption key for the client (Wireless only). - **Mikrotik-Wireless-VLANID** - VLAN ID for the client (Wireless only). - **Mikrotik-Wireless-VLANID-type** - VLAN ID type for the client. 0 - 802.1q tag and 1 - 802.1ad tag (Wireless only). - **Mikrotik-Switching-Filter** - Allows creating dynamic switch rules, when authenticating clients with dot1x server. - **Mikrotik-Rate-Limit** - Datarate limitation for clients. Format is: rx-rate[/tx-rate] [rx-burst-rate[/tx-burst-rate] [rx-burst-threshold[/tx-burst-threshold] [rx-burst-time[/tx-burst-time] [priority] [rx-rate-min[/tx-rate-min]]]] from the point of view of the router (so "rx" is client upload, and "tx" is client download). All rates should be numbers with optional 'k' (1,000s) or 'M' (1,000,000s). If tx-rate is not specified, rx-rate is as tx-rate too. Same goes for tx-burst-rate and tx-burst-threshold and tx-burst-time. If both rx-burst-threshold and tx-burst-threshold are not specified (but burst-rate is specified), rx-rate and tx-rate are used as burst thresholds. If both rx-burst-time and tx-burst-time are not specified, 1s is used as default. Priority takes values 1..8, where 1 implies the highest priority, but 8 - the lowest. If rx-rate-min and tx-rate-min are not specified rx-rate and tx-rate values are used. The rx-rate-min and tx-rate-min values can not exceed rx-rate and tx-rate values. - **Mikrotik-Group** - Router local user group name (defined in `/user/group`) for local users; HotSpot default profile for HotSpot users; PPP default profile name for PPP users. - **Mikrotik-Advertise-URL** - URL of the page with advertisements that should be displayed to clients. If this attribute is specified, advertisements are enabled automatically, including transparent proxy, even if they were explicitly disabled in the corresponding user profile. Multiple attribute instances may be sent by RADIUS server to specify additional URLs which are chosen in round robin fashion. - **Mikrotik-Advertise-Interval** - Time interval between two adjacent advertisements. Multiple attribute instances may be sent by RADIUS server to specify additional intervals. All interval values are treated as a list and are taken one-by-one for each successful advertisement. If end of list is reached, the last value is continued to be used. - **WISPr-Redirection-URL** - URL, which the clients will be redirected to after successful login. - **WISPr-Bandwidth-Min-Up** - Minimal datarate (CIR) provided for the client upload. - **WISPr-Bandwidth-Min-Down** - Minimal datarate (CIR) provided for the client download. - **WISPr-Bandwidth-Max-Up** - Maximal datarate (MIR) provided for the client upload. - **WISPr-Bandwidth-Max-Down** - Maximal datarate (MIR) provided for the client download. - **WISPr-Session-Terminate-Time** - Time, when the user should be disconnected; in "YYYY-MM-DDThh:mm:ssTZD" form, where Y - year; M - month; D - day; T - separator symbol (must be written between date and time); h - hour (in 24 hour format); m - minute; s - second; TZD - time zone in one of these forms: "+hh:mm", "+hhmm", "-hh:mm", "-hhmm". The received attributes override the default ones (set in the default profile), but if an attribute is not received from the RADIUS server, the default one is to be used. Rate-Limit takes precedence over all other ways to specify data rate for the client. Ascend data rate attributes are considered second; and WISPr attributes take the last precedence. Here are some Rate-Limit examples: - **128k** - rx-rate=128000, tx-rate=128000 (no bursts). - **64k/128M** - rx-rate=64000, tx-rate=128000000. - **64k 256k** - rx/tx-rate=64000, rx/tx-burst-rate=256000, rx/tx-burst-threshold=64000, rx/tx-burst-time=1s. - **64k/64k 256k/256k 128k/128k 10/10** - rx/tx-rate=64000, rx/tx-burst-rate=256000, rx/tx-burst-threshold=128000, rx/tx-burst-time=10s. ### Accounting-Request packet The accounting request carries the same attributes as Access Request, plus these ones: - **Acct-Status-Type** - Start, Stop, or Interim-Update. - **Acct-Authentic** - Either authenticated by RADIUS or Local authority (PPPs only). - **Class** - RADIUS server cookie, as received in Access-Accept. - **Acct-Delay-Time** - How long the router tries to send this Accounting-Request packet. ### Stop and Interim-Update Accounting-Request packet In addition to the accounting start request, the following messages will contain the following attributes: - **Acct-Session-Time** - Connection uptime in seconds. - **Acct-Input-Octets** - Bytes received from the client. - **Acct-Input-Gigawords** - 4G (2^32) bytes received from the client (bits 32..63, when bits 0..31 are delivered in Acct-Input-Octets). - **Acct-Input-Packets** - Number of packets received from the client. - **Acct-Output-Octets** - Bytes sent to the client. - **Acct-Output-Gigawords** - 4G (2^32) bytes sent to the client (bits 32..63, when bits 0..31 are delivered in Acct-Output-Octets). - **Acct-Output-Packets** - Number of packets sent to the client. :::warning RADIUS accounting messages in RouterOS represent output as traffic from the client point of view, for example, for VPN user "test" output is user upload. ::: ### **Stop Accounting-Request packet** These packets will, in addition to the Interim Update packets, have: - **Acct-Terminate-Cause** - session termination cause (see RFC 2866 ch. 5.10) ### **Change of Authorization** RADIUS disconnect and Change of Authorization (according to RFC3576) are supported as well. These attributes may be changed by a CoA request from the RADIUS server: - **Mikrotik-Group** - **Mikrotik-Recv-Limit** - **Mikrotik-Xmit-Limit** - **Mikrotik-Rate-Limit** - **Ascend-Data-Rate** (only if Mikrotik-Rate-Limit is not present) - **Ascend-XMit-Rate** (only if Mikrotik-Rate-Limit is not present) - **Mikrotik-Mark-Id** - **Filter-Id** - **Mikrotik-Advertise-Url** - **Mikrotik-Advertise-Interval** - **Session-Timeout** - **Idle-Timeout** - **Port-Limit** Note that it is not possible to change the IP address, the pool or routes that way - for such changes a user must be disconnected first. ## MikroTik Specific RADIUS Attribute Numeric Values | Name | VendorID | Value | RFC | |:-- | --:| --:|:-- | | **MIKROTIK\_RECV\_LIMIT** | 14988 | 1 | | | **MIKROTIK\_XMIT\_LIMIT** | 14988 | 2 | | | **MIKROTIK\_GROUP** | 14988 | 3 | | | **MIKROTIK\_WIRELESS\_FORWARD** | 14988 | 4 | | | **MIKROTIK\_WIRELESS\_SKIPDOT1X** | 14988 | 5 | | | **MIKROTIK\_WIRELESS\_ENCALGO** | 14988 | 6 | | | **MIKROTIK\_WIRELESS\_ENCKEY** | 14988 | 7 | | | **MIKROTIK\_RATE\_LIMIT** | 14988 | 8 | | | **MIKROTIK\_REALM** | 14988 | 9 | | | **MIKROTIK\_HOST\_IP** | 14988 | 10 | | | **MIKROTIK\_MARK\_ID** | 14988 | 11 | | | **MIKROTIK\_ADVERTISE\_URL** | 14988 | 12 | | | **MIKROTIK\_ADVERTISE\_INTERVAL** | 14988 | 13 | | | **MIKROTIK\_RECV\_LIMIT\_GIGAWORDS** | 14988 | 14 | | | **MIKROTIK\_XMIT\_LIMIT\_GIGAWORDS** | 14988 | 15 | | | **MIKROTIK\_WIRELESS\_PSK** | 14988 | 16 | | | **MIKROTIK\_TOTAL\_LIMIT** | 14988 | 17 | | | **MIKROTIK\_TOTAL\_LIMIT\_GIGAWORDS** | 14988 | 18 | | | **MIKROTIK\_ADDRESS\_LIST** | 14988 | 19 | | | **MIKROTIK\_WIRELESS\_MPKEY** | 14988 | 20 | | | **MIKROTIK\_WIRELESS\_COMMENT** | 14988 | 21 | | | **MIKROTIK\_DELEGATED\_IPV6\_POOL** | 14988 | 22 | | | **MIKROTIK\_DHCP\_OPTION\_SET** | 14988 | 23 | | | **MIKROTIK\_DHCP\_OPTION\_PARAM\_STR1** | 14988 | 24 | | | **MIKROTIK\_DHCP\_OPTION\_PARAM\_STR2** | 14988 | 25 | | | **MIKROTIK\_WIRELESS\_VLANID** | 14988 | 26 | | | **MIKROTIK\_WIRELESS\_VLANIDTYPE** | 14988 | 27 | | | **MIKROTIK\_WIRELESS\_MINSIGNAL** | 14988 | 28 | | | **MIKROTIK\_WIRELESS\_MAXSIGNAL** | 14988 | 29 | | | **Mikrotik-Switching-Filter** | 14988 | 30 | ## All Supported Attribute Numeric Values | Name | VendorID | Value | RFC | |:-- |:-- | --:|:-- | | **Acct-Authentic** | | 45 | RFC 2866 | | **Acct-Delay-Time** | | 41 | RFC 2866 | | **Acct-Input-Gigawords** | | 52 | RFC 2869 | | **Acct-Input-Octets** | | 42 | RFC 2866 | | **Acct-Input-Packets** | | 47 | RFC 2866 | | **Acct-Interim-Interval** | | 85 | RFC 2869 | | **Acct-Output-Gigawords** | | 53 | RFC 2869 | | **Acct-Output-Octets** | | 43 | RFC 2866 | | **Acct-Output-Packets** | | 48 | RFC 2866 | | **Acct-Session-Id** | | 44 | RFC 2866 | | **Acct-Session-Time** | | 46 | RFC 2866 | | **Acct-Status-Type** | | 40 | RFC 2866 | | **Acct-Terminate-Cause** | | 49 | RFC 2866 | | **Ascend-Client-Gateway** | 529 | 132 | | | **Ascend-Data-Rate** | 529 | 197 | | | **Ascend-Xmit-Rate** | 529 | 255 | | | **Called-Station-Id** | | 30 | RFC 2865 | | **Calling-Station-Id** | | 31 | RFC 2865 | | **CHAP-Challenge** | | 60 | RFC 2866 | | **CHAP-Password** | | 3 | RFC 2865 | | **Class** | | 25 | RFC 2865 | | **Filter-Id** | | 11 | RFC 2865 | | **Framed-Compression** | | 13 | RFC 2865 | | **Framed-IP-Address** | | 8 | RFC 2865 | | **Framed-IP-Netmask** | | 9 | RFC 2865 | | **Framed-IPv6-Prefix** | | 97 | RFC 3162 | | **Framed-Mtu** | | 12 | RFC 2865 | | **Framed-Pool** | | 88 | RFC 2869 | | **Framed-Protocol** | | 7 | RFC 2865 | | **Framed-Route** | | 22 | RFC 2865 | | **Framed-Routing** | | 10 | RFC 2865 | | **Idle-Timeout** | | 28 | RFC 2865 | | **MS-CHAP-Challenge** | 311 | 11 | RFC 2548 | | **MS-CHAP-Domain** | 311 | 10 | RFC 2548 | | **MS-CHAP-Response** | 311 | 1 | RFC 2548 | | **MS-CHAP2-Response** | 311 | 25 | RFC 2548 | | **MS-CHAP2-Success** | 311 | 26 | RFC 2548 | | **MS-MPPE-Encryption-Policy** | 311 | 7 | RFC 2548 | | **MS-MPPE-Encryption-Types** | 311 | 8 | RFC 2548 | | **MS-MPPE-Recv-Key** | 311 | 17 | RFC 2548 | | **MS-MPPE-Send-Key** | 311 | 16 | RFC 2548 | | **NAS-Identifier** | | 32 | RFC 2865 | | **NAS-Port** | | 5 | RFC 2865 | | **NAS-IP-Address** | | 4 | RFC 2865 | | **NAS-Port-Id** | | 87 | RFC 2869 | | **NAS-Port-Type** | | 61 | RFC 2865 | | **Port-Limit** | | 62 | RFC 2865 | | **Redback-Agent-Remote-Id** | 2352 | 96 | | | **Redback-Agent-Circuit-Id** | 2352 | 97 | | | **Service-Type** | | 6 | RFC 2865 | | **Session-Timeout** | | 27 | RFC 2865 | | **User-Name** | | 1 | RFC 2865 | | **User-Password** | | 2 | RFC 2865 | | **WISPr-Bandwidth-Max-Down** | 14122 | 8 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Bandwidth-Max-Up** | 14122 | 7 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Bandwidth-Min-Down** | 14122 | 6 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Bandwidth-Min-Up** | 14122 | 5 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Location-Id** | 14122 | 1 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Location-Name** | 14122 | 2 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Logoff-URL** | 14122 | 3 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Redirection-URL** | 14122 | 4 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Session-Terminate-Time** | 14122 | 9 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Session-Terminate-End-Of-Day** | 14122 | 10 | [wi-fi.org](https://www.wi-fi.org/) | | **WISPr-Billing-Class-Of-Service** | 14122 | 11 | [wi-fi.org](https://www.wi-fi.org/) | | | | | | --- ## User Manager ## Overview User Manager is a RADIUS server implementation in RouterOS which provides centralized user authentication and authorization to a certain service. Having a central user database allows better tracking of system users and customers. As a separate package, User Manager is available on all architectures except SMIPS; however, care must be taken due to limited free space available. It supports many different authentication methods including PAP, CHAP, MS-CHAP, MS-CHAPv2, EAP-TLS, EAP-TTLS, and EAP-PEAP. In RouterOS, DHCP, Dot1x, Hotspot, IPsec, PPP, and Wireless are features that benefit from User Manager the most. Each user can see their account statistics and manage available profiles using the WEB interface. Additionally, users can buy their own data plans (profiles) using the most popular payment gateway - PayPal, making it a great system for service providers. Customized reports can be generated to ease processing by the billing department. User Manager works according to RADIUS standards defined in [RFC2865](https://tools.ietf.org/html/rfc2865) and [RFC3579](https://tools.ietf.org/html/rfc3579). User Manager is one of the RouterOS features, that is limited by the RouterOS license level. Depending on the [License level](../getting-started/routeros-licensing/x86/index.md#routeros-license-key-levels), the number of active sessions will be limited, including multiple connections per user (not unique accounts). ![](./img/user-manager-01.webp) ## Attributes **Sub-menu:** `/user-manager/attribute` RADIUS attributes are defined authorization, information, and configuration parameters that are passed between the RADIUS server and the client. User Manager allows sending customized attributes defined in the "attributes" menu. RouterOS has a set of predefined attributes already present, but it is also possible to add additional attributes if necessary. Predefined attributes: | Attribute | Vendor ID | Type ID | Value type | Packet type | Description | | :-- | :-- | --: | :-- | :-- | :-- | | Framed-IP-Address | 0 (standard) | 8 | ip address | Access-Accept | [RFC2865 section 5.8](https://tools.ietf.org/html/rfc2865#section-5.8) | | Framed-IP-Netmask | 0 (standard) | 9 | `/ip/address` | Access-Accept | [RFC2865 section 5.9](https://tools.ietf.org/html/rfc2865#section-5.9) | | Session-Timeout | 0 (standard) | 27 | integer (maximum value: 21474720) | Access-Accept, Access-Challenge | [RFC2865 section 5.27](https://tools.ietf.org/html/rfc2865#section-5.27) | | Idle-Timeout | 0 (standard) | 28 | integer | Access-Accept, Access-Challenge | [RFC2865 section 5.28](https://tools.ietf.org/html/rfc2865#section-5.28) | | Tunnel-Type | 0 (standard) | 64 | | Value | Description | | --------: | :----------------------------------------------------------- | | 1 | Point-to-Point Tunneling Protocol (PPTP) | | 2 | Layer Two Forwarding (L2F) | | 3 | Layer Two Tunneling Protocol (L2TP) | | 4 | Ascend Tunnel Management Protocol (ATMP) | | 5 | Virtual Tunneling Protocol (VTP) | | 6 | IP Authentication Header in the Tunnel-mode (AH) | | 7 | IP-in-IP Encapsulation (IP-IP) | | 8 | Minimal IP-in-IP Encapsulation (MIN-IP-IP) | | 9 | IP Encapsulating Security Payload in the Tunnel-mode (ESP) | | 10 | Generic Route Encapsulation (GRE) | | 11 | Bay Dial Virtual Services (DVS) | | 12 | IP-in-IP Tunneling | | 13 | Virtual LAN | | Value | Description | | Value | Description | | | | | | 1 | Point-to-Point Tunneling Protocol (PPTP) | | | | | | 2 | Layer Two Forwarding (L2F) | | | | | | 3 | Layer Two Tunneling Protocol (L2TP) | | | | | | 4 | Ascend Tunnel Management Protocol (ATMP) | | | | | | 5 | Virtual Tunneling Protocol (VTP) | | | | | | 6 | IP Authentication Header in the Tunnel-mode (AH) | | | | | | 7 | IP-in-IP Encapsulation (IP-IP) | | | | | | 8 | Minimal IP-in-IP Encapsulation (MIN-IP-IP) | | | | | | 9 | IP Encapsulating Security Payload in the Tunnel-mode (ESP) | | | | | | 10 | Generic Route Encapsulation (GRE) | | | | | | 11 | Bay Dial Virtual Services (DVS) | | | | | | 12 | IP-in-IP Tunneling | | | | | | 13 | Virtual LAN | | | | | | Tunnel-Medium-Type | 0 (standard) | 65 | | Value | Description | | --------: | :-------------------------------------------------------------- | | 1 | IPv4 (IP version 4) | | 2 | IPv6 (IP version 6) | | 3 | NSAP | | 4 | HDLC (8-bit multidrop) | | 5 | BBN 1822 | | 6 | 802 (includes all 802 media plus Ethernet "canonical format") | | 7 | E.163 (POTS) | | 8 | E.164 (SMDS, Frame Relay, ATM) | | 9 | F.69 (Telex) | | 10 | X.121 (X.25, Frame Relay) | | 11 | IPX | | 12 | Appletalk | | 13 | Decnet IV | | 14 | Banyan Vines | | 15 | E.164 with NSAP format subaddress | | Value | Description | | Value | Description | | | | | | 1 | IPv4 (IP version 4) | | | | | | 2 | IPv6 (IP version 6) | | | | | | 3 | NSAP | | | | | | 4 | HDLC (8-bit multidrop) | | | | | | 5 | BBN 1822 | | | | | | 6 | 802 (includes all 802 media plus Ethernet "canonical format") | | | | | | 7 | E.163 (POTS) | | | | | | 8 | E.164 (SMDS, Frame Relay, ATM) | | | | | | 9 | F.69 (Telex) | | | | | | 10 | X.121 (X.25, Frame Relay) | | | | | | 11 | IPX | | | | | | 12 | Appletalk | | | | | | 13 | Decnet IV | | | | | | 14 | Banyan Vines | | | | | | 15 | E.164 with NSAP format subaddress | | | | | | Tunnel-Private-Group-ID | 0 (standard) | 81 | string | Access-Accept | [RFC2868 section 3.6](https://tools.ietf.org/html/rfc2868#section-3.6) | | Framed-Pool | 0 (standard) | 88 | string | Access-Accept | [RFC2869 section 5.18](https://tools.ietf.org/html/rfc2869#section-5.18) | | Framed-IPv6-Prefix | 0 (standard) | 97 | ipv6 prefix | Access-Accept | [RFC3162 section 2.3](https://tools.ietf.org/html/rfc3162#section-2.3) | | Framed-IPv6-Pool | 0 (standard) | 100 | string | Access-Accept | [RFC3162 section 2.6](https://tools.ietf.org/html/rfc3162#section-2.6) | | Delegated-IPv6-Prefix | 0 (standard) | 123 | ipv6 prefix | Access-Accept | [RFC4818](https://tools.ietf.org/html/rfc4818) | | Framed-IPv6-Address | 0 (standard) | 168 | ip address | Access-Accept | [RFC6911 section 3.1](https://tools.ietf.org/html/rfc6911#section-3.1) | | Mikrotik-Recv-Limit | 14988 (Mikrotik) | 1 | integer | Access-Accept | Total receive limit in bytes for the client. | | Mikrotik-Xmit-Limit | 14988 (Mikrotik) | 2 | integer | Access-Accept | Total transmit limit in bytes for the client. | | Mikrotik-Group | 14988 (Mikrotik) | 3 | string | Access-Accept | User's group for local users. HotSpot profile for HotSpot users. PPP profile for PPP users. | | Mikrotik-Wireless-Forward | 14988 (Mikrotik) | 4 | integer | Access-Accept | Does not forward the client's frames back to the wireless infrastructure if this attribute is set to "0" (wireless only). | | Mikrotik-Wireless-Skip-Dot1x | 14988 (Mikrotik) | 5 | integer | Access-Accept | Disables 802.1x authentication for the particular wireless client if set to a non-zero value (wireless only). | | Mikrotik-Wireless-Enc-Algo | 14988 (Mikrotik) | 6 | | Value | Description | | --------: | :-------------- | | 0 | No-encryption | | 1 | 40-bit-WEP | | 2 | 104-bit-WEP | | 3 | AES-CCM | | 4 | TKIP | | Value | Description | | Value | Description | | | | | | 0 | No-encryption | | | | | | 1 | 40-bit-WEP | | | | | | 2 | 104-bit-WEP | | | | | | 3 | AES-CCM | | | | | | 4 | TKIP | | | | | | Mikrotik-Wireless-Enc-Key | 14988 (Mikrotik) | 7 | string | Access-Accept | WEP encryption key for the client (wireless only). | | Mikrotik-Rate-Limit | 14988 (Mikrotik) | 8 | string | Access-Accept | Datarate limitation for clients. The format is: rx-rate[/tx-rate] [rx-burst-rate[/tx-burst-rate] [rx-burst-threshold[/tx-burst-threshold] [rx-burst-time[/tx-burst-time] [priority] [rx-rate-min[/tx-rate-min]]]] from the point of view of the router (so "rx" is client upload, and "tx" is client download). All rates should be numbers with optional 'k' (1,000s) or 'M' (1,000,000s). If the tx-rate is not specified, the rx-rate is used as the tx-rate too. The same goes for tx-burst-rate and tx-burst-threshold and tx-burst-time. If both rx-burst-threshold and tx-burst-threshold are not specified (but burst-rate is specified), rx-rate and tx-rate are used as burst thresholds. If both rx-burst-time and tx-burst-time are not specified, 1s is used as the default. Priority takes values 1..8, where 1 implies the highest priority, but 8 - the lowest. If rx-rate-min and tx-rate-min are not specified rx-rate and tx-rate values are used. The rx-rate-min and tx-rate-min values can not exceed rx-rate and tx-rate values. | | Mikrotik-Realm | 14988 (Mikrotik) | 9 | string | Access-Request | If it is set in /radius menu, it is included in every RADIUS request as the Mikrotik-Realm attribute. If it is not set, the same value is sent as in the MS-CHAP-Domain attribute (if MS-CHAP-Domain is missing, Realm is not included either). | | Mikrotik-Host-IP | 14988 (Mikrotik) | 10 | ip address | Access-Request | The IP address of the HotSpot client before Universal Client translation (the original IP address of the client). | | Mikrotik-Mark-Id | 14988 (Mikrotik) | 11 | string | Access-Accept | Firewall mangle chain name (HotSpot only). The MikroTik RADIUS client upon receiving this attribute creates a dynamic firewall mangle rule with action=jump chain=hotspot and jump-target equal to the attribute value. Mangle chain name can have suffixes .in or .out, which will install the rule only for incoming or outgoing traffic. Multiple Mark-id attributes can be provided, but only the last ones for incoming and outgoing are used. | | Mikrotik-Advertise-URL | 14988 (Mikrotik) | 12 | string | Access-Accept | The URL of the page with advertisements that should be displayed to clients. If this attribute is specified, advertisements are enabled automatically, including transparent proxy, even if they were explicitly disabled in the corresponding user profile. Multiple attribute instances may be sent by the RADIUS server to specify additional URLs which are chosen in a round-robin fashion. | | Mikrotik-Advertise-Interval | 14988 (Mikrotik) | 13 | integer | Access-Accept | The time interval between two adjacent advertisements. Multiple attribute instances may be sent by the RADIUS server to specify additional intervals. All interval values are treated as a list and are taken one by one for each successful advertisement. If the end of the list is reached, the last value is continued to be used. | | Mikrotik-Recv-Limit-Gigawords | 14988 (Mikrotik) | 14 | integer | Access-Accept | 4G (2^32) bytes of total receive limit (bits 32..63, when bits 0..31 are delivered in Mikrotik-Recv-Limit). | | Mikrotik-Xmit-Limit-Gigawords | 14988 (Mikrotik) | 15 | integer | Access-Accept | 4G (2^32) bytes of total transmit limit (bits 32..63, when bits 0..31 are delivered in Mikrotik-Xmit-Limit). | | Mikrotik-Wireless-PSK | 14988 (Mikrotik) | 16 | string | Access-Accept | | | Mikrotik-Total-Limit | 14988 (Mikrotik) | 17 | integer | Access-Accept | | | Mikrotik-Total-Limit-Gigawords | 14988 (Mikrotik) | 18 | integer | Access-Accept | | | Mikrotik-Address-List | 14988 (Mikrotik) | 19 | string | Access-Accept | | | Mikrotik-Wireless-MPKey | 14988 (Mikrotik) | 20 | string | Access-Accept | | | Mikrotik-Wireless-Comment | 14988 (Mikrotik) | 21 | string | Access-Accept | | | Mikrotik-Delegated-IPv6-Pool | 14988 (Mikrotik) | 22 | string | Access-Accept | The IPv6 pool used for Prefix Delegation. | | Mikrotik-DHCP-Option-Set | 14988 (Mikrotik) | 23 | string | Access-Accept | | | Mikrotik-DHCP-Option-Param-STR1 | 14988 (Mikrotik) | 24 | string | Access-Accept | | | Mikrotik-DHCP-Option-Param-STR2 | 14988 (Mikrotik) | 25 | string | Access-Accept | | | Mikrotik-Wireless-VLANID | 14988 (Mikrotik) | 26 | integer | Access-Accept | VLAN ID for the client (Wireless only). | | Mikrotik-Wireless-VLANIDtype | 14988 (Mikrotik) | 27 | | Value | Description | | --------: | :-------------- | | 0 | 802.1q | | 1 | 802.1ad | | Value | Description | | Value | Description | | | | | | 0 | 802.1q | | | | | | 1 | 802.1ad | | | | | | Mikrotik-Wireless-Minsignal | 14988 (Mikrotik) | 28 | string | Access-Accept | | | Mikrotik-Wireless-Maxsignal | 14988 (Mikrotik) | 29 | string | Access-Accept | | | Mikrotik-Switching-Filter | 14988 (Mikrotik) | 30 | string | Access-Accept | Allows creating dynamic switch rules when authenticating clients with dot1x server. | **Properties** | Property | Description | | :-- | :-- | | **name** (*string*; Default: ) | Name of the attribute. | | **packet-types** (*string*; Default: **access-accept**) | access-accept - use this attribute in RADIUS Access-Accept messagesaccess-challenge - use this attribute in RADIUS Access-Challenge messages | | **type-id** (*integer:1..255*; Default: ) | Attribute identification number from the specific vendor's attribute database. | | **value-type** (*string*; Default: ) | hexip-address - IPv4 or IPv6 IP addressip6-prefix - IPv6 prefixmacrostringuint32 | | **vendor-id** (*integer*; Default: **0**) | IANA-allocated specific enterprise identification number. | ## Database **Sub-menu:** `/user-manager/database` All RADIUS-related information is stored in a separate User Manager's database configurable under the "database" sub-menu. "Enabled" and "db-path" are the only parameters that are not stored in the User Manager's database and instead are stored in the main RouterOS configuration table, meaning that these parameters will be affected by the RouterOS configuration reset. The rest of the configuration, session, and payment data is stored in a separate SQLite database on the FLASH storage of the device. When performing any actions with databases, it is advised to make a backup before and after any activity. ### Properties | Property | Description | | :-- | :-- | | **db-path** (*string*; Default: ) | Path to the location where database files will be stored. | ### Read-only properties | Property | Description | | :-- | :-- | | **db-size** | The current size of the database. | | **free-disk-space** | Free space left on the disk where the database is stored. | ### Commands | Property | Description | | :-- | :-- | | **load** (*name*) | Restore a previously created backup file in .umb format. | | **migrate-legacy-db** (*database-path; overwrite*) | Convert the old User Manager (from RouterOS v6 or before) to the new standard. It is possible to overwrite the current database. | | **optimize-db** () | | | **save** (name; overwrite) | Save the current state of the User Manager database. | ## Limitations **Sub-menu:** `/user-manager/limitation` Limitations are used by Profiles and are linked together by Profile-Limitations. RADIUS accounting and Interim updates must be enabled to seamlessly switch between multiple limitations or disconnect active sessions when *download-limit*, *upload-limit* or *uptime-limit* is reached. To disconnect already active sessions from User Manager, *accept* must be set to *yes* on the RADIUS client side. If simultaneous session limits are not unlimited (shared-users) and it has reached the maximum allowed number, then the router will try to disconnect the older user session first. User-Manager attempts to disconnect an active session before a new user will be accepted (when the appropriate limit is set). That's why in such setups it is suggested to use 1s for `/radius/client/timeout`. :::danger IPsec service in RouterOS does not support rate limitations. ::: ## Properties | Property | Description | | :-- | :-- | | **comment** (*string*; Default: ) | Short description of the limitation. | | **download-limit** (*integer*; Default: **0**) | The total amount of traffic a user can download in Bytes. | | **name** (*string*; Default: ) | Unique name of the limitation. | | **rate-limit-burst-rx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-burst-threshold-rx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-burst-threshold-tx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-burst-time-rx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-burst-time-tx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-burst-tx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-min-rx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-min-tx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-priority** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-rx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **rate-limit-tx** () | Part of *MT-Rate-Limit* RADIUS attribute. Refer to [Queues#SimpleQueue](../firewall-and-quality-of-service/queues/index.md). | | **reset-counters-interval** (*hourly* \| *daily* \| *weekly* \| *monthly* \| *disabled*); Default: **disabled**) | The interval from *reset-counters-start-time* when all associated user statistics are cleared. | | **reset-counters-start-time** (*datetime*; Default: ) | Static date and time value from which *reset-counters-interval* is calculated. | | **transfer-limit** (*integer*; Default: **0**) | The total amount of aggregated (download+upload) traffic in Bytes. | | **upload-limit** (*integer*; Default: **0**) | The total amount of traffic a user can upload in Bytes. | | **uptime-limit** (*time*; Default: **00:00:00**) | The total amount of uptime during which a user can stay active. | ## Payments **Sub-menu:** `/user-manager/payment` Information about all received payments is available in this section. **Read-only properties** | Property | Description | | :-- | :-- | | **currency** (*string*) | The currency used in the transaction. | | **method** (*string*) | Service used for the transaction (currently PayPal only). | | **price** (*decimal*) | Amount paid by the user. | | **profile** (*profile*) | Name of the profile the user purchased. | | **trans-end** (*datetime*) | Date and time when the transaction ended. | | **trans-start** (*datetime*) | Date and time when the transaction started. | | **trans-status** (*string*) | Status of the transaction. Possible statuses - *started*, *pending*, *approved*, *declined*, *error*, *timeout*, *aborted*, *user approved*. Only *approved* should be considered as a complete transaction. | | **user** (*string*; Default: ) | Name of the user who performed the transaction. | | **user-message** (*string*; Default: ) | | ## Profiles **Sub-menu:** `/user-manager/profile` ### Properties | Property | Description | | :-- | :-- | | **comment** (*string*; Default: ) | Short description of the entry. | | **name** (*string*; Default: ) | Unique name of the profile. | | **name-for-users** (*string*; Default: ) | Name of the profile that will be shown for users on the Web page. | | **override-shared-users** (*decimal \| off \| unlimited*; Default: **off**) | Whether to allow multiple sessions with the same user name. This overrides the *shared-users* setting. | | **price** (*decimal*; Default: **0.00**) | | | **starts-when** (*assigned* \| *first-auth*; Default: **assigned**) | The time when the profile becomes active. *Assigned* - immediately when a User Profile entry is created. *First-auth* - upon first authentication request from the user. | | **validity** (*time \| unlimited*; Default: **unlimited**) | The total amount of time a user can use this profile. | ## Profile Limitations **Sub-menu:** `/user-manager/profile-limitation` The Profile-Limitations table links Limitations and Profiles together and defines their validity period. When multiple Limitations are assigned to the same Profile, a user must comply with all Limitations for the session to be established. This allows more complicated setups to be created, for example, separate monthly and daily bandwidth limits. ### Properties | Property | Description | | :-- | :-- | | **comment** (*string*; Default: ) | Short description of the entry. | | **from-time** (*time*; Default: **00:00:00**) | Time of day when the limitation should start. | | **limitation** (*limitation*; Default: ) | Name of an already created **Limitation**. | | **profile** (*profile*; Default: ) | Name of an already created **Profile**. | | **till-time** (*time*; Default: **23:59:59**) | Time of day when the limitation should end. | | **weekdays** (*day of week*; Default: **Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday**) | Days of the week when the limitation should be active. | ## Routers **Sub-menu:** `/user-manager/router` Here you can define NAS devices that can use User Manager as a RADIUS server. ### Properties | Property | Description | | :-- | :-- | | **coa-port** (*integer:1..65535*; Default: **3799**) | Port number of CoA (Change of Authorization) communication. | | **address** (*IP/IPv6***;** Default: ) | IP address of the RADIUS client. | | **comment** (*string*; Default: ) | Short description of the NAS. | | **disabled** (*yes \| no*; Default: **no**) | Controls whether the entry is currently active or not. | | **name** (*string*; Default: ) | Unique name of the RADIUS client. | | **protocol**(*radsec*\| *udp*;Default udp) | Protocol to use with the router. | | **shared-secret** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | Used to secure communication between a RADIUS server and a RADIUS client. | ### Commands | Property | Description | | :-- | :-- | | **reset-counters** () | Clears all statistics for a specific RADIUS client. | ## Sessions **Sub-menu:** `/user-manager/session` Sessions are logged only if accounting is enabled on the NAS. **Read-only properties** | Property | Description | | :-- | :-- | | **acct-session-id** (*string*) | Unique identification of the accounting session. | | **active** (*yes \| no*) | Whether the session is currently used. | | **calling-station-id** (*string*) | User's identifier, usually IP address or MAC address. | | **download** (*Bytes*) | Amount of traffic downloaded. | | **ended** (*datetime*) | Date and time when the session was closed. Empty for active sessions. | | **last-accounting-packet** (*datetime*) | Date and time when the last accounting update was received. | | **nas-ip-address** (*IP address*) | The IP address of the NAS. | | **nas-port-id** (*string*) | Identifier of the NAS port that is authenticating the user. | | **nas-port-type** (*string*) | The port type (*physical* or *virtual*) that is authenticating the user. | | **started** (*datetime*) | Date and time when the session was established. | | **status** (*list of statuses*) | Possible available statuses of a session: *start -* accounting message *Start* has been received, *stop -* accounting message *Stop* has been received, *interim - Interim update* has been received, *close-acked* - session is successfully closed, *expired.* | | **terminate-cause** (*string*) | The reason why the session was closed. | | **upload** (*Bytes*) | Amount of traffic uploaded. | | **uptime** (*time*) | Total logged uptime on the session. | | **user** (*string*) | Name of the user. | | **user-address** (*IP address*) | IP address provided to the user. | ## Settings **Sub-menu:** `/user-manager` **Properties** | Property | Description | | :-- | :-- | | **accounting-port** (*integer*; Default: **1813**) | Port to listen for RADIUS accounting requests. | | **authentication-port**(*integer*; Default: **1812**) | Port to listen for RADIUS authentication requests. | | ***certificate*** (*certificate*; Default: ) | Certificate for use in EAP TLS-type authentication methods. | | ***enabled*** (*yes \| no*; Default: **no**) | Whether the User Manager functionality is enabled. | | **radsec-certificate**(certificate; Default:) | Certificate for use with RadSec protocol. | | **use-profiles**(*yes \| no*; Default: **no**) | Whether to use **Profiles** and **Limitations**. When set to *no,* only **User** configuration is required to run User Manager. | ### Advanced **Sub-menu:** `/user-manager/advanced` **Properties** | Property | Description | | :-- | :-- | | **paypal-allow** (*yes \| no*; Default: **no**) | Whether to enable PayPal functionality for User Manager. | | **paypal-currency** (*string*; Default: **USD**) | The currency related to the *price* setting in which users will be billed. | | **paypal-password** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | The password of your PayPal API account. | | **paypal-signature** (*string*; Default: ) | The signature of your PayPal API account. | | **paypal-use-sandbox** (*yes \| no*; Default: **no**) | Whether to use PayPal's sandbox environment for testing purposes. | | **paypal-user** (*string*; Default: ) | The username of your PayPal API account. | | **web-private-password** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | Password for accessing the */um/PRIVATE/* section over HTTP. | | **web-private-username** (*string*; Default: ) | Username for accessing the */um/PRIVATE/* section over HTTP. | ## Users **Sub-menu:** `/user-manager/user` ### Properties | Property | Description | | :-- | :-- | | **attributes** (*array of attributes*; Default: ) | Custom set of **Attributes** with their values that will additionally be added to Access-Accept messages. | | **caller-id**(*string*; Default: ) | Allow user's authentication with a specific *Calling-Station-Id* value. | | **comment** (*string*; Default: ) | Short description of the user. | | **disabled** (*yes \| no*; Default: **no**) | Controls whether the user can be used or not. | | **group** (*group*; Default: **default**) | Name of the **Group** the user is associated to. | | **name** (*string*; Default: ) | Username for session authentication. | | **otp-secret** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | A one-time password token that is attached to the password. | | **password** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | The password of the user for session authentication. | | **shared-users** (*integer \| unlimited*; Default: **1**) | The total number of sessions the user can simultaneously establish. | ### Commands | Property | Description | | :-- | :-- | | **add-batch-users** () | The command can generate multiple user accounts based on various parameters. | | **generate-voucher** () | Generates a file based on *voucher-template* that can be presented to the end user. | | **monitor** () | Shows total statistics for a user. Stats include *total-uptime*, *total-download*, *total-upload*, *active-sessions*, *actual-profile*, *attributes-details*. | ## User Groups **Sub-menu:** `/user-manager/user/group` User groups define common characteristics of multiple users such as allowed authentication methods and RADIUS attributes. There are two groups already present in User Manager called *default* and *default-anonymous*. ### Properties | Property | Description | | :-- | :-- | | **attributes** (*array of attributes*; Default: ) | Custom set of **Attributes** with their values that will additionally be added to Access-Accept messages for users in this group. | | **comment** (*string*; Default: ) | Short description of the group. | | **inner-auths** (*list of auths*; Default: ) | List of allowed authentication methods for tunneled (outer) authentication methods. Supported inner authentication methods - *ttls-pap*, *ttls-chap*, *ttls-mschap1*, *ttls-mschap2*, *peap-mschap2*. | | **name** (*string*; Default: ) | Unique name of the group. | | **outer-auths** (*list of auths*; Default: ) | List of allowed authentication methods. Supported outer authentication methods - *pap*, *chap*, *mschap1*, *mschap2*, *eap-tls*, *eap-ttls*, *eap-peap*, *eap-mschap2*. | ## User Profiles **Sub-menu:** `/user-manager/user-profile` This menu assigns users a profile and tracks the status of the profile. A single user can have multiple profiles assigned; however, only one can be used at the same time. A user will seamlessly be switched to the next profile when the currently active profile expires without dropping the user's session. ### Properties | Property | Description | | :-- | :-- | | **profile** (*profile*; Default: ) | Name of the profile to assign to a user. | | **user**(*user*; Default: ) | Name of the user to use a particular profile. | ### Read-only properties | Property | Description | | :-- | :-- | | **end-time** (*datetime*) | Date and time the **User Profile** will expire. | | **state** (*running active* \| running \| *used*) | The current state of the **User Profile**. *Running active -* a currently used profile by the user. *Running* - a profile is ready to be used. *Used* - an expired profile that can no longer be activated. | ### Commands | Property | Description | | :-- | :-- | | **activate-user-profile** () | Makes a **User Profile** entry active immediately. | ## WEB Interface Each user has access to his personal profile using a WEB interface. The WEB interface can be accessed by adding the "/um/" directory to the router's IP or domain, for example, `http://example.com/um/`. Note that the WEB interface is affected by IP Services "www" and "www-ssl". The WEB interface can be customized using CSS, JavaScript, and HTML. ### Customizable file reference | File | Description | | :-- | :-- | | **css/login.css** | Cascading style sheet file used in the login prompt page. | | **css/user.css** | Cascading style sheet file used in user's profile page. | | **img/PayPal\_mark\_37x23.gif** | PayPal logo image. | | **img/ajax-loader.gif** | Loading gif while processing page switching. | | **img/mikrotik\_logo.png** | MikroTik logo that is displayed on all pages. | | **js/generic.js** | Javascript file used on all pages. | | **js/login.js** | Javascript file used in the login prompt page. | | **js/user.js** | Javascript file used in user's profile page. | | **user/login\_dynamic.html** | Layout of the login prompt page. | | **user/user\_dynamic.html** | Layout of the user's profile page. | ## Application Guides ### Batch user creation It is possible to create multiple new users with randomly generated usernames and passwords. For example, the following command will generate 3 new users with 6 lowercase symbols as the username and 6 lowercase letters, uppercase letters, and numbers as the password. ```ros /user-manager/user add-batch-users number-of-users=3 password-characters=lowercase,numbers,uppercase password-length=6 username-characters=lowercase username-length=6 ``` The command-generated users can be seen by printing the users table: ```ros /user-manager/user/print Flags: X - disabled 0 name="olsgkl" password="86a6zH" otp-secret="" group=default shared-users=1 attributes="" 1 name="lkbwss" password="jaKY5V" otp-secret="" group=default shared-users=1 attributes="" 2 name="cwxbwu" password="a62yZd" otp-secret="" group=default shared-users=1 attributes="" ``` ### Providing NAS with custom RADIUS attributes It is possible to send additional RADIUS attributes during the authentication process to provide NAS with custom information about the session, such as what IP address should be assigned to the supplicant or what address pool to use for address assignment. #### Static IP address for a user To assign the end user a static IP address, the *Framed-IP-Address* attribute can be used. When using static IP address allocation, *shared-sessions* must be set to 1 to prevent cases when a user has multiple simultaneous sessions, but there is only one IP address. For example: ```ros /user-manager/user set [find name=username] shared-users=1 attributes=Framed-IP-Address:192.168.1.4 ``` #### Specifying address pool for a group of users We can group up multiple similar users and assign RADIUS attributes to all of them at once. First of all, create a new group: ```ros /user-manager/user/group add name=location1 outer-auths=chap,eap-mschap2,eap-peap,eap-tls,eap-ttls,mschap1,mschap2,pap \ inner-auths=peap-mschap2,ttls-chap,ttls-mschap1,ttls-mschap2,ttls-pap attributes=Framed-Pool:pool1 ``` The next step is to assign a user to the group: ```ros /user-manager/user set [find name=username] group=location1 ``` In this case, an IP address from *pool1* will be assigned to the user upon authentication - make sure *pool1* is created on the NAS device. ### Using TOTP (time-based one-time password) for user authentication User Manager supports time-based authentication token addition to the user's password field that is regenerated every 30 seconds. :::danger OTP depends on the clock, so make sure time settings are configured correctly. ::: TOTP works by having a shared secret on the supplicant (client) and the authentication server (User Manager). To configure TOTP on RouterOS, simply set the *otp-secret* for the user. For example: ```ros /user-manager/user set [find name=username] password=mypass otp-secret=mysecret ``` To calculate the TOTP token on the supplicant side, many widely available applications can be used, for example, Google Authenticator or [https://totp.app/](https://totp.app/). Adding mysecret to the TOTP token generator will provide a new unique 6-digit code that must be added to the user password. ![](./img/user-manager-02.webp) The following example will accept the user's authentication with a calculated TOTP token added to the common password until a new TOTP token is generated. ```text User-Name=username User-Password=mypass620872 ``` ### Exporting user credentials #### **Printable login credentials for a single user** To generate a single user's printable voucher card, simply use the *generate-voucher* command. Specify the RouterOS ID number of the user or use the *find* command to specify a username. A template is already included in User Manager's installation available in the Files section of your device. You can customize the template for your needs. ```ros /user-manager/user generate-voucher voucher-template=printable_vouchers.html [find where name=username] ``` The generated voucher card is available by accessing the router using a WEB browser and navigating to */um/PRIVATE/GENERATED/vouchers/gen\_printable\_vouchers.html* By default, the printable card looks like this: ![](./img/user-manager-03.webp) :::warning To access the PRIVATE path of the /um/ directory by the WEB browser, *private-username* and *private-password* must be configured. See **Settings** section. ::: It is possible to use different variables when generating vouchers. Currently, supported variables are: $(username) - Represents the User Manager username $(password) - Password of the username $(userprofname) - Profile that is active for the particular user $(userprofendtime) - Profile validity end time if specified #### Multiple user credential export It is possible to generate a CSV or XML file with multiple or all user credentials at once by using the *export.xml* or *export.csv* as a *voucher-template*. ```ros /user-manager/user generate-voucher voucher-template=export.xml [find] ``` The command generates an XML file *um5files/PRIVATE/GENERATED/vouchers/gen\_export.xml* which can either be accessible by the WEB browser or by any other file access tools. ```text olsgkl 86a6zH lkbwss jaKY5V cwxbwu a62yZd username secretpassword ``` ### Generating usage report In cases where presentable network usage information is required by company's billing or legal team, an automated session export can be created using the *generate-report* command. The command requires an input of the report template - an example of the template is available in *um5files/PRIVATE/TEMPLATES/reports/report\_default.html*. Example of the report generation: ```ros /user-manager generate-report report-template=report_default.html columns=username,uptime,download,upload ``` The generated report is available by accessing the router using a WEB browser and navigating to */um/PRIVATE/GENERATED/reports/gen\_report\_default.html* *![](./img/user-manager-04.webp)* ### Purchasing a profile After logging into the user's private profile by accessing the router's */um/* directory using a WEB browser, for example, http://example.com/um/, he will be able to see all available **Profiles** in the respective menu. Profiles that have specified *price* values will have a *Buy this Profile* button available. ![](./img/user-manager-05.webp) After pressing the *Buy this Profile* button, the user will be asked to choose from available transaction service providers (currently only PayPal is available) and later redirected to PayPal's payment processing page. ![](./img/user-manager-06.webp) When the payment is completed, the User Manager will ask PayPal to approve the transaction. After approval, the profile is assigned to the user and is ready to use.![](./img/user-manager-07.webp) ### Migrating from RouterOS v6 When you upgrade your User Manager router from RouterOS v6 to the v7, the new User Manager will work with new database files and configuration. To continue using the old user, router, profile, etc. configuration, you must manually execute the migrate command. To do so you must have files from the old User Manager server folder "user-manager" present. The folder can be renamed, but all the contents from the old installation must be transferred to the new v7 installation (you can move the old configuration from one router to another router with v7, but you must copy the "user-manager" folder). After that, all you need to do is execute this command - `/user-manager/database/migrate-legacy-db database-path=`. The import process will try to convert such configuration - users, profiles, user-profiles, limitations, profile-limitations, user-counters, routers, and sessions. ## Application Examples ### Basic L2TP/IPsec server with User Manager authentication ![](./img/user-manager-08.webp) #### User Manager configuration Start off by enabling User Manager functionality. ```ros /user-manager set enabled=yes ``` Allow receiving RADIUS requests from localhost (the router itself). ```ros /user-manager/router add address=127.0.0.1 comment=localhost name=local shared-secret=test ``` Next, add users and their credentials that clients will use to authenticate to the server. ```ros /user-manager/user add name=user1 password=password ``` #### Configuring RADIUS client For the router to use the RADIUS server for user authentication, it is required to add a new RADIUS client that has the same shared secret that we already configured on User Manager. ```ros /radius add address=127.0.0.1 secret=test service=ipsec ``` #### L2TP/IPsec server configuration Configure the IP pool from which IP addresses will be assigned to the users and assign it to the PPP Profile. ```ros /ip/pool add name=vpn-pool range=192.168.99.2-192.168.99.100 /ppp/profile set default-encryption local-address=192.168.99.1 remote-address=vpn-pool ``` Enable the use of RADIUS for PPP authentication. ```ros /ppp/aaa set use-radius=yes ``` Enable the L2TP server with IPsec encryption. ```ros /interface/l2tp-server/server set enabled=yes use-ipsec=required ipsec-secret=mySecret ``` That is it. Your router is now ready to accept L2TP/IPsec connections and authenticate them to the internal User Manager. ### Two factor authentication for RouterOS user login (MFA/2FA) As User-Manager supports TOTP (time-based-one-time password), it is possible to setup so-called MFA authentication for different services. Here we will look into RouterOS user authentication over User Manager (radius) with time-based password that is changed every 30 seconds. **Here are the necessary configuration options on your MikroTik router.** Enable use of RADIUS for /user menu, and set default-group from `/user/group` menu. Keep in mind that local /user database is checked first, and then RADIUS is contacted. ``` /user/aaa/set use-radius=yes default-group=full ``` Enable the radius client for the login service. As we run User Manager on the same router, 127.0.0.1 is used, ``` /radius/add address=127.0.0.1 service=login secret=mystrongsecret ``` **Here are the configuration steps for User Manager**, Make sure you have added your managed devices to the "Routers" menu, ``` /user-manager/router/add name=myrouter address=127.0.0.1 shared-secret=mystrongsecret ``` Add a user to the User-Manager user table with OTP secret parameter. A few more steps are required for proper OTP configuration. Pick an OTP-secret name and convert it to base32 format (there are plenty of online converters from utf-8 to base32 format). For my configuration, I use "mysupersecret", which in base32 would be NV4XG5LQMVZHGZLDOJSXI=== ``` /user-manager/user/add name=mikrotik password=mysuperpassword otp-secret="NV4XG5LQMVZHGZLDOJSXI===" ``` Note that in your favorite authenticator app, you will need to set this key for the user manually "NV4XG5LQMVZHGZLDOJSXI===", when adding a new time password instance. To login to your MikroTik device, open Winbox/Console and connect to your router address, and use login:mikrotik and password:mysuperpasswordxxxxxx, where xxxxxx is a 6 digit code from your favorite authentication app. The password is changed every 30 seconds and it is available from your favorite app. ![](./img/user-manager-qr-code.jpg) --- ## User ## Summary MikroTik RouterOS router user facility manages the users connecting to the router from any of the Management tools. The users are authenticated using either a local database or a designated RADIUS server. Each user is assigned to a user group, which denotes the rights of this user. A group policy is a combination of individual policy items. In case the user authentication is performed using RADIUS, the [RADIUS](./radius.md) client should be previously configured. ## User Settings The settings submenu allows controlling the password complexity requirements of the router users. | Property | Description | | :-- | :-- | | **minimum-password-length** (*integer*; 0..4294967295; Default: ) | Specifies the minimum character length of the user password | | **minimum-categories** (*integer*; 0..4; Default: ) | Specifies the complexity requirements of the password, with categories being *uppercase, lowercase, digit, symbol.* | ## User Groups The router user groups provide a convenient way to assign different permissions and access rights to different user classes. ### Properties | Property | Description | | :-- | :-- | | **name** (*string*; Default: ) | The name of the user group | | **policy** (*local \| telnet \| ssh \| ftp \| reboot \| read \| write \| policy \| test \| winbox \| password \| web \| sniff \| sensitive \| api \| rest-api \| romon*; Default: **none**) | List of allowed policies: Login policies: local - policy that grants rights to log in locally via consoletelnet - policy that grants rights to log in remotely via telnetssh - policy that grants rights to log in remotely via secure shell protocolweb - policy that grants rights to log in remotely via WebFig.winbox - policy that grants rights to log in remotely via WinBox and bandwidth test authenticationpassword - policy that grants rights to change the password for currently logged in user (own password) api - grants rights to access the router via API.rest-api - grants rights to access the router via REST API.ftp - policy that grants full rights to log in remotely via FTP. Allows reading/writing/erasing files and to transfer files from/to the router. Should be used together with read/write policies.romon - policy that grants rights to connect to the RoMon server. Config Policies: reboot - policy that allows rebooting the routerread - policy that grants read access to the router's configuration. All console commands that do not alter the router's configuration are allowed. Doesn't affect FTPwrite - policy that grants write access to the router's configuration, except for user management. This policy does not allow reading the configuration, so make sure to enable read policy as wellpolicy - policy that grants user management rights. Should be used together with the write policy. Also allows seeing global variables created by other users (requires also 'test' policy). Allows designing skins (requires also "sensitive" policy).test - policy that grants rights to run ping, traceroute, bandwidth-test, wireless scan, snooper, fetch, email and other test commandssensitive - grants rights to change the "hide sensitive" option, if this policy is disabled sensitive information is not displayed.sniff - policy that grants rights to use the packet sniffer tool, torch tool, traffic generator. | | **skin** (*name*; Default: **default**) | The skin used for WebFig | ### Default groups There are three default system groups which cannot be deleted: ```ros [admin@MikroTik] > /user/group/print 0 name="read" policy=local,telnet,ssh,reboot,read,test,winbox,password,web,sniff,sensitive,api,romon,rest-api,!ftp,!write,!policy skin=default 1 name="write" policy=local,telnet,ssh,reboot,read,write,test,winbox,password,web,sniff,sensitive,api,romon,rest-api,!ftp,!policy skin=default 2 name="full" policy=local,telnet,ssh,ftp,reboot,read,write,policy,test,winbox,password,web,sniff,sensitive,api,romon,rest-api skin=default ``` Please note, that even the "*read*" group includes *sensitive*, *reboot,* and other important policies, meaning that this group should not be given to untrusted users. For truly limited groups, make a custom group, defining specific policies. All groups have access to file operations. The exclamation sign '!' just before the policy item name means NOT. ## Router Users The router user database stores information such as username, password, allowed access addresses, and group, about router management personnel. ### Properties | Property | Description | | :-- | :-- | | **address** (*IP/mask \| IPv6 prefix*; Default: ) | Host or network address from which the user is allowed to log in | | **group** (*string*; Default: ) | Name of the group the user belongs to | | **inactivity-policy** (*lockscreen* \| *logout* \| *none*; Default: ***none***) | Specifies inactivity action - logout (the user will be logged out) or lockscreen (the session will be locked, requiring password input to continue). Works only for CLI sessions. | | **inactivity-timeout** (*time*; Default: ***10min***) | Specifies time after which the user will be logged out or the session will be locked. Minimal timeout - 1 minute, maximal timeout - 24 hours. Works only for CLI sessions. | | **name** (*string*; Default: ) | User name. Must start and end with an alphanumeric character but can include "\_", ".", "#", "-", and "@" symbols. However, the "\*" symbol is prohibited in the user name. | | **password** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | User password. If not specified, it is left blank (hit Enter when logging in). It conforms to standard Unix characteristics of passwords and may contain letters, digits, "\*" and "\_" symbols. | | **last-logged-in** (*time and date*; Default: **""**) | Read-only field. Last time and date when a user logged in. | ### Actions Actions for an existing router user. | Action | Description | | :-- | :-- | | **password** | Option to change the user password. | | **expire-password** | Expires the user password, on the next login, the router will prompt to change the password. | ### Notes There is one predefined user with full access rights: ```ros [admin@MikroTik] /user> print Flags: X - disabled # NAME GROUP ADDRESS LAST-LOGGED-IN 0 ;;; system default user admin full 0.0.0.0/0 2010-12-08 16:19:24 ``` There always should be at least one user with full access rights. If the user with full access rights is the only one, it cannot be removed. ## Monitoring Active Users ```ros /user/active/print ``` The command shows the currently active users along with respective statistics information. ### Properties All properties are read-only. | Property | Description | | :-- | :-- | | **address** (*IP/IPv6 address/MAC address*) | Host IP/IPv6/MAC address from which the user is accessing the router. | | **group** (*string*) | A group that the user belongs to. | | **name** (*string*) | Username. | | **radius** (*true \| false*) | Whether a user is authenticated by the RADIUS server. | | **via** (*telnet \| ssh \| winbox \| api \| rest-api \| web \| ftp* ) | User's access method | | **by-romon**(MAC address) | RoMON agent MAC address | | **when** (*time*) | Time and date when the user logged in. | ### Request logout It is possible to close an active session using the request logout function. ```routeros /user/active/request-logout ACTIVE_USER_SESSION_NUMBER ``` ## Remote AAA Router user remote AAA enables router user authentication and accounting via a RADIUS server. The RADIUS user database is consulted only if the required username is not found in the local user database. ### Properties | Property | Description | | :-- | :-- | | **accounting** (*yes \| no*; Default: **yes**) | If the RADIUS server should be sent accounting for login, logout. Bandwidth usage statistics are not part of `/user` accounting | | **exclude-groups** (*list of group names*; Default: ) | Exclude-groups consist of the groups that should not be allowed to be used for users authenticated by radius. If the radius server provides a group specified in this list, the default-group will be used instead. This is to protect against privilege escalation when one user (without policy permission) can change the radius server list, set up their own radius server and log in as admin. | | **default-group** (*string*; Default: **read**) | User group used by default for users authenticated via a RADIUS server. | | **interim-update** (*time*; Default: **0s**) | Interim-Update time interval | | **use-radius** (*yes \|no*; Default: **no**) | Enable user authentication via RADIUS | :::info If you are using RADIUS, you need to have CHAP support enabled in the RADIUS server for WinBox to work. ::: ## SSH Keys This menu allows importing of private and public keys used for SSH authentication. :::warning By default, the user is not allowed to log in via SSH by password if an SSH key for the user is added. For more details see the [SSH](../management-tools/ssh.md) page. ::: ### Public keys This menu is used to import (or add) and list imported public keys. Public keys are used to approve another device's identity when logging into a router using an SSH key. :::info RSA, Ed25519 and Ed25519-sk keys are supported in PEM, PKCS#8, or OpenSSH format. ::: | Property | Description | | :-- | :-- | | **user** (read-only*)* | system user to which the SSH key has been assigned | | **info** (read-only*)* | key info | | **key-type** (read-only*)* | key type | | **bits** (read-only*)* | key length | | **fingerprint** (read-only*)* | key fingerprint in SHA256 (Base64) format | #### Import public SSH key On public SSH key import, you must specify the key file, the system user to which SSH key will be assigned, optionally, it is possible to specify the key owner. | Property | Description | | :-- | :-- | | **user** (*string*; Default: ) | system user to which the SSH key has been assigned | | **key-owner** (*string*) | SSH key owner | | **public-key-file** (*string*) | file name in the router's root directory containing the public key | #### Add public SSH key It is possible to *add* a public SSH key (pasting the SSH key string), you must provide the key string, and the system user to which the SSH key has been assigned. :::note It is possible to *add* keys only in OpenSSH format ::: | Property | Description | | :-- | :-- | | **user** (*string*; Default: ) | system user to which the SSH key has been assigned | | **key** (*string*) | public key | ### Private keys This menu is used to import and list imported private keys. Private keys are used to approve the router's identity during login to another device using an SSH key. On private key import, it is possible to specify key-owner. :::info RSA and Ed25519 keys are supported in PEM or PKCS#8 format. ::: | Property | Description | | :-- | :-- | | **user** (*string*; Default: ) | system user to which the SSH key has been assigned | | **key-owner** (*string*) | SSH key owner | | **key-type** (read-only*)* | key type | | **bits** (read-only*)* | key length | #### Import private SSH key On private SSH key import, you must specify key file, system user to which SSH key will be assigned, optionally it is possible to provide key passphrase and specify key owner. | Property | Description | | :-- | :-- | | **user** (*string*; Default: ) | system user to which the SSH key has been assigned | | **key-owner** (*string*) | SSH key owner | | **passphrase** *(string) [sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | key file passphrase | | **private-key-file** (*string*) | file name in the router's root directory containing the private key | --- ## CRS1xx and 2xx series switches --- The Cloud Router Switch series is highly integrated switches with a high-performance MIPS CPU and feature-rich packet processors. The CRS switches can be designed into various Ethernet applications including unmanaged switch, Layer 2 managed switch, carrier switch, and wireless/wired unified packet processing. See [Cloud Router Switch](./user-guides/crs1xx-2xx-series-switches-examples.md) configuration examples. :::danger This article applies to CRS1xx and CRS2xx series switches and not to MikroTik devices with Marvell Prestera switch (e.g. CRS3xx). For MikroTik devices with Marvell Prestera switch, see the [Marvell Prestera switch chip features](./marvell-prestera-switch-chip-features.md) manual. ::: | Features | Description | | :-- | :-- | | **Forwarding** | Configurable ports for switching or routingFull non-blocking wire-speed switchingUp to 16k MAC entries in Unicast FDB for Layer 2 unicast forwardingUp to 1k MAC entries in Multicast FDB for multicast forwardingUp to 256 MAC entries in Reserved FDB for control and management purposesAll Forwarding Databases support IVL and SVLConfigurable Port-based MAC learning limitJumbo frame support (CRS1xx/2xx: 9204 Bytes; CRS125/CRS109: 4064 Bytes)IGMP Snooping support | | **Mirroring** | Various types of mirroring:Port-based mirroringVLAN-based mirroringMAC-based mirroring2 independent mirroring analyzer ports | | **VLAN** | Fully compatible with IEEE802.1Q and IEEE802.1ad VLAN4k active VLANsFlexible VLAN assignment:Port-based VLANProtocol-based VLANMAC-based VLANFrom any to any VLAN translation and swapping1:1 VLAN switching - VLAN to port mappingVLAN filtering | | **Port Isolation and Leakage** | Applicable for Private VLAN implementation3 port profile types: Promiscuous, Isolated, and CommunityUp to 28 Community profilesLeakage profiles allow bypassing egress VLAN filtering | | **Trunking** | Supports static link aggregation groupsUp to 8 Port Trunk groupsUp to 8 member ports per Port Trunk groupHardware automatic failover and load balancing | | **Quality of Service (QoS)** | Flexible QoS classification and assignment:Port-basedMAC-basedVLAN-basedProtocol-basedPCP/DEI basedDSCP basedACL basedQoS remarking and remapping for QoS domain translation between a service provider and client networksOverriding of each QoS assignment according to the configured priority | | **Shaping and Scheduling** | 8 queues on each physical portShaping per port, per queue, per queue group | | **Access Control List** | Ingress and Egress ACL tablesUp to 128 ACL rules (limited by RouterOS)Classification based on ports, L2, L3, L4 protocol header fieldsACL actions include filtering, forwarding, and modifying the protocol header fields | ## Cloud Router Switch models --- This table clarifies the main differences between Cloud Router Switch models. | | | | | | | | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | **Model** | **Switch Chip** | **CPU** | **Wireless** | **SFP+ port** | **Access Control List** | **Jumbo Frame (Bytes)** | | **CRS105-5S-FB** | QCA-8511 | 400MHz | - | - | + | 9204 | | **CRS106-1C-5S** | QCA-8511 | 400MHz | - | - | + | 9204 | | **CRS112-8G-4S** | QCA-8511 | 400MHz | - | - | + | 9204 | | **CRS210-8G-2S+** | QCA-8519 | 400MHz | - | + | + | 9204 | | **CRS212-1G-10S-1S+** | QCA-8519 | 400MHz | - | + | + | 9204 | | **CRS226-24G-2S+** | QCA-8519 | 400MHz | - | + | + | 9204 | | **CRS125-24G-1S** | QCA-8513L | 600MHz | - | - | - | 4064 | | **CRS125-24G-1S-2HnD** | QCA-8513L | 600MHz | + | - | - | 4064 | | **CRS109-8G-1S-2HnD** | QCA-8513L | 600MHz | + | - | - | 4064 | ## Abbreviations and Explanations --- CVID - Customer VLAN id: inner VLAN tag id of the IEEE 802.1ad frame SVID - Service VLAN id: outer VLAN tag id of the IEEE 802.1ad frame IVL - Independent VLAN learning - learning/lookup is based on both MAC addresses and VLAN IDs. SVL - Shared VLAN learning - learning/lookup is based on MAC addresses - not on VLAN IDs. TPID - Tag Protocol Identifier PCP - Priority Code Point: a 3-bit field which refers to the IEEE 802.1p priority DEI - Drop Eligible Indicator DSCP - Differentiated Services Code Point Drop precedence - an internal CRS switch QoS attribute used for packet enqueuing or dropping. ## Port Switching --- To set up port switching on CRS1xx/2xx series switches, check the [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) page. :::warning Dynamic reserved VLAN entries (VLAN4091; VLAN4090; VLAN4089; etc.) are created in the CRS switch when switched port groups are added when a hardware offloaded bridge is created. These VLANs are necessary for internal operation and have lower precedence than user-configured VLANs. ::: ### Multiple switch groups The CRS1xx/2xx series switches allow you to use multiple bridges with hardware offloading; this allows you to easily isolate multiple switch groups. This can be done by simply creating multiple bridges and enabling hardware offloading. :::warning Multiple hardware offloaded bridge configuration is designed as a fast and simple port isolation solution, but it limits a part of the VLAN functionality supported by the CRS switch chip. For advanced configurations use one bridge within the CRS switch chip for all ports, configure VLANs, and isolate port groups with port isolation profile configuration. ::: :::danger CRS1xx/2xx series switches can run multiple hardware offloaded bridges with (R)STP enabled, but it is not recommended since the device is not designed to run multiple (R)STP instances on a hardware level. To isolate multiple switch groups and have (R)STP enabled you should isolate port groups with port isolation profile configuration. ::: ## Global Settings --- The CRS switch chip is configurable from the `/interface/ethernet/switch` console menu. **Sub-menu:** `/interface/ethernet/switch` | Property | Description | | :-- | :-- | | **name** (*string value*; Default: **switch1**) | Name of the switch. | | **bridge-type** (*customer-vid-used-as-lookup-vid \| service-vid-used-as-lookup-vid*; Default: **customer-vid-used-as-lookup-vid**) | The bridge type defines which VLAN tag is used as Lookup-VID. Lookup-VID serves as the VLAN key for all VLAN-based lookups. | | **mac-level-isolation** (*yes \| no*; Default: **yes**) | Globally enables or disables MAC level isolation. Once enabled, the switch will check the source and destination MAC address entries and their `isolation-profile` from the unicast forwarding table. By default, the switch will learn MAC addresses and place them into a `promiscuous` isolation profile. Other isolation profiles can be used when creating static unicast entries. If the source or destination MAC address is located on a `promiscuous` isolation profile, the packet is forwarded. If both source and destination MAC addresses are located on the same `community1` or `community2` isolation profile, the packet is forwarded. The packet is dropped when the source and destination MAC address isolation profile is `isolated`, or when the source and destination MAC address isolation profiles are from different communities (e.g. source MAC address is `community1` and destination MAC address is `community2`). When MAC level isolation is globally disabled, the isolation is bypassed. | | **use-svid-in-one2one-vlan-lookup** (*yes \| no*; Default: **no**) | Whether to use service VLAN ID for 1:1 VLAN switching lookup. | | **use-cvid-in-one2one-vlan-lookup** (*yes \| no*; Default: **yes**) | Whether to use customer VLAN ID for 1:1 VLAN switching lookup. | | **multicast-lookup-mode** (*dst-ip-and-vid-for-ipv4 \| dst-mac-and-vid-always*; Default:**dst-ip-and-vid-for-ipv4**) | Lookup mode for IPv4 multicast bridging.dst-mac-and-vid-always - For all packet types, the lookup key is the destination MAC and VLAN ID.dst-ip-and-vid-for-ipv4 - For IPv4 packets, the lookup key is the destination IP and VLAN ID. For other packet types, the lookup key is the destination MAC and VLAN ID. | | **unicast-fdb-timeout** (*time interval*; Default: **5m**) | Timeout for Unicast FDB entries. | | **override-existing-when-ufdb-full** (*yes \| no*; Default: **no**) | Enable or disable overriding an existing entry which has the lowest aging value when UFDB is full. | | Property | Description | | :-- | :-- | | **drop-if-no-vlan-assignment-on-ports** (*ports*; Default: **none**) | Ports which drop frames if no MAC-based, Protocol-based VLAN assignment or Ingress VLAN Translation is applied. | | **drop-if-invalid-or-src-port- -not-member-of-vlan-on-ports** (*ports*; Default: **none**) | Ports that drop invalid and other port VLAN ID frames. | | **unknown-vlan-lookup-mode** (*ivl \| svl*; Default: **svl**) | Lookup and learning mode for packets with an invalid VLAN. | | **forward-unknown-vlan** (*yes \| no*; Default: **yes**) | Whether to allow forwarding VLANs that are not members of the VLAN table. | | Property | Description | | :-- | :-- | | **bypass-vlan-ingress-filter-for** (*protocols*; Default: **none**) | Protocols that are excluded from Ingress VLAN filtering. These protocols are not dropped if they have an invalid VLAN. (arp, dhcpv4, dhcpv6, eapol, igmp, mld, nd, pppoe-discovery, ripv1) | | **bypass-ingress-port-policing-for** (*protocols*; Default: **none**) | Protocols that are excluded from Ingress Port Policing. (arp, dhcpv4, dhcpv6, eapol, igmp, mld, nd, pppoe-discovery, ripv1) | | **bypass-l2-security-check-filter-for** (*protocols*; Default: **none**) | Protocols that are excluded from Policy rule security check. (arp, dhcpv4, dhcpv6, eapol, igmp, mld, nd, pppoe-discovery, ripv1) | | Property | Description | | :-- | :-- | | **ingress-mirror0** (*port \| trunk,format*; Default: **none,modified**) | The first ingress mirroring analyzer port or trunk and mirroring format:analyzer-configured - The packet is the same as the packet to the destination. VLAN format is modified based on the VLAN configurations of the analyzer port.modified - The packet is the same as the packet to the destination. VLAN format is modified based on the VLAN configurations of the egress port.original - Traffic is mirrored without any change to the original incoming packet format. But the service VLAN tag is stripped in the edge port. | | **ingress-mirror1** (*port \| trunk,format*; Default: **none,modified**) | The second ingress mirroring analyzer port or trunk and mirroring format:analyzer-configured - The packet is the same as the packet to the destination. VLAN format is modified based on the VLAN configurations of the analyzer port.modified - The packet is the same as the packet to the destination. VLAN format is modified based on the VLAN configurations of the egress port.original - Traffic is mirrored without any change to the original incoming packet format. But the service VLAN tag is stripped in the edge port. | | **ingress-mirror-ratio** (*1/32768..1/1*; Default: **1/1**) | The proportion of ingress mirrored packets compared to all packets. | | **egress-mirror0** (*port \| trunk,format*; Default: **none,modified**) | The first egress mirroring analyzer port or trunk and mirroring format:analyzer-configured - The packet is the same as the packet to the destination. VLAN format is modified based on the VLAN configurations of the analyzer port.modified - The packet is the same as the packet to the destination. VLAN format is modified based on the VLAN configurations of the egress port.original - Traffic is mirrored without any change to the original incoming packet format. But the service VLAN tag is stripped in the edge port. | | **egress-mirror1** (*port \| trunk,format*; Default: **none,modified**) | The second egress mirroring analyzer port or trunk and mirroring format:analyzer-configured - The packet is the same as the packet to the destination. VLAN format is modified based on the VLAN configurations of the analyzer port.modified - The packet is the same as the packet to the destination. VLAN format is modified based on the VLAN configurations of the egress port.original - Traffic is mirrored without any change to the original incoming packet format. But the service VLAN tag is stripped in the edge port. | | **egress-mirror-ratio** (*1/32768..1/1*; Default: **1/1**) | The proportion of egress mirrored packets compared to all packets. | | **mirror-egress-if-ingress-mirrored** (*yes \| no*; Default: **no**) | When a packet is applied to both ingress and egress mirroring, only ingress mirroring is performed on the packet, if this setting is disabled. If this setting is enabled, both mirroring types are applied. | | **mirror-tx-on-mirror-port** (*yes \| no*; Default: **no**) | | | **mirrored-packet-qos-priority** (*0..7*; Default: **0**) | Remarked priority in mirrored packets. | | **mirrored-packet-drop-precedence** (*drop \| green \| red \| yellow*; Default: **green**) | Remarked drop precedence in mirrored packets. This QoS attribute is used for mirrored packet enqueuing or dropping. | | **fdb-uses** (*mirror0 \| mirror1*; Default: **mirror0**) | Analyzer port used for FDB-based mirroring. | | **vlan-uses** (*mirror0 \| mirror1*; Default: **mirror0**) | Analyzer port used for VLAN-based mirroring. | ## Port Settings --- **Sub-menu:** `/interface/ethernet/switch/port` | Property | Description | | :-- | :-- | | **vlan-type** (*edge-port \| network-port*; Default: **network-port**) | Port VLAN type specifies whether VLAN ID is used in UFDB learning. The network port learns VLAN ID in UFDB, edge port does not - VLAN 0. It can be observed only in IVL learning mode. | | **isolation-leakage-profile-override** (*yes \| no*; Default: **!isolation-leakage-profile-override**) **isolation-leakage-profile** (*0..31*;) | Custom port profile for port isolation/leakage configurations.Port-level isolation profile 0. Uplink port - allows the port to communicate with all ports in the device.Port-level isolation profile 1. Isolated port - allows the port to communicate only with uplink ports.Port-level isolation profile 2 - 31. Community port - allows communication among the same community ports and uplink ports. | | **learn-override** (*yes \| no*; Default: **!learn-override**) **learn-limit** (*1..1023*; Default: **!learn-limit**) | Enable or disable MAC address learning and set the MAC limit on the port. MAC learning limit is disabled by default when !learn-override and !learn-limit are set. The property learn-override is replaced with learn under the `/interface/bridge/port` menu since RouterOS v6.42. | | **drop-when-ufdb-entry-src-drop** (*yes \| no*; Default: **yes**) | Enable or disable dropping packets when UFDB entry has action src-drop. | | **allow-unicast-loopback** (*yes \| no*; Default: **no**) | Unicast loopback on port. When enabled, it permits sending back when the source port and destination port are the same for known unicast packets. | | **allow-multicast-loopback** (*yes \| no*; Default: **no**) | Multicast loopback on port. When enabled, it permits sending back when the source port and destination port are the same for registered multicast or broadcast packets. | | **action-on-static-station-move** (*copy-to-cpu \| drop \| forward \| redirect-to-cpu*; Default: **forward**) | Action for packets when UFDB already contains a static entry with such a MAC but with a different port. | | **drop-dynamic-mac-move** (*yes \| no*; Default: **no**) | Prevents MAC relearning until UFDB timeout if the MAC is already learned on another port. | | Property | Description | | :-- | :-- | | **allow-fdb-based-vlan-translate** (*yes \| no*; Default: **no**) | Enable or disable MAC-based VLAN translation on the port. | | **allow-mac-based-service-vlan-assignment-for** (*all-frames \| none \|* *tagged-frame-only \| untagged-and-priority-tagged-frame-only*; Default: **none**) | Frame type for which MAC-based service VLAN translation applies. | | **allow-mac-based-customer-vlan-assignment-for** (*all-frames \| none \|* *tagged-frame-only \| untagged-and-priority-tagged-frame-only*; Default: **none**) | Frame type for which MAC-based customer VLAN translation applies. | | **default-customer-pcp** (*0..7*; Default: **0**) | Default customer PCP of the port. | | **default-service-pcp** (*0..7*; Default: **0**) | Default service PCP of the port. | | **pcp-propagation-for-initial-pcp** (*yes \| no*; Default: **no**) | Enables or disables PCP propagation for initial PCP assignment on ingress.If the port vlan-type is an Edge port, the service PCP is copied from the customer PCP.If the port vlan-type is a Network port, the customer PCP is copied from the service PCP. | | **filter-untagged-frame** (*yes \| no*; Default: **no**) | Whether to filter untagged frames on the port. | | **filter-priority-tagged-frame** (*yes \| no*; Default: **no**) | Whether to filter tagged frames with priority on the port. | | **filter-tagged-frame** (*yes \| no*; Default: **no**) | Whether to filter tagged frames on the port. | | Property | Description | | :-- | :-- | | **egress-vlan-tag-table-lookup-key** (*according-to-bridge-type \| egress-vid*; Default: **egress-vid**) | Egress VLAN table (VLAN Tagging) lookup:egress-vid - Lookup VLAN ID is CVID when an Edge port is configured, SVID when a Network port is configured.according-to-bridge-type - Lookup VLAN ID is CVID when a customer VLAN bridge is configured, SVID when a service VLAN bridge is configured. The Customer tag is unmodified for an Edge port in a service VLAN bridge. | | **egress-vlan-mode** (*tagged \| unmodified \| untagged*; Default: **unmodified**) | Egress VLAN tagging action on the port. | | **egress-pcp-propagation** (*yes \| no*; Default: **no**) | Enables or disables egress PCP propagation.If the port vlan-type is an Edge port, the service PCP is copied from the customer PCP.If the port vlan-type is a Network port, the customer PCP is copied from the service PCP. | | Property | Description | | :-- | :-- | | **ingress-mirror-to** (*mirror0 \| mirror1 \| none*; Default: **none**) | Analyzer port for port-based ingress mirroring. | | **ingress-mirroring-according-to-vlan** (*yes \| no*; Default: **no**) | | | **egress-mirror-to** (*mirror0 \| mirror1 \| none*; Default: **none**) | Analyzer port for port-based egress mirroring. | | Property | Description | | :-- | :-- | | **qos-scheme-precedence** (*da-based \| dscp-based \| ingress-acl-based \| pcp-based \| protocol-based \| sa-based \| vlan-based*; Default: **pcp-based, sa-based, da-based, dscp-based, protocol-based, vlan-based**) | Specifies applied QoS assignment schemes on the ingress of the port.da-baseddscp-basedingress-acl-basedpcp-basedprotocol-basedsa-basedvlan-based | | **pcp-or-dscp-based-qos-change-dei** (*yes \| no*; Default: **no**) | Enables or disables PCP or DSCP based DEI change on the port. | | **pcp-or-dscp-based-qos-change-pcp** (*yes \| no*; Default: **no**) | Enables or disables PCP or DSCP based PCP change on the port. | | **pcp-or-dscp-based-qos-change-dscp** (*yes \| no*; Default: **no**) | Enables or disables PCP or DSCP based DSCP change on the port. | | **dscp-based-qos-dscp-to-dscp-mapping** (*yes \| no*; Default: **yes**) | Enables or disables DSCP to internal DSCP mapping on the port. | | **pcp-based-qos-drop-precedence-mapping** (*PCP/DEI-range:drop-precedence*; Default: **0-15:green**) | The new value of drop precedence for the PCP/DEI to drop precedence (drop \| green \| red \| yellow) mapping. Multiple mappings are allowed separated by a comma e.g. "0-7:yellow,8-15:red". | | **pcp-based-qos-dscp-mapping** (*PCP/DEI-range:DEI*; Default: **0-15:0**) | The new value of DSCP for the PCP/DEI to DSCP (0..63) mapping. Multiple mappings are allowed separated by a comma e.g. "0-7:25,8-15:50". | | **pcp-based-qos-dei-mapping** (*PCP/DEI-range:DEI*; Default: **0-15:0**) | The new value of DEI for the PCP/DEI to DEI (0..1) mapping. Multiple mappings are allowed separated by a comma e.g. "0-7:0,8-15:1". | | **pcp-based-qos-pcp-mapping** (*PCP/DEI-range:DEI*; Default: **0-15:0**) | The new value of PCP for the PCP/DEI to PCP (0..7) mapping. Multiple mappings are allowed separated by a comma e.g. "0-7:3,8-15:4". | | **pcp-based-qos-priority-mapping** (*PCP/DEI-range:DEI*; Default: **0-15:0**) | The new value of internal priority for the PCP/DEI to priority (0..15) mapping. Multiple mappings are allowed separated by a comma e.g. "0-7:5,8-15:15". | | Property | Description | | :-- | :-- | | **priority-to-queue** (*priority-range:queue*; Default: **0-15:0,1:1,2:2,3:3**) | Internal priority (0..15) mapping to queue (0..7) per port. | | **per-queue-scheduling** (*Scheduling-type:Weight*; Default: **wrr-group0:1,wrr-group0:2,wrr-group0:4,wrr-group0:8,wrr-group0:16,wrr-group0:32,** **wrr-group0:64,wrr-group0:128**) | Set port to use either strict or weighted round robin policy for traffic shaping for each queue group; each queue is separated by a comma. | | Property | Description | | :-- | :-- | | **ingress-customer-tpid-override** (*yes \| no*; Default:**!ingress-customer-tpid-override**) **ingress-customer-tpid** (*0..10000*; Default: **0x8100**) | Ingress customer TPID override allows accepting specific frames with a custom customer tag TPID. The default value is for the tag of 802.1Q frames. | | **egress-customer-tpid-override** (*yes \| no*; Default: **!egress-customer-tpid-override**) **egress-customer-tpid** (*0..10000*; Default: **0x8100**) | Egress customer TPID override allows custom identification for egress frames with a customer tag. The default value is for the tag of 802.1Q frames. | | **ingress-service-tpid-override** (*yes \| no*; Default: **!ingress-service-tpid-override**) **ingress-service-tpid** (*0..10000*; Default: **0x88A8**) | Ingress service TPID override allows accepting specific frames with a custom service tag TPID. The default value is for the service tag of 802.1AD frames. | | **egress-service-tpid-override** (*yes \| no*; Default: **!egress-service-tpid-override**) **egress-service-tpid** (*0..10000*; Default: **0x88A8**) | Egress service TPID override allows custom identification for egress frames with a service tag. The default value is for the service tag of 802.1AD frames. | | Property | Description | | :-- | :-- | | **custom-drop-counter-includes** (*counters*; Default: **none**) | Custom include to count dropped packets for switch port custom-drop-packet counter.device-loopbackfdb-hash-violationexceeded-port-learn-limitationdynamic-station-movestatic-station-moveufdb-source-drophost-source-dropunknown-hostingress-vlan-filtered | | **queue-custom-drop-counter0-includes** (*counters*; Default: **none**) | Custom include to count dropped packets for switch port tx-queue-custom0-drop-packet and bytes for tx-queue-custom0-drop-byte counter. redyellowgreenqueue0...queue7 | | **queue-custom-drop-counter1-includes** (*counters*; Default: **none**) | Custom include to count dropped packets for switch port tx-queue-custom1-drop-packet and bytes for tx-queue-custom1-drop-byte counter. redyellowgreenqueue0...queue7 | | **policy-drop-counter-includes** (*counters*; Default: **none**) | Custom include to count dropped packets for switch port policy-drop-packet counter.ingress-policingingress-aclegress-policingegress-acl | ## Forwarding Databases --- ### Unicast FDB The unicast forwarding database supports up to 16K MAC entries. **Sub-menu:** `/interface/ethernet/switch/unicast-fdb` | Property | Description | | :-- | :-- | | **action** (*action*; Default: **forward**) | Action for UFDB entry:dst-drop - Packets are dropped when their destination MAC matches the entry.dst-redirect-to-cpu - Packets are redirected to the CPU when their destination MAC matches the entry.forward - Packets are forwarded.src-and-dst-drop - Packets are dropped when their source MAC or destination MAC matches the entry.src-and-dst-redirect-to-cpu - Packets are redirected to CPU when their source MAC or destination MAC matches the entry.src-drop - Packets are dropped when their source MAC matches the entry.src-redirect-to-cpu - Packets are redirected to the CPU when their source MAC matches the entry. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables Unicast FDB entry. | | **isolation-profile** (*community1 \| community2 \| isolated \| promiscuous*; Default: **promiscuous**) | MAC level isolation profile. | | **mac-address** (*MAC address*) | The action command applies to the packet when the destination MAC or source MAC matches the entry. | | **mirror** (*yes \| no*; Default: **no**) | Enables or disables mirroring based on source MAC or destination MAC. | | **port** (*port*) | Matching port for the Unicast FDB entry. | | **qos-group** (*none*; Default: **none**) | Defined QoS group from the QoS group menu. | | **svl** (*yes \| no*; Default: **no**) | Unicast FDB learning mode:Shared VLAN Learning (svl) - learning/lookup is based on MAC addresses - not on VLAN IDs.Independent VLAN Learning (ivl) - learning/lookup is based on both MAC addresses and VLAN IDs. | | **vlan-id** (*0..4095*) | Unicast FDB lookup/learning VLAN id. | ### Multicast FDB CRS125 switch-chip supports up to 1024 entries in the MFDB for multicast forwarding. For each multicast packet, destination MAC or destination IP lookup is performed in the MFDB. MFDB entries are not automatically learned and can only be configured. **Sub-menu:** `/interface/ethernet/switch/multicast-fdb` | Property | Description | | :-- | :-- | | **address** (*X.X.X.X \| XX:XX:XX:XX:XX:XX*) | Matching IP address or MAC address for multicast packets. | | **bypass-vlan-filter** (*yes \| no*; Default: **no**) | Allows bypassing VLAN filtering for matching multicast packets. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables Multicast FDB entry. | | **ports** (*ports*) | Member ports for multicast traffic. | | **qos-group** (*none*; Default: **none**) | Defined QoS group from QoS group menu. | | **svl** (*yes \| no*; Default: **no**) | Multicast FDB learning mode:Shared VLAN Learning (svl) - learning/lookup is based on MAC addresses - not on VLAN IDs.Independent VLAN Learning (ivl) - learning/lookup is based on both MAC addresses and VLAN IDs. | | **vlan-id** (*0..4095*; Default: **0**) | Multicast FDB lookup VLAN ID. If the VLAN learning mode is IVL, VLAN id is lookup id, otherwise VLAN id = 0. | ### Reserved FDB Cloud Router Switch supports 256 RFDB entries. Each RFDB entry can store either a Layer2 unicast or multicast MAC address with specific commands. **Sub-menu:** `/interface/ethernet/switch/reserved-fdb` | Property | Description | | :-- | :-- | | **action** (*copy-to-cpu \| drop \| forward \| redirect-to-cpu*; Default: **forward**) | Action for RFDB entry:copy-to-cpu - Packets are copied to the CPU when their destination MAC matches the entry.drop - Packets are dropped when their destination MAC matches the entry.forward - Packets are forwarded when their destination MAC matches the entry.redirect-to-cpu - Packets are redirected to the CPU when their destination MAC matches the entry. | | **bypass-ingress-port-policing** (*yes \| no*; Default: **no**) | Allows bypassing Ingress Port Policer for matching packets. | | **bypass-ingress-vlan-filter** (*yes \| no*; Default: **no**) | Allows bypassing VLAN filtering for matching packets. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables Reserved FDB entry. | | **mac-address** (*MAC address*; Default: **00:00:00:00:00:00**) | Matching MAC address for Reserved FDB entry. | | **qos-group** (*none*; Default: **none**) | Defined QoS group from QoS group menu. | ## VLAN --- ### VLAN Table The VLAN table supports 4096 VLAN entries for storing VLAN member information as well as other VLAN information such as QoS, isolation, forced VLAN, learning, and mirroring. **Sub-menu:** `/interface/ethernet/switch/vlan` | Property | Description | | :-- | :-- | | **disabled** (*yes \| no*; Default: **no**) | Indicates whether the VLAN entry is disabled. Only the enabled entry is applied to the lookup process and forwarding decision. | | **flood** (*yes \| no*; Default: **no**) | Enables or disables forced VLAN flooding per VLAN. If the feature is enabled, the result of the destination MAC lookup in the UFDB or MFDB is ignored, and the packet is forced to flood in the VLAN. | | **ingress-mirror** (*yes \| no*; Default: **no**) | Enables the ingress mirror per VLAN to support the VLAN-based mirror function. | | **learn** (*yes \| no*; Default: **yes**) | Enables or disables source MAC learning for VLAN. | | **ports** (*ports*) | Member ports of the VLAN. | | **qos-group** (*none*; Default: **none**) | Defined QoS group from the QoS group menu. | | **svl** (*yes \| no*; Default: **no**) | FDB lookup mode for lookup in UFDB and MFDB.Shared VLAN Learning (svl) - learning/lookup is based on MAC addresses - not on VLAN IDs.Independent VLAN Learning (ivl) - learning/lookup is based on both MAC addresses and VLAN IDs. | | **vlan-id** (*0..4095*) | VLAN ID of the VLAN member entry. | ### Egress VLAN Tag Egress packets can be assigned different VLAN tag formats. The VLAN tags can be removed, added, or left as is when the packet is sent to the egress port (destination port). Each port has dedicated control of the egress VLAN tag format. The tag formats include: - Untagged - Tagged - Unmodified The Egress VLAN Tag table includes 4096 entries for VLAN tagging selection. **Sub-menu:** `/interface/ethernet/switch/egress-vlan-tag` | Property | Description | | :-- | :-- | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables the Egress VLAN Tag table entry. | | **tagged-ports** (*ports*) | Ports that are tagged in egress. | | **vlan-id** (*0..4095*) | VLAN ID which is tagged in egress. | ### Ingress/Egress VLAN Translation The Ingress VLAN Translation table allows for up to 15 entries for each port. One or multiple fields can be selected from the packet header for lookup in the Ingress VLAN Translation table. The S-VLAN or C-VLAN or both configured in the first matched entry are assigned to the packet. **Sub-menu:** `/interface/ethernet/switch/ingress-vlan-translation, /interface/ethernet/switch/egress-vlan-translation` | Property | Description | | :-- | :-- | | **customer-dei** (*0..1*; Default: **none**) | Matching DEI of the customer tag. | | **customer-pcp** (*0..7*; Default: **none**) | Matching PCP of the customer tag. | | **customer-vid** (*0..4095*; Default: **none**) | Matching the VLAN ID of the customer tag. | | **customer-vlan-format** (*any \| priority-tagged-or-tagged \| tagged \| untagged-or-tagged*; Default:**any**) | Type of frames with customer tag for which VLAN translation rule is valid. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables VLAN translation entry. | | **new-customer-vid** (*0..4095*; Default: **none**) | The new customer VLAN ID replaces the matching customer VLAN ID. If set to 4095 and ingress VLAN translation is used, then traffic is dropped. | | **new-service-vid** (*0..4095*; Default: **none**) | The new service VLAN ID replaces the matching service VLAN ID. | | **pcp-propagation** (*yes \| no*; Default: **no**) | Enables or disables PCP propagation.If the port type is Edge, the customer PCP is copied from the service PCP.If the port type is Network, the service PCP is copied from the customer PCP. | | **ports** (*ports*) | Matching switch ports for VLAN translation rule. | | **protocol** (*protocols*; Default: **none**) | Matching Ethernet protocol. *(only for Ingress VLAN Translation)* | | **sa-learning** (*yes \| no*; Default: **no**) | Enables or disables source MAC learning after VLAN translation. *(only for Ingress VLAN Translation)* | | **service-dei** (*0..1*; Default: **none**) | Matching DEI of the service tag. | | **service-pcp** (*0..7*; Default: **none**) | Matching PCP of the service tag. | | **service-vid** (*0..4095*; Default: **none**) | Matching VLAN ID of the service tag. | | **service-vlan-format** (*any \| priority-tagged-or-tagged \| tagged \| untagged-or-tagged*; Default:**any**) | Type of frames with service tag for which VLAN translation rule is valid. | Below is a table of traffic that triggers a rule that has a certain VLAN format set; note that traffic that is tagged with VLAN ID 0 is a special case that is also taken into account. | Property | Description | | :-- | :-- | | **any** | Accepts:Untagged trafficTagged trafficTagged traffic with priority setVLAN 0 trafficVLAN 0 traffic with priority set | | **priority-tagged-or-tagged** | Accepts:Tagged trafficTagged traffic with priority setVLAN 0 trafficVLAN 0 traffic with priority set | | **tagged** | Accepts:Tagged trafficTagged traffic with priority set | | **untagged-or-tagged** | Accepts:Untagged trafficTagged trafficTagged traffic with priority set | :::danger If `VLAN-format` is set to `any`, then `customer-vid``/``service-vid` set to `0` will trigger the switch rule with VLAN 0 traffic. In this case, the switch rule will be looking for untagged traffic or traffic with a VLAN 0 tag, and only `untagged-or-tagged` will filter out VLAN 0 traffic. ::: ### Protocol Based VLAN The Protocol Based VLAN table is used to assign VID and QoS attributes to related protocol packets per port. **Sub-menu:** `/interface/ethernet/switch/protocol-based-vlan` | Property | Description | | :-- | :-- | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables Protocol Based VLAN entry. | | **frame-type** (*ethernet \| llc \| rfc-1042*; Default: **ethernet**) | Encapsulation type of the matching frames. | | **new-customer-vid** (*0..4095*; Default: **0**) | The new customer VLAN ID replaces the original customer VLAN ID for the specified protocol. If set to 4095, then traffic is dropped. | | **new-service-vid** (*0..4095*; Default: **0**) | The new service VLAN ID replaces the original service VLAN ID for the specified protocol. | | **ports** (*ports*) | Matching switch ports for Protocol-based VLAN rule. | | **protocol** (*protocol*; Default: **0**) | Matching protocol for Protocol-based VLAN rule. | | **qos-group** (*none*; Default: **none**) | Defined QoS group from the QoS group menu. | | **set-customer-vid-for** (*all \| none \| tagged \| untagged-or-priority-tagged*; Default: **all**) | Customer VLAN ID assignment command for different packet types. | | **set-qos-for** (*all \| none \| tagged \| untagged-or-priority-tagged*; Default: **none**) | Frame type for which QoS assignment command applies. | | **set-service-vid-for** (*all \| none \| tagged \| untagged-or-priority-tagged*; Default: **all**) | Service VLAN ID assignment command for different packet types. | ### MAC Based VLAN MAC Based VLAN table is used to assign a VLAN based on the source MAC. **Sub-menu:** `/interface/ethernet/switch/mac-based-vlan` | Property | Description | | :-- | :-- | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables MAC Based VLAN entry. | | **new-customer-vid** (*0..4095*; Default: **0**) | The new customer VLAN ID replaces the original service VLAN ID for matched packets. If set to 4095, then traffic is dropped. | | **new-service-vid** (*0..4095*; Default: **0**) | The new service VLAN ID replaces the original service VLAN ID for matched packets. | | **src-mac-address** (*MAC address*) | Matching source MAC address for MAC based VLAN rule. | :::warning All CRS1xx/2xx series switches support up to 1024 MAC Based VLAN table entries. ::: ### 1:1 VLAN Switching 1:1 VLAN switching can be used to replace the regular L2 bridging for matched packets. When a packet hits a 1:1 VLAN switching table entry, the destination port information in the entry is assigned to the packet. The matched destination information in the UFDB and MFDB entries no longer applies to the packet. **Sub-menu:** `/interface/ethernet/switch/one2one-vlan-switching` | Property | Description | | :-- | :-- | | **customer-vid** (*0..4095*; Default: **0**) | Matching customer VLAN id for 1:1 VLAN switching. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables the 1:1 VLAN switching table entry. | | **dst-port** (*port*) | Destination port for matched 1:1 VLAN switching packets. | | **service-vid** (*0..4095*; Default: **0**) | Matching customer VLAN id for 1:1 VLAN switching. | ## Port Isolation/Leakage --- The CRS switches support flexible multi-level isolation features, which can be used for user access control, traffic engineering and advanced security and network management. The isolation features provide an organized fabric structure allowing the user to easily program and control the access by port, MAC address, VLAN, protocol, flow, and frame type. The following isolation and leakage features are supported: - Port-level isolation - MAC-level isolation - VLAN-level isolation - Protocol-level isolation - Flow-level isolation - Free combination of the above Port-level isolation supports different control schemes on the source port and destination port. Each entry can be programmed with access control for either the source port or the destination port. - When the entry is programmed with source port access control, the entry is. applied to the ingress packets. - When the entry is programmed with destination port access control, the entry is applied to the egress packets. Port leakage allows bypassing egress VLAN filtering on the port. A leaky port is allowed to access other ports for various applications such as security, network control, and management. Note: When both isolation and leakage are applied to the same port, the port is isolated. **Sub-menu:** `/interface/ethernet/switch/port-isolation` **Sub-menu:** `/interface/ethernet/switch/port-leakage` | Property | Description | | :-- | :-- | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables port isolation/leakage entry. | | **flow-id** (*0..63*; Default: **none**) | | | **forwarding-type** (*bridged; routed*; Default: **bridged,routed**) | Matching traffic forwarding type on Cloud Router Switch. | | **mac-profile** (*community1 \| community2 \| isolated \| promiscuous*; Default: **none**) | Matching MAC isolation/leakage profile. | | **port-profile** (*0..31*; Default: **none**) | Matching Port isolation/leakage profile. | | **ports** (*ports*; Default: **none**) | Isolated/leaked ports. | | **protocol-type** (*arp; nd; dhcpv4; dhcpv6; ripv1*; Default: **arp,nd,dhcpv4,dhcpv6,ripv1**) | Included protocols for isolation/leakage. | | **registration-status** (*known; unknown*; Default: **known,unknown**) | Registration status for matching packets. Known ones are present in UFDB and MFDB, and unknown ones are not. | | **traffic-type** (*unicast; multicast; broadcast*; Default: **unicast,multicast,broadcast**) | Matching traffic type. | | **type** (*dst \| src*; Default: **src**) | Lookup type of the isolation/leakage entry:src - Entry applies to ingress packets of the ports.dst - Entry applies to egress packets of the ports. | | **vlan-profile** (*community1 \| community2 \| isolated \| promiscuous*; Default: **none**) | Matching VLAN isolation/leakage profile. | ## Trunking --- Trunking in the Cloud Router Switches provides static link aggregation groups with hardware automatic failover and load balancing. IEEE802.3ad and IEEE802.1ax compatible Link Aggregation Control Protocol is not supported. Up to 8 Trunk groups are supported with up to 8 Trunk member ports per Trunk group. CRS Port Trunking calculates transmit-hash based on all of the following parameters: L2 src-dst MAC + L3 src-dst IP + L4 src-dst Port. **Sub-menu:** `/interface/ethernet/switch/trunk` | Property | Description | | :-- | :-- | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables port trunking entry. | | **member-ports** (*ports*) | Member ports of the Trunk group. | | **name** (*string value*; Default: **trunkX**) | Name of the Trunk group. | ## Quality of Service --- ### Shaper Traffic shaping restricts the rate and burst size of the flow which is transmitted out from the interface. The shaper is implemented by a token bucket. If the packet exceeds the maximum rate or the burst size, which means not enough tokens for the packet, the packet is stored in the buffer until there are enough tokens to transmit it. **Sub-menu:** `/interface/ethernet/switch/shaper` | Property | Description | | :-- | :-- | | **burst** (*integer*; Default: **100k**) | Maximum data rate which can be transmitted while the burst is allowed. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables traffic shaper entry. | | **meter-unit** (*bit \| packet*; Default: **bit**) | Measuring units for traffic shaper rate. | | **port** (*port*) | Physical port for traffic shaper. | | **rate** (*integer*; Default: **1M**) | Maximum data rate limit. | | **target** (*port \| queueX \| wrr-groupX*; Default: **port**) | Three levels of shapers are supported on each port (including CPU port):Port level - Entry applies to the port of the switch-chip.WRR group level - Entry applies to one of the 2 Weighted Round Robin queue groups (wrr-group0, wrr-group1) on the port.Queue level - Entry applies to one of the 8 queues (queue0 - queue7) on the port. | ### Ingress Port Policer **Sub-menu:** `/interface/ethernet/switch/ingress-port-policer` | Property | Description | | :-- | :-- | | **burst** (*integer*; Default: **100k**) | Maximum data rate which can be transmitted while the burst is allowed. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables ingress port policer entry. | | **meter-len** (*layer-1 \| layer-2 \| layer-3*; Default: **layer-1**) | Packet classification which sets the packet byte length for metering.layer-1 - includes the entire layer-2 frame + FCS + inter-packet gap + preamble.layer-2 - includes the layer-2 frame + FCS.layer-3 - includes only the layer-3 + ethernet padding without the layer-2 header and FCS. | | **meter-unit** (*bit \| packet*; Default: **bit**) | Measuring units for traffic ingress port policer rate. | | **new-dei-for-yellow** (*0..1 \| remap*; Default: **none**) | Remarked DEI for exceeded traffic if yellow-action is remark. | | **new-dscp-for-yellow** (*0..63 \| remap*; Default: **none**) | Remarked DSCP for exceeded traffic if yellow-action is remark. | | **new-pcp-for-yellow** (*0..7 \| remap*; Default: **none**) | Remarked PCP for exceeded traffic if yellow-action is remark. | | **packet-types** (*packet-types*; Default: **all types from the description**) | Matching packet types for which the ingress port policer entry is valid. | | **port** (*port*) | Physical port or trunk for the ingress port policer entry. | | **rate** (*integer*) | Maximum data rate limit. | | **yellow-action** (*drop \| forward \| remark*; Default: **drop**) | Performed action for exceeded traffic. | ### QoS Group The global QoS group table is used for VLAN-based, Protocol-based, and MAC-based QoS group assignment configuration. **Sub-menu:** `/interface/ethernet/switch/qos-group` | Property | Description | | :-- | :-- | | **dei** (*0..1*; Default: **none**) | The new value of DEI for the QoS group. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables the protocol QoS group entry. | | **drop-precedence** (*drop \| green \| red \| yellow*; Default: **green**) | Drop precedence is an internal QoS attribute used for packet enqueuing or dropping. | | **dscp** (*0..63*; Default: **none**) | The new value of DSCP for the QoS group. | | **name** (*string value*; Default: **groupX**) | Name of the QoS group. | | **pcp** (*0..7*; Default: **none**) | The new value of PCP for the QoS group. | | **priority** (*0..15*; Default: **0**) | Internal priority is of local significance for classifying traffic to different egress queues on a port. (1 is highest, 15 is lowest) | ### DSCP QoS Map The global DSCP to QOS mapping table is used for mapping from the DSCP of the packet to new QoS attributes configured in the table. **Sub-menu:** `/interface/ethernet/switch/dscp-qos-map` | Property | Description | | :-- | :-- | | **dei** (*0..1*) | The new value of DEI for the DSCP to QOS mapping entry. | | **drop-precedence** (*drop \| green \| red \| yellow*) | The new value of Drop precedence for the DSCP to QOS mapping entry. | | **pcp** (*0..7*) | The new value of PCP for the DSCP to QOS mapping entry. | | **priority** (*0..15*) | The new value of internal priority for the DSCP to QOS mapping entry. | ### DSCP To DSCP Map The global DSCP to DSCP mapping table is used for mapping from the packet's original DSCP to the new DSCP value configured in the table. **Sub-menu:** `/interface/ethernet/switch/dscp-to-dscp` | Property | Description | | :-- | :-- | | **new-dscp** (*0..63*) | The new value of DSCP for the DSCP to DSCP mapping entry. | ### Policer QoS Map **Sub-menu:** `/interface/ethernet/switch/policer-qos-map` | Property | Description | | :-- | :-- | | **dei-for-red** (*0..1*; Default: **0**) | Policer DEI remapping value for red packets. | | **dei-for-yellow** (*0..1*; Default: **0**) | Policer DEI remapping value for yellow packets. | | **dscp-for-red** (*0..63*; Default: **0**) | Policer DSCP remapping value for red packets. | | **dscp-for-yellow** (*0..63*; Default: **0**) | Policer DSCP remapping value for yellow packets. | | **pcp-for-red** (*0..7*; Default: **0**) | Policer PCP remapping value for red packets. | | **pcp-for-yellow** (*0..7*; Default: **0**) | Policer PCP remapping value for yellow packets. | ## Access Control List --- Access Control List consists of ingress policy and egress policy engines and allows configuration of up to 128 policy rules (limited by RouterOS). It is an advanced tool for wire-speed packet filtering, forwarding, shaping, and modifying based on Layer2, Layer3, and Layer4 protocol header field conditions. :::info See the Summary section for Access Control List-supported Cloud Router Switch devices. ::: :::danger Due to hardware limitations, it is not possible to match broadcast/multicast traffic on specific ports. You should use port isolation, drop traffic on ingress ports, or use VLAN filtering to prevent certain broadcast/multicast traffic from being forwarded. ::: **Sub-menu:** `/interface/ethernet/switch/acl` ### ACL condition part for MAC-related fields of packets | Property | Description | | :-- | :-- | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables an ACL entry. | | **table** (*egress \| ingress*; Default: **ingress**) | Selects the policy table for incoming or outgoing packets. | | **invert-match** (*yes \| no*; Default: **no**) | Inverts the whole ACL rule matching. | | **src-ports** (*ports,trunks*) | Matching physical source ports or trunks. | | **dst-ports** (*ports,trunks*) | Matching physical destination ports or trunks. It is not possible to match broadcast/multicast traffic on the egress port due to a hardware limitation. | | **mac-src-address** (*MAC address/Mask*) | Source MAC address and mask. | | **mac-dst-address** (*MAC address/Mask*) | Destination MAC address and mask. | | **dst-addr-registered** (*yes \| no*) | Defines whether to match packets with a registered state - packets whose destination MAC address is in UFDB/MFDB/RFDB. Valid only in the egress table. | | **mac-protocol** (*802.2 \| arp \| homeplug-av \| ip \| ip-or-ipv6 \| ipv6 \| ipx \| lldp \| loop-protect \| mpls-multicast \| mpls-unicast \| mvrp \| non-ip \| packing-compr \| packing-simple \| pppoe \| pppoe-discovery \| rarp \| service-vlan \| vlan or integer: 0..65535 decimal format or 0x0000-0xffff hex format*) | Ethernet payload type (MAC-level protocol)802.2 - 802.2 Frames (0x0004)arp - Address Resolution Protocol (0x0806)capsman - CAPsMAN to CAP MAC layer connection (0x88BB)dot1x - EAPoL IEEE 802.1X (0x888E)homeplug-av - HomePlug AV MME (0x88E1)ip - Internet Protocol version 4 (0x0800)ip-or-ipv6 - IPv4 or IPv6 (0x0800 or 0x86DD)ipv6 - Internet Protocol Version 6 (0x86DD)ipx - Internetwork Packet Exchange (0x8137)lacp - Link Aggregation Control Protocol (0x8809)lldp - Link Layer Discovery Protocol (0x88CC)loop-protect - Loop Protect Protocol (0x9003)macsec - MAC security IEEE 802.1AE (0x88E5)mpls-multicast - MPLS multicast (0x8848)mpls-unicast - MPLS unicast (0x8847)mvrp - Multiple VLAN Registration protocol (0x88F5)non-ip - Not Internet Protocol version 4 (not 0x0800)packing-compr - Encapsulated packets with compressed IP packing (0x9001)packing-simple - Encapsulated packets with simple IP packing (0x9000)pppoe - PPPoE Session Stage (0x8864)pppoe-discovery - PPPoE Discovery Stage (0x8863)rarp - Reverse Address Resolution Protocol (0x8035)romon - Router Management Overlay Network RoMON (0x88BF)service-vlan - Provider Bridging (IEEE 802.1ad) & Shortest Path Bridging IEEE 802.1aq (0x88A8)vlan - VLAN-tagged frame (IEEE 802.1Q) and Shortest Path Bridging IEEE 802.1aq with NNI compatibility (0x8100) | | **drop-precedence** (*drop \| green \| red \| yellow*) | Matching internal drop precedence. Valid only in the egress table. | | **custom-fields** | | ### ACL condition part for VLAN-related fields of packets | Property | Description | | :-- | :-- | | **lookup-vid** (*0..4095*) | VLAN ID used in lookup. It can be changed before reaching the egress table. | | **service-vid** (*0-4095*) | Matching service VLAN ID. | | **service-pcp** (*0..7*) | Matching service PCP. | | **service-dei** (*0..1*) | Matching service DEI. | | **service-tag** (*priority-tagged \| tagged \| tagged-or-priority-tagged \| untagged*) | Format of the service tag. | | **customer-vid** (*0-4095*) | Matching customer VLAN ID. | | **customer-pcp** (*0..7*) | Matching customer PCP. | | **customer-dei** (*0..1*) | Matching customer DEI. | | **customer-tag** (*priority-tagged \| tagged \| tagged-or-priority-tagged \| untagged*) | Format of the customer tag. | | **priority** (*0..15*) | Matching internal priority. Valid only in the egress table. | ### ACL condition part for IPv4 and IPv6 related fields of packets | Property | Description | | :-- | :-- | | **ip-src** (*IPv4/0..32*) | Matching source IPv4 address. | | **ip-dst** (*IPv4/0..32*) | Matching destination IPv4 address. | | **ip-protocol** (*tcp \| udp \| udp-lite \| other*) | IP protocol type. | | **src-l3-port** (*0-65535*) | Matching Layer3 source port. | | **dst-l3-port** (*0-65535*) | Matching Layer3 destination port. | | **ttl** (*0 \| 1 \| max \| other*) | Matching TTL field of the packet. | | **dscp** (*0..63*) | Matching DSCP field of the packet. | | **ecn** (*0..3*) | Matching ECN field of the packet. | | **fragmented** (*yes \| no*) | Whether to match fragmented packets. | | **first-fragment** (*yes \| no*) | YES matches not fragmented and the first fragments, NO matches other fragments. | | **ipv6-src** (*IPv6/0..128*) | Matching source IPv6 address. | | **ipv6-dst** (*IPv6/0..128*) | Matching destination IPv6 address. | | **mac-isolation-profile** (*community1 \| community2 \| isolated \| promiscuous*) | Matches isolation profile based on UFDB. Valid only in the egress policy table. | | **src-mac-addr-state** (*dynamic-station-move \| sa-found \| sa-not-found \| static-station-move*) | Defines whether to match packets with registered state - packets whose destination MAC address is in UFDB/MFDB/RFDB. Valid only in the egress policy table. | | **flow-id** (*0..63*) | | ### ACL rule action part | Property | Description | | :-- | :-- | | **action** (*copy-to-cpu \| drop \| forward \|* *redirect-to-cpu \| send-to-new-dst-ports*; Default: **forward**) | copy-to-cpu - Packets are copied to the CPU if they match the ACL conditions.drop - Packets are dropped if they match the ACL conditions.forward - Packets are forwarded if they match the ACL conditions.redirect-to-cpu - Packets are redirected to the CPU if they match the ACL conditions.send-to-new-dst-ports - Packets are sent to new destination ports if they match the ACL conditions. | | **new-dst-ports** (*ports,trunks*) | If the action is "send-to-new-dst-ports", then this property sets which ports/trunks are the new destinations. | | **mirror-to** (*mirror0 \| mirror1*) | Mirroring destination for ACL packets. | | **policer** (*policer*) | Applied ACL Policer for ACL packets. | | **src-mac-learn** (*yes \| no*) | Whether to learn the source MAC of the matched ACL packets. Valid only in the ingress policy table. | | **new-service-vid** (*0..4095*) | New service VLAN ID for ACL packets. | | **new-service-pcp** (*0..7*) | New service PCP for ACL packets. | | **new-service-dei** (*0..1*) | New service DEI for ACL packets. | | **new-customer-vid** (*0..4095*) | New customer VLAN ID for ACL packets. If set to 4095, then traffic is dropped. | | **new-customer-pcp** (*0..7*) | New customer PCP for ACL packets. | | **new-customer-dei** (*0..1*) | New customer DEI for ACL packets. | | **new-dscp** (*0..63*) | New DSCP for ACL packets. | | **new-priority** (*0..15*) | New internal priority for ACL packets. | | **new-drop-precedence** (*drop \| green \| red \| yellow*) | New internal drop precedence for ACL packets. | | **new-registered-state** (*yes \| no*) | Whether to modify packet status. YES sets packet status to registered, NO - unregistered. Valid only in the ingress policy table. | | **new-flow-id** (*0..63*) | | ### Filter bypassing part for ACL packets | Property | Description | | :-- | :-- | | **attack-filter-bypass** (*yes \| no*; Default: **no**) | | | **ingress-vlan-filter-bypass** (*yes \| no*; Default: **no**) | Allows bypassing ingress VLAN filtering in the VLAN table for matching packets. This applies only to the ingress policy table. | | **egress-vlan-filter-bypass** (*yes \| no*; Default: **no**) | Allows bypassing egress VLAN filtering in the VLAN table for matching packets. This applies only to the ingress policy table. | | **isolation-filter-bypass** (*yes \| no*; Default: **no**) | Allows bypassing the Isolation table for matching packets. This applies only to the ingress policy table. | | **egress-vlan-translate-bypass** (*yes \| no*; Default: **no**) | Allows bypassing the egress VLAN translation table for matching packets. | ### ACL Policer **Sub-menu:** `/interface/ethernet/switch/acl/policer` | Property | Description | | :-- | :-- | | **name** (*string*; Default: **policerX**) | Name of the Policer used in ACL. | | **yellow-rate** (*integer*) | Maximum data rate limit for packets with yellow drop precedence. | | **yellow-burst** (*integer*; Default: **0**) | Maximum data rate which can be transmitted while the burst is allowed for packets with yellow drop precedence. | | **red-rate** (*integer*; Default: **0**) | Maximum data rate limit for packets with red drop precedence. | | **red-burst** (*integer*; Default: **0**) | Maximum data rate which can be transmitted while the burst is allowed for packets with red drop precedence. | | **meter-unit** (*bit \| packet*; Default: **bit**) | Measuring units for ACL traffic rate. | | **meter-len** (*layer-1 \| layer-2 \| layer-3*; Default: **layer-1**) | Packet classification which sets the packet byte length for metering.layer-1 - includes entire layer-2 frame + FCS + inter-packet gap + preamble.layer-2 - includes layer-2 frame + FCS.layer-3 - includes only layer-3 + ethernet padding without layer-2 header and FCS. | | **color-awareness** (*yes \| no*; Default: **no**) | YES makes the policer take into account pre-colored drop precedence, NO - ignores drop precedence. | | **bucket-coupling** (*yes \| no*; Default: **no**) | | | **yellow-action** (*drop \| forward \| remark*; Default: **drop**) | Performed action for exceeded traffic with yellow drop precedence. | | **new-dei-for-yellow** (*0..1 \| remap*) | New DEI for yellow drop precedence packets. | | **new-pcp-for-yellow** (*0..7 \| remap*) | New PCP for yellow drop precedence packets. | | **new-dscp-for-yellow** (*0..63 \| remap*) | New DSCP for yellow drop precedence packets. | | **red-action** (*drop \| forward \| remark*; Default: **drop**) | Performed action for exceeded traffic with red drop precedence. | | **new-dei-for-red** (*0..1 \| remap*) | New DEI for red drop precedence packets. | | **new-pcp-for-red** (*0..7 \| remap*) | New PCP for red drop precedence packets. | | **new-dscp-for-red** (*0..63 \| remap*) | New DSCP for red drop precedence packets. | ## See also --- - [CRS1xx/2xx series switches examples](./user-guides/crs1xx-2xx-series-switches-examples.md) - [Basic VLAN switching](./user-guides/basic-vlan-switching.md) - [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) - [Spanning Tree Protocol](./user-guides/spanning-tree-protocol.md) - [IGMP Snooping](./user-guides/bridge-igmp-mld-snooping.md) - [DHCP Snooping and Option 82](index.md#dhcp-snooping-and-dhcp-option-82) - [MTU on RouterBOARD](../hardware/mtu-in-routeros.md) - [Layer2 misconfiguration](./user-guides/layer2-misconfiguration.md) --- ## Bridging and Switching import WideTable from '@site/src/components/WideTable'; # Bridging and Switching --- ![Bridge diagram](./img/index-01.webp) Ethernet-like networks (Ethernet, Ethernet over IP, IEEE 802.11 in ap-bridge or bridge mode, WDS, VLAN) can be connected together using MAC bridges. The bridge feature allows the interconnection of hosts connected to separate LANs (using EoIP, geographically distributed networks can be bridged as well if any kind of IP network interconnection exists between them) as if they were attached to a single LAN. As bridges are transparent, they do not appear in the traceroute list, and no utility can make a distinction between a host working in one LAN and a host working in another LAN if these LANs are bridged. However, depending on the way the LANs are interconnected, latency and data rate between hosts may vary. Network loops may emerge (intentionally or not) in complex topologies. Without any special treatment, loops would prevent the network from functioning normally, as they would lead to avalanche-like packet multiplication. Each bridge runs an algorithm that calculates how the loop can be prevented. (R/M)STP allows bridges to communicate with each other, so they can negotiate a loop-free topology. All other alternative connections that would otherwise form loop are put on standby, so that should the main connection fail, another connection could take its place. This algorithm exchanges configuration messages (BPDUs - Bridge Protocol Data Unit) periodically, so that all bridges are updated with the newest information about changes in the network topology. (R/M)STP selects a root bridge, which is responsible for network reconfiguration, such as blocking and opening ports on other bridges. The root bridge is the bridge with the lowest bridge ID. ## Bridge Interface Setup --- To combine a number of networks into one bridge, a bridge interface should be created. Later, all the desired interfaces should be set up as its ports. By default, bridge MAC address will be chosen automatically, depending on the bridge port configuration. To avoid unwanted MAC address changes, it is recommended to disable `auto-mac` and manually specify the MAC address by using `admin-mac`. **Sub-menu:** `/interface/bridge` | Property | Description | | :-- | :-- | | **add-dhcp-option82** (*yes* \| *no*; Default: **no**) | **Important:** Starting from **RouterOS version 7.23**, this setting has been removed. Custom Remote ID and Circuit ID values can now be configured using predefined variables (such as BRIDGEMAC, HOSTNAME, INTERFACE, VID). See the `dhcp-agent-circuit-id` and `dhcp-agent-remote-id` properties below for details. If this setting was enabled in earlier versions (7.22 or earlier), upgrading will automatically update the configuration to the new format. Whether to add DHCP Option 82 information (Agent Remote ID and Agent Circuit ID) to DHCP packets. Can be used together with an Option 82 capable DHCP server to assign IP addresses and implement policies. This property only has an effect when `dhcp-snooping` is set to `yes`. In RouterOS versions 7.22 or earlier, the values are predefined and cannot be modified: For Agent Remote ID, RouterOS uses the bridge interface MAC address, formatted as "xx:xx:xx:xx:xx:xx" (lowercase, colon-separated).For Agent Circuit ID, RouterOS uses the interface name and VLAN ID separated by a colon (interface:vlan-id) where the DHCP client is connected. The VLAN ID is included only if vlan-filtering is enabled on the bridge. For example (`vlan-filtering=yes`): Agent Remote ID - cc:2d:e0:01:6a:43 Agent Circuit ID - ether2:10 | | **admin-mac** (*MAC address*; Default: **none**) | Static MAC address of the bridge. This property only has an effect when `auto-mac` is set to `no`. | | **ageing-time** (*time*; Default: **00:05:00**) | How long a host's information will be kept in the bridge database. | | **arp** (*disabled* \| *enabled* \| *local-proxy-arp \| proxy-arp \| reply-only*; Default: **enabled**) | Address Resolution Protocol settingdisabled - the interface will not use ARPenabled - the interface will use ARPlocal-proxy-arp - the router performs proxy ARP on the interface and sends replies to the same interfaceproxy-arp - the router performs proxy ARP on the interface and sends replies to other interfacesreply-only - the interface will only respond to requests originating from matching IP address/MAC address combinations that are entered as static entries in the IP/ARP table. No dynamic entries will be automatically stored in the IP/ARP table. Therefore, for communications to be successful, a valid static entry must already exist. | | **arp-timeout** (*auto \| integer*; Default: **auto**) | How long the ARP record is kept in the ARP table after no packets are received from an IP address. Value `auto` equals the value of `arp-timeout` in `/ip/settings`, default is 30s. | | **auto-mac** (*yes \| no*; Default: **yes**) | When `auto-mac=yes` is configured, the bridge will automatically select a MAC address for the bridge interface based on the following order of priority: From an Ethernet interface that is part of the bridge;From a non-Ethernet interface in the bridge (e.g., WiFi or tunnel);A randomly generated address if none of the above is available. If the configuration is changed, for example, if you add a new port to the bridge, the bridge’s MAC address will be updated only if a higher-priority address source becomes available. For example, if the bridge initially used a randomly generated MAC, then an Ethernet interface was added, the MAC would update according to the highest available priority (in this case, the Ethernet interface). The bridge will also update the MAC address if the current MAC is associated with a port that is moved to a different bridge. The current MAC address and its priority level are saved and will be reused after a reboot. When `auto-mac=no` is configured, you can set a static MAC address manually using the `admin-mac` property. | | **comment** (*string*; Default: ) | Short description of the interface. | | **dhcp-agent-circuit-id** (*string*; Default: **!dhcp-agent-circuit-id**) | Specify the **Circuit ID** suboption value of Option 82 for DHCP messages passing through the bridge. The string length is limited to 255 characters. This setting replaces the now deprecated `add-dhcp-option82` property. If `add-dhcp-option82` was enabled in earlier versions (7.22 or earlier), upgrading will automatically update the configuration to the new format: $(INTERFACE):$(VID). This format will also be shown when configuring the setting through the GUI. The following variables are supported: $(BRIDGEMAC) - current bridge MAC address, formatted as "xx:xx:xx:xx:xx:xx" (lowercase, colon-separated);$(HOSTNAME) - system identity;$(INTERFACE) - interface name where the DHCP client is connected;$(VID) - VLAN ID used by the DHCP client. If the DHCP client is untagged, the VID corresponds to the port's pvid. Applies only when vlan-filtering is enabled on the bridge. Variable syntax rules Variables must be enclosed in parentheses and prefixed with a dollar sign ($).When configuring from the terminal, the dollar sign must be escaped with a backslash (\), otherwise it will be interpreted as a RouterOS script variable. Example: `/interface/bridge``add add-dhcp-option82=yes dhcp-agent-circuit-id="interface: \$(INTERFACE), vlan: \$(VID)" dhcp-snooping=yes name=bridge1 vlan-filtering=yes` This property has an effect only when `dhcp-snooping` is set to yes. | | **dhcpv6-agent-circuit-id** (*string*; Default: **!dhcpv6-agent-circuit-id**) | Specify the **Interface ID** suboption value of Option 18 for DHCPv6 messages passing through the bridge. The `dhcpv6-agent-circuit-id` property follows the same rules as `dhcp-agent-circuit-id`. | | **dhcp-agent-remote-id** (*string*; Default: **!dhcp-agent-remote-id**) | Specify the **Remote ID** suboption value of Option 82 for DHCP messages passing through the bridge. The string length is limited to 255 characters. This setting replaces the now deprecated `add-dhcp-option82` property. If `add-dhcp-option82` was enabled in earlier versions (7.22 or earlier), upgrading will automatically update the configuration to the new format: $(BRIDGEMAC). This format will also be shown when configuring the setting through the GUI. The following variables are supported: $(BRIDGEMAC) - current bridge MAC address, formatted as "xx:xx:xx:xx:xx:xx" (lowercase, colon-separated);$(HOSTNAME) - system identity;$(INTERFACE) - interface name where the DHCP client is connected;$(VID) - VLAN ID used by the DHCP client. If the DHCP client is untagged, the VID corresponds to the port's pvid. Applies only when vlan-filtering is enabled on the bridge. Variable syntax rules Variables must be enclosed in parentheses and prefixed with a dollar sign ($).When configuring from the terminal, the dollar sign must be escaped with a backslash (\), otherwise it will be interpreted as a RouterOS script variable. Example: `/interface/bridge``add add-dhcp-option82=yes dhcp-agent-remote-id="ip: 192.168.88.1, identity: \$(HOSTNAME), mac: \$(BRIDGEMAC)" dhcp-snooping=yes name=bridge1 vlan-filtering=yes` This property has an effect only when `dhcp-snooping` is set to yes. | | **dhcpv6-agent-remote-id** (*string*; Default: **!dhcpv6-agent-remote-id**) | Specify the **Remote ID** suboption value of Option 37 for DHCPv6 messages passing through the bridge. The `dhcpv6-agent-remote-id` property follows the same rules as `dhcp-agent-remote-id`. | | **dhcp-snooping** (*yes \| no*; Default: **no**) | Enables or disables DHCP Snooping on the bridge. **Caution:** Enabling the DHCP snooping feature will turn off bridge [fast-path](../firewall-and-quality-of-service/packet-flow-in-routeros.md#fast-path), which in turn affects the ability to [fasttrack](../firewall-and-quality-of-service/packet-flow-in-routeros.md#fasttrack) connections going over that bridge. | | **dhcpv6-snooping**(*yes \| no*; Default: **no**) | Enables or disables DHCPv6 Snooping on the bridge. **Caution:** Enabling the DHCP snooping feature will turn off bridge [fast-path](../firewall-and-quality-of-service/packet-flow-in-routeros.md#fast-path), which in turn affects the ability to [fasttrack](../firewall-and-quality-of-service/packet-flow-in-routeros.md#fasttrack) connections going over that bridge. | | **disabled** (*yes \| no*; Default: **no**) | Changes whether the bridge is disabled. | | **ether-type** (*0x9100 \| 0x8100 \| 0x88a8*; Default: **0x8100**) | Changes the EtherType, which will be used to determine if a packet has a VLAN tag. Packets that have a matching EtherType are considered as tagged packets. This property only has an effect when `vlan-filtering` is set to `yes`. | | **fast-forward** (*yes \| no*; Default: **yes**) | A special and faster case of Fast Path which works only on bridges with 2 interfaces (enabled by default only for new bridges). More details can be found in the Fast Forward section. | | **forward-delay** (*time*; Default: **00:00:15**) | The time which is spent during the initialization phase of the bridge interface (i.e., after router startup or enabling the interface) in the listening/learning state before the bridge will start functioning normally. | | **forward-reserved-addresses** (*yes \| no*: Default: **no**) | Whether to forward IEEE reserved multicast MAC addresses that are in the **01:80:C2:00:00:0x** range. Bridges compliant with R/M/STP standards should refrain from forwarding these packets; this property can only be applied when `protocol-mode` is set to `none`. Enabling forwarding of reserved MAC addresses may affect certain protocols relying on these addresses. It is advisable to enable forwarding only when absolutely necessary, such as in transparent bridging setups (e.g., extending long links, using bridges as media converters, or conducting network analysis). Here are some notable MAC addresses and protocols used by RouterOS: 01:80:C2:00:00:00 - Spanning Tree Protocol (STP);01:80:C2:00:00:01 - Ethernet Flow Control;01:80:C2:00:00:02 - Link Aggregation Control Protocol (LACP);01:80:C2:00:00:03 - Dot1x client and server;01:80:C2:00:00:08 - Spanning Tree Protocol (for 802.1ad bridges, using ether-type=0x88a8);01:80:C2:00:00:0D - Multiple VLAN Registration protocol (for 802.1ad bridges, using ether-type=0x88a8);01:80:C2:00:00:0E - Link Layer Discovery Protocol, Multi-chassis Link Aggregation Group and Precision Time Protocol;**Important:** The Flow Control MAC address 01:80:C2:00:00:01 is an exception; it does not get forwarded by the bridge. | | **frame-types** (*admit-all \| admit-only-untagged-and-priority-tagged \| admit-only-vlan-tagged*; Default: **admit-all**) | Specifies allowed frame types on a bridge port. This property only has an effect when `vlan-filtering` is set to `yes`. | | **igmp-snooping** (*yes \| no*; Default: **no**) | Enables multicast group and port learning to prevent multicast traffic from flooding all interfaces in a bridge. | | **igmp-version** (*2 \| 3*; Default: **2**) | Selects the IGMP version in which IGMP membership queries will be generated when the bridge interface is acting as an IGMP querier. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | | **ingress-filtering** (*yes \| no*; Default: **yes**) | Enables or disables VLAN ingress filtering, which checks if the ingress port is a member of the received VLAN ID in the bridge VLAN table. By default, VLANs that don't exist in the bridge VLAN table are dropped before they are sent out (egress), but this property allows you to drop the packets when they are received (ingress). Should be used with `frame-types` to specify if the ingress traffic should be tagged or untagged. This property only has an effect when `vlan-filtering` is set to `yes`. The setting is enabled by default since RouterOS v7. | | **l2mtu** (*read-only*; Default: ) | L2MTU indicates the maximum size of the frame without a MAC header that can be sent by this interface. The L2MTU value will be automatically set by the bridge and it will use the lowest L2MTU value of any associated bridge port. This value cannot be manually changed. | | **last-member-interval** (*time*; Default: **1s**) | When the last client on the bridge port unsubscribes from a multicast group and the bridge is acting as an active querier, the bridge will send a group-specific IGMP/MLD query, to make sure that no other client is still subscribed. The setting changes the response time for these queries. In case no membership reports are received in a certain time period (`last-member-interval` \* `last-member-query-count`), the multicast group is removed from the multicast database (MDB). If the bridge port is configured with fast-leave, the multicast group is removed right away without sending any queries. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | | **last-member-query-count** (*integer: 0..4294967295*; Default: **2**) | How many times should `last-member-interval` pass until the IGMP/MLD snooping bridge stops forwarding a certain multicast stream. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | | **max-hops** (*integer: 6..40*; Default: **20**) | Bridge count which a BPDU can pass in an MSTP enabled network in the same region before BPDU is being ignored. This property only has an effect when `protocol-mode` is set to `mstp`. | | **max-learned-entries** (*integer: 0..4294967295 \| auto \| unlimited*; Default: **auto**) | Sets the maximum number of learned hosts for the bridge interface. The default value is `auto`, and it depends on the installed amount of RAM. It is possible to set a higher value than the default or choose the `unlimited` option, but it increases the risk of an out-of-memory condition. The default values for certain RAM sizes: 8192 for 64 MB;16384 for 128 MB;32768 for 256 MB;65536 for 512 MB;131072 for 1024 MB or higher. This limit specifically applies to the bridge interface, not the hardware limits on the switch FDB table. Even if the bridge limit is reached, the switch can continue to learn hosts up to its hardware limits and make correct forwarding decisions. However, these additional hosts will not show up in the `/interface/bridge/host` table nor can they be monitored. Additionally, hitting this limit could impact MLAG host synchronization. This setting has been available since RouterOS version 7.16. | | **max-message-age** (*time: 6s..40s*; Default: **00:00:20**) | Changes the Max Age value in BPDU packets, which are transmitted by the root bridge. A root bridge sends BPDUs with Max Age set to `max-message-age` value and a Message Age of 0. Every sequential bridge will increment the Message Age before sending its BPDUs. Once a bridge receives a BPDU where Message Age is equal to or greater than Max Age, the BPDU is ignored. This property only has an effect when `protocol-mode` is set to `stp` or `rstp`. | | **membership-interval** (*time*; Default: **4m20s**) | The amount of time after an entry in the Multicast Database (MDB) is removed if no IGMP/MLD membership reports are received on a bridge port. This property only has an effect when `igmp-snooping` is set to `yes`. | | **mld-version** (*1 \| 2*; Default: **1**) | Selects the MLD version in which MLD membership queries will be generated, when the bridge interface is acting as an MLD querier. This property only has an effect when the bridge has an active IPv6 address, `igmp-snooping` and `multicast-querier` are set to `yes`. | | **mtu** (*integer*; Default: **auto**) | Maximum transmission unit. By default, the bridge will set MTU automatically and it will use the lowest MTU value of any associated bridge port. The default bridge MTU value without any bridge ports added is 1500. The MTU value can be set manually, but it cannot exceed the bridge L2MTU or the lowest bridge port L2MTU. If a new bridge port is added with L2MTU which is smaller than the `actual-mtu` of the bridge (set by the `mtu` property), then the manually set value will be ignored and the bridge will act as if `mtu=auto` is set. When adding VLAN interfaces on the bridge, and when VLAN is using higher MTU than the default 1500, it is recommended to manually set the MTU of the bridge. | | **multicast-querier** (*yes \| no*; Default: **no**) | Multicast querier generates periodic IGMP/MLD general membership queries to which all IGMP/MLD capable devices respond with an IGMP/MLD membership report. Usually, a PIM (multicast) router or IGMP proxy generates these queries. By using this property you can make an IGMP/MLD snooping enabled bridge generate IGMP/MLD general membership queries. This property should be used whenever there is no active querier (PIM router or IGMP proxy) in a Layer2 network. Without a multicast querier in a Layer2 network, the Multicast Database (MDB) is not being updated; the learned entries will timeout and IGMP/MLD snooping will not function properly. Only untagged IGMP/MLD general membership queries are generated. IGMP queries are sent with the bridge interface's own IPv4 address as the source address (see `querier-uses-bridge-address`), MLD queries are sent with the IPv6 link-local address of the bridge interface. The bridge will not send queries if an external IGMP/MLD querier is detected (see the monitoring values `igmp-querier` and `mld-querier`). This property only has an effect when `igmp-snooping` is set to `yes`. | | **multicast-router** (*disabled \| permanent \| temporary-query*; Default: **temporary-query**) | A multicast router port is a port where a multicast router or querier is connected. On this port, unregistered multicast streams and IGMP/MLD membership reports will be sent. This setting changes the state of the multicast router for a bridge interface itself. This property can be used to send IGMP/MLD membership reports to the bridge interface for further multicast routing or proxying. This property only has an effect when `igmp-snooping` is set to `yes`.disabled - disabled multicast router state on the bridge interface. Unregistered multicast and IGMP/MLD membership reports are not sent to the bridge interface regardless of what is configured on the bridge interface.permanent - enabled multicast router state on the bridge interface. Unregistered multicast and IGMP/MLD membership reports are sent to the bridge interface itself regardless of what is configured on the bridge interface.temporary-query - automatically detect multicast router state on the bridge interface using IGMP/MLD queries. | | **name** (*text*; Default: **bridgeN**) | Name of the bridge interface. | | **port-cost-mode** (*long \| short*; Default: **long**) | Changes the port path-cost and internal-path-cost mode for bridged ports, utilizing automatic values based on interface speed. This setting does not impact bridged ports with manually configured `path-cost` or `internal-path-cost` properties. Below are examples illustrating the path-costs corresponding to specific data rates (with proportionate calculations for intermediate rates):
Path-cost tableData rateLongShort10 Mbps2,000,000100100 Mbps200,000191 Gbps20,000410 Gbps2,000225 Gbps800140 Gbps500150 Gbps4001100 Gbps2001
For HW offloaded bond interfaces, the highest path-cost among all bonded member ports is applied; this value remains unaffected by the total link speed of the bonding. For virtual interfaces (such as VLAN, EoIP, VXLAN and non-HW offloaded bond), as well as wifi, wireless, and 60GHz interfaces, a path-cost of 20,000 is assigned for long mode, and 10 for short mode. For dynamically bridged interfaces (e.g. wifi, wireless, PPP, VPLS), the path-cost defaults to 20,000 for long mode and 10 for short mode. However, this can be manually overridden by the service that dynamically adds interfaces to the bridge, for instance, by using the CAPsMAN `datapath.bridge-cost` setting. Use [port monitor](index.md#bridge-port-monitoring) to observe the applied path-cost. This property has an effect when `protocol-mode` is set to `stp`, `rstp`, or `mstp`. | | **priority** (*integer: 0..65535 decimal format or 0x0000-0xffff hex format*; Default: **32768 / 0x8000**) | Bridge priority, used by R/STP to determine the root bridge, used by MSTP to determine the CIST and IST regional root bridge. This property has no effect when `protocol-mode` is set to `none`. **Valid values:** The bridge priority must be set in steps of 4096 (0x1000). The 12 lowest bits are ignored. Valid values are: 0x0000, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0xf000 (or their decimal equivalents: 0, 4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 36864, 40960, 45056, 49152, 53248, 57344, 61440). | | **protocol-mode** (*none \| rstp \| stp \| mstp*; Default: **rstp**) | Select Spanning tree protocol (STP) or Rapid spanning tree protocol (RSTP) to ensure a loop-free topology for any bridged LAN. RSTP provides a faster spanning tree convergence after a topology change. Select MSTP to ensure loop-free topology across multiple VLANs. The forwarding of reserved MAC addresses that are in the **01:80:C2:00:00:0x** range is separated from `protocol-mode=none`, and is now available as a controllable property `forward-reserved-addresses` since RouterOS v7.16. | | **pvid** (*integer: 1..4094*; Default: **1**) | Port VLAN ID (pvid) specifies which VLAN the untagged ingress traffic is assigned to. It applies e.g. to frames sent from bridge IP and destined to a bridge port. This property only has an effect when `vlan-filtering` is set to `yes`. | | **querier-interval** (*time*; Default: **4m15s**) | Changes the timeout period for detected querier and multicast-router ports. This property only has an effect when `igmp-snooping` is set to `yes`. | | **querier-uses-bridge-address** (*yes \| no*; Default: **yes**) | When enabled, the bridge IGMP querier uses the bridge interface's own IPv4 address as the source address for IGMP query packets instead of the default 0.0.0.0. Some multicast clients consider queries from 0.0.0.0 invalid and do not respond, which can lead to multicast stream interruptions when snooping table entries time out. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes` and the bridge interface has an IPv4 address assigned. This setting applies only to IPv4 (IGMP). MLD queries always use the IPv6 link-local address of the bridge interface. | | **query-interval** (*time*; Default: **2m5s**) | Changes the interval at which IGMP/MLD general membership queries are sent out when the bridge interface is acting as an IGMP/MLD querier. The interval takes place when the last startup query is sent. This property only has an effect when `igmp-snooping` and `multicast-querier` is set to `yes`. | | **query-response-interval** (*time*; Default: **10s**) | The setting changes the response time for general IGMP/MLD queries when the bridge is active as an IGMP/MLD querier. This property only has an effect when `igmp-snooping` and `multicast-querier` is set to `yes`. | | **region-name** (*text*; Default: ) | MSTP region name. This property only has an effect when `protocol-mode` is set to `mstp`. | | **region-revision** (*integer: 0..65535*; Default: **0**) | MSTP configuration revision number. This property only has an effect when `protocol-mode` is set to `mstp`. | | **ra-guard** (*yes \| no*; Default: **no**) | RA guard - a security feature that validates incoming Router Advertisements against a list of authorized, trusted ports. | | **startup-query-count** (*integer: 0..4294967295*; Default: **2**) | Specifies how many times general IGMP/MLD queries must be sent when the bridge interface is enabled or the active querier times out. This property only has an effect when `igmp-snooping` and `multicast-querier` is set to `yes`. | | **startup-query-interval** (*time*; Default: **31s250ms**) | Specifies the interval between startup general IGMP/MLD queries. This property only has an effect when `igmp-snooping` and `multicast-querier` is set to `yes`. | | **transmit-hold-count** (*integer: 1..10*; Default: **6**) | The Transmit Hold Count used by the Port Transmit state machine to limit the transmission rate. | | **vlan-filtering** (*yes \| no*; Default: **no**) | Globally enables or disables VLAN functionality for the bridge. | :::danger Changing certain properties can cause the bridge to temporarily disable all ports. This must be taken into account whenever changing such properties on production environments since it can cause all packets to be temporarily dropped. Such properties include `vlan-filtering`, `protocol-mode`, `igmp-snooping`, `fast-forward` and others. ::: ### Example The following example demonstrates how to create and verify a basic bridge interface for simple Layer 2 switching. This configuration creates a bridge that combines multiple Ethernet ports into a single switched network segment. ```ros [admin@MikroTik] > /interface/bridge/add [admin@MikroTik] > interface bridge print Flags: X - disabled, R - running 0 R name="bridge1" mtu=auto actual-mtu=1500 l2mtu=65535 arp=enabled arp-timeout=auto mac-address=5E:D2:42:95:56:7F protocol-mode=rstp fast-forward=yes igmp-snooping=no auto-mac=yes ageing-time=5m priority=0x8000 max-message-age=20s forward-delay=15s transmit-hold-count=6 vlan-filtering=no dhcp-snooping=no ``` ### Bridge Monitoring To monitor the current status of a bridge interface, use the `monitor` command. **Sub-menu:** `/interface/bridge/monitor` | Property | Description | | :-- | :-- | | **bridge-id** (*priority.MAC address*) | Local bridge identifier, which is in the form of bridge-priority.bridge-MAC-address. | | **current-mac-address** (*MAC address*) | Current MAC address of the bridge. | | **designated-port-count** (*integer*) | Number of designated bridge ports. | | **declared-vlan-ids** (*integer 1..4094*) | VLANs declared on the bridge interface via [MVRP protocol](./index.md#mvrp). | | **fast-forward** (*yes \| no*) | Whether bridge fast-forward is active. | | **igmp-querier** (*none* \| *interface & IPv4 address*) | Shows a bridge port and source IP address from the detected IGMP querier. Only shows detected external IGMP querier, local bridge IGMP querier (including IGMP proxy and PIM) will not be displayed. Monitoring value appears only when `igmp-snooping` is enabled. | | **mld-querier** (*none* \| *interface & IPv6 address*) | Shows a bridge port and source IPv6 address from the detected MLD querier. Only shows detected external MLD querier, local bridge MLD querier will not be displayed. Monitoring value appears only when `igmp-snooping` is enabled and the bridge has an active IPv6 address. | | **mst-config-digest** (*integer*) | Computed hash of VLAN mappings to MST Instance IDs. | | **multicast-router** (*yes \| no*) | Shows if a multicast router is detected on the port. Monitoring value appears only when `igmp-snooping` is enabled. | | **port-count** (*integer*) | Number of the bridge ports. | | **regional-root-bridge-id** (*priority.MAC address*) | The regional root bridge ID, which is in the form of bridge-priority.bridge-MAC-address. Only applies when MSTP is enabled. | | **registered-vlan-ids** (*integer 1..4094*) | VLANs registered on the bridge interface via [MVRP protocol](./index.md#mvrp). | | **root-bridge** (*yes \| no*) | Shows whether the bridge is the root bridge of the spanning tree. | | **root-bridge-id** (*priority.MAC address*) | The root bridge ID, which is in the form of bridge-priority.bridge-MAC-address. | | **root-path-cost** (*integer*) | The total cost of the path to the root-bridge. | | **root-port** (*name*) | Port to which the root bridge is connected. | | **state** (*enabled \| disabled*) | State of the bridge. | ```ros [admin@MikroTik] /interface/bridge/monitor bridge1 state: enabled current-mac-address: 2C:C8:1B:FF:92:F4 bridge-id: 0x1000.2C:C8:1B:FF:92:F4 root-bridge: yes root-bridge-id: 0x1000.2C:C8:1B:FF:92:F4 regional-root-bridge-id: 0x1000.2C:C8:1B:FF:92:F4 root-path-cost: 0 root-port: none port-count: 2 designated-port-count: 2 mst-config-digest: d2b171a8ad95f593c241fc33d419a88c fast-forward: no multicast-router: no igmp-querier: none mld-querier: none declared-vlan-ids: 1 registered-vlan-ids: 1 ``` ## Spanning Tree Protocol --- RouterOS bridge interfaces are capable of running Spanning Tree Protocol to ensure a loop-free and redundant topology. For small networks with just 2 bridges, STP does not bring many benefits, but for larger networks, properly configured STP is very crucial, leaving STP-related values at default may result in a completely unreachable network in case of even a single bridge failure. To achieve a proper loop-free and redundant topology, it is necessary to properly set bridge priorities, port path costs, and port priorities. :::danger In RouterOS it is possible to set any value for bridge priority between 0 and 65535, the IEEE 802.1W standard states that the bridge priority must be in steps of 4096. This can cause incompatibility issues between devices that do not support such values. To avoid compatibility issues, it is recommended to use only these priorities: 0, 4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 36864, 40960, 45056, 49152, 53248, 57344, 61440 ::: STP has multiple variants; currently, RouterOS supports STP, RSTP, and MSTP. Depending on needs, either one of them can be used; some devices are able to run some of these protocols using hardware offloading; detailed information about which devices support it can be found in the Hardware Offloading section. STP is considered to be outdated and slow; it has been almost entirely replaced in all network topologies by RSTP, which is backward compatible with STP. For network topologies that depend on VLANs, it is recommended to use MSTP since it is a VLAN-aware protocol and gives the ability to do load balancing per VLAN groups. There are a lot of considerations that should be made when designing an STP-enabled network, more detailed case studies can be found in the [Spanning Tree Protocol](./user-guides/spanning-tree-protocol.md) article. In RouterOS, the `protocol-mode` property controls the used STP variant. :::info RouterOS bridge does not work with PVST and its variants. The PVST BPDUs (with a MAC destination 01:00:0C:CC:CC:CD) are treated by RouterOS bridges as typical multicast packets. In simpler terms, they undergo RouterOS bridge/switch forwarding logic and may get tagged or untagged. ::: :::info By the IEEE 802.1ad standard, the BPDUs from bridges that comply with IEEE 802.1Q are not compatible with IEEE 802.1ad bridges. This means that the same bridge VLAN protocol should be used across all bridges in a single Layer2 domain; otherwise (R/M)STP will not function properly. ::: ### Per-port STP There might be certain situations where you want to limit STP functionality on a single port or multiple ports. Below you can find examples for different use cases. :::danger Be careful when changing the default (R/M)STP functionality; make sure you understand the working principles of STP and BPDUs. Misconfigured (R/M)STP can cause unexpected behavior. ::: #### Create Edge Ports Edge ports are used for connections to end devices that have no other bridges attached, such as workstations or routers. Setting a bridge port as an edge port will restrict it from sending BPDUs (Bridge Protocol Data Units) and will cause it to ignore any received BPDUs. This allows the port to transition directly to the forwarding state, bypassing the standard STP learning and listening phases, which reduces network convergence time. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 edge=yes add bridge=bridge1 interface=ether2 ``` ## Drop Received BPDUs The bridge firewall filter and NAT rules cannot drop BPDUs when the bridge has STP/RSTP/MSTP enabled because BPDUs receive special processing within the bridge. However, dropping received BPDUs on a specific port can be accomplished on some switch chips using ACL rules: On MikroTik devices with a Marvell Prestera switch: ```ros /interface/ethernet/switch/rule add dst-mac-address=01:80:C2:00:00:00/FF:FF:FF:FF:FF:FF new-dst-ports="" port=ether1 switch=switch1 ``` On CRS1xx/CRS2xx series devices with Access Control List (ACL) support: ```ros /interface/ethernet/switch/acl add action=drop mac-dst-address=01:80:C2:00:00:00 src-ports=ether1 ``` This configuration drops all received BPDUs on **ether1**. :::danger If you intend to drop received BPDUs on a port, ensure that BPDUs are also prevented from being sent out through the interface that this port is connected to. A root bridge always transmits BPDUs and normally waits for a superior BPDU (from a bridge with a lower bridge ID). However, the bridge must temporarily disable the new root port when transitioning from a root bridge to a designated bridge. If you block BPDUs on only one side, the port will continuously flap between states. ::: #### Enable BPDU guard The BPDU Guard feature provides an additional layer of security for bridge ports. It is designed to prevent potential network issues by blocking a port if it receives a BPDU (Bridge Protocol Data Unit), which indicates an unauthorized bridge device has been connected. This is particularly useful for edge ports that should only connect to end devices. In this example, if **ether1** receives a BPDU, the port will be automatically blocked and will require manual intervention to re-enable it. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 bpdu-guard=yes add bridge=bridge1 interface=ether2 ``` #### Enable Root Guard Root Guard is a spanning tree security feature that prevents a port from becoming the root port, thereby protecting the active spanning tree topology from being influenced by external bridges. In this example, **ether1** is configured with `restricted-role=yes`. This setting prevents the port from becoming the root port for the CIST or any MSTI, regardless of its best spanning tree priority vector. Such a port will be selected as an Alternate Port (in discarding state) and will remain in that state as long as it continues to receive superior BPDUs. It will automatically transition to the forwarding state when it no longer detects a superior root path. Network administrators may enable this setting to safeguard against external bridges influencing the active spanning tree. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 restricted-role=yes add bridge=bridge1 interface=ether2 [admin@MikroTik] /interface/bridge/port/monitor [find] interface: ether1 ether2 status: in-bridge in-bridge port-id: 0x80.1 0x80.2 role: alternate-port designated-port edge-port: no yes edge-port-discovery: yes yes point-to-point-port: yes yes external-fdb: no no sending-rstp: yes yes learning: no yes forwarding: no yes actual-path-cost: 2000 2000 internal-root-path-cost: 2000 designated-bridge-id: 0x7000.64:D1:54:C7:3A:6E designated-internal-cost: 0 0 designated-port-id: 0x80.1 0x80.2 designated-remaining-hops: 20 20 tx-rx-bpdu: 2/363 4/1049 discard-transitions: 0 0 forward-transitions: 0 0 tx-rx-tc: 0/2 2/4 topology-changes: 0 1 last-topology-change: 34m53s multicast-router: no yes hw-offload-group: switch1 switch1 declared-vlan-ids: registered-vlan-ids: ``` ## Bridge Settings --- Under the bridge settings menu, it is possible to control certain features for all bridge interfaces and monitor global bridge counters. **Sub-menu:** `/interface/bridge/settings` | Property | Description | | :-- | :-- | | **use-ip-firewall** (*yes \| no*; Default: **no**) | Direct bridged traffic to [IP/IPv6 firewall](../firewall-and-quality-of-service/firewall/index.md) (prerouting, forward, and postrouting sections of IP/IPv6 routing, see more details on [Packet Flow](../firewall-and-quality-of-service/packet-flow-in-routeros.md#flow-of-bridged-packet) article). Below are some use cases when this setting can be enabled to accomplish certain tasks: In case you want to assign Simple Queues or global Queue Tree for traffic flowing through bridged ports.In case you want to use IP/IPv6 firewall capabilities for traffic flowing through bridged ports, which would normally bypass IP/IPv6 firewall.**Caution:** Enabling the `use-ip-firewall` feature will turn off bridge [Fast Path](../firewall-and-quality-of-service/packet-flow-in-routeros.md#fast-path), which in turn affects the ability to [fasttrack](../firewall-and-quality-of-service/packet-flow-in-routeros.md#fasttrack) connections going over that bridge. And because this setting introduces additional processing steps (prerouting, forward and postrouting chains), it will increase CPU usage even more when forwarding packets. **Routed traffic**, including traffic from VLAN interfaces (e.g., `/interface/vlan` created on the bridge), **is already processed by the IP firewall**. In such cases, enabling this setting has no additional effect. | | **use-ip-firewall-for-pppoe** (*yes \| no*; Default: **no**) | Direct bridged un-encrypted PPPoE encapsulated traffic to IP/IPv6 firewall. This property only has an effect when `use-ip-firewall` is set to `yes`. | | **use-ip-firewall-for-vlan** (*yes \| no*; Default: **no**) | Direct bridged VLAN tagged traffic to IP/IPv6 firewall. This property only has an effect when `use-ip-firewall` is set to `yes`. If you need to use the IP/IPv6 firewall and bridge `vlan-filtering` is enabled (which involves VLAN tag handling), then you should also enable `use-ip-firewall-for-vlan=yes`. When this setting is enabled and packets are routed between VLAN interfaces (e.g., `/interface/vlan`), the `in-interface` in the IP firewall's **prerouting** chain will match the bridge interface instead of the individual VLAN interface. | | **allow-fast-path** (*yes \| no*; Default: **yes**) | Whether to enable a bridge Fast Path globally. | | **bridge-fast-path-active** (*yes \| no*; Default: *)* | Shows whether a bridge Fast Path is active globally. Fast Path status per bridge interface is not displayed. | | **bridge-fast-path-packets** (*integer*; Default: *)* | Shows packet count forwarded by bridge Fast Path. | | **bridge-fast-path-bytes** (*integer*; Default: *)* | Shows byte count forwarded by bridge Fast Path. | | **bridge-fast-forward-packets** (*integer*; Default: *)* | Shows packet count forwarded by bridge Fast Forward. | | **bridge-fast-forward-bytes** (*integer*; Default: *)* | Shows byte count forwarded by bridge Fast Forward. | :::warning In case you want to assign Simple Queues or global Queue Trees to traffic that is being forwarded by a bridge, then you need to enable the `use-ip-firewall` property. Without using this property the bridge traffic will never reach the postrouting chain. Simple Queues and global Queue Trees are working in the postrouting chain. To assign Simple Queues or global Queue Trees for VLAN or PPPoE traffic in a bridge you should enable the appropriate properties as well. ::: ## Port Settings --- The Port submenu is used to add interfaces in a particular bridge. **Sub-menu:** `/interface/bridge/port` | Property | Description | | :-- | :-- | | **auto-isolate** (*yes \| no*; Default: **no**) | When enabled, it prevents a port from moving from discarding state into forwarding state if no BPDUs are received from the neighboring bridge. The port will change into a forwarding state only when a BPDU is received. This property only has an effect when `protocol-mode` is set to `rstp` or `mstp` and `edge` is set to `no`. | | **bpdu-guard** (*yes \| no*; Default: **no**) | Enables or disables the BPDU Guard feature on a port. This feature puts the port in a disabled role if it receives a BPDU and requires the port to be manually disabled and enabled if a BPDU is received. It should be used to prevent a bridge from BPDU-related attacks. This property has no effect when `protocol-mode` is set to `none`. | | **bridge** (*name*; Default: **none**) | The bridge interface where the respective interface is grouped. | | **broadcast-flood** (*yes \| no*; Default: **yes**) | When enabled, the bridge floods broadcast traffic to all bridge egress ports. When disabled, the bridge drops broadcast traffic on egress ports. It can be used to filter all broadcast traffic on an egress port. Broadcast traffic is considered as traffic that uses **FF:FF:FF:FF:FF:FF** as the destination MAC address. Such traffic is crucial for many protocols such as DHCP, ARP, NDP, BOOTP (Netinstall), and others. This option does not limit traffic flood to the CPU. | | **edge** (*auto \| no \| no-discover \| yes \| yes-discover*; Default: **auto**) | Set a port as an edge port or a non-edge port, or enable edge discovery. Edge ports are connected to a LAN that has no other bridges attached. An edge port will skip the learning and the listening states in STP and will transition directly to the forwarding state. This reduces the STP initialization time. If the port is configured to discover an edge port, then as soon as the bridge detects a BPDU coming to an edge port, the port becomes a non-edge port. This property has no effect when `protocol-mode` is set to `none`.no - non-edge port with disabled discovery. It will participate in learning and listening states in STP. It will not transition to the forwarding state until it exchanges BPDUs and reaches agreement with the connected bridge. If no BPDU is received, the port may remain in a non-forwarding state indefinitely.no-discover - non-edge port with enabled discovery. It will participate in learning and listening states in STP. A port can become an edge port if no BPDU is received.yes - edge port without discovery. It will transition directly to forwarding state.yes-discover - edge port with enabled discovery. It will transition directly to forwarding state.auto - same as no-discover, but will additionally detect if a bridge port is a Wireless interface with disabled bridge-mode. Such an interface will be automatically set as an edge port without discovery. | | **fast-leave** (*yes \| no*; Default: **no**) | Enables the IGMP/MLD fast leave feature on the bridge port. The bridge will stop forwarding multicast traffic to a bridge port when an IGMP/MLD leave message is received. This property only has an effect when `igmp-snooping` is set to `yes`. | | **frame-types** (*admit-all \| admit-only-untagged-and-priority-tagged \| admit-only-vlan-tagged*; Default: **admit-all**) | Specifies allowed ingress frame types on a bridge port. This property only has an effect when `vlan-filtering` is set to `yes`. | | **ingress-filtering** (*yes \| no*; Default: **yes**) | Enables or disables VLAN ingress filtering, which checks if the ingress port is a member of the received VLAN ID in the bridge VLAN table. Should be used with `frame-types` to specify if the ingress traffic should be tagged or untagged. This property only has an effect when `vlan-filtering` is set to `yes`. The setting is enabled by default since RouterOS v7. | | **learn** (*auto \| no \| yes*; Default: **auto**) | Changes MAC learning behavior on a bridge portyes - enables MAC learningno - disables MAC learningauto - detects if the bridge port is a Wireless interface and uses a Wireless registration table instead of MAC learning, will use the Wireless registration table if the Wireless interface is set to one of ap-bridge, bridge, wds-slave mode and bridge mode for the Wireless interface is disabled. | | **multicast-router** (*disabled \| permanent \| temporary-query*; Default: **temporary-query**) | A multicast router port is a port where a multicast router or querier is connected. On this port, unregistered multicast streams and IGMP/MLD membership reports will be sent. This setting changes the state of the multicast router for bridge ports. This property can be used to send IGMP/MLD membership reports to certain bridge ports for further multicast routing or proxying. This property only has an effect when `igmp-snooping` is set to `yes`.disabled - disabled multicast router state on the bridge port. Unregistered multicast and IGMP/MLD membership reports are not sent to the bridge port regardless of what is connected to it.permanent - enabled multicast router state on the bridge port. Unregistered multicast and IGMP/MLD membership reports are sent to the bridge port regardless of what is connected to it.temporary-query - automatically detect multicast router state on the bridge port using IGMP/MLD queries. | | **horizon** (*integer 0..429496729*; Default: **none**) | Use split horizon bridging to prevent bridging loops. Set the same value for a group of ports, to prevent them from sending data to ports with the same horizon value. Split horizon is a software feature that disables hardware offloading. | | **hw** (*yes \| no*; Default: **yes**) | Allows enabling or disabling [hardware offloading](index.md#bridge-hardware-offloading) on interfaces capable of HW offloading. For software interfaces like [EoIP](../virtual-private-networks/eoip.md) or [VLAN](./vlan.md), this setting is ignored and has no effect. Certain bridge or port functions can automatically disable HW offloading, use the `print` command to see whether the "H" flag is active. | | **internal-path-cost** (*integer: 1..200000000*; Default: ) | Path cost to the interface for MSTI0 inside a region. If not manually configured, the bridge automatically determines the internal-path-cost based on the interface speed and the `port-cost-mode` setting. To revert to the automatic determination and remove any manually applied value, simply use an exclamation mark before the `internal-path-cost` property. This property only has an effect when `protocol-mode` is set to `mstp`. `/interface/bridge/port/set [find interface=sfp28-1] !internal-path-cost` Use [port monitor](index.md#bridge-port-monitoring) to observe the applied internal-path-cost. | | **interface** (*name*; Default: **none**) | Name of the interface or interface list. | | **path-cost** (*integer: 1..200000000*; Default: ) | Path cost to the interface, used by STP and RSTP to determine the best path, and used by MSTP to determine the best path between regions. If not manually configured, the bridge automatically determines the path-cost based on the interface speed and the `port-cost-mode` setting. To revert to the automatic determination and remove any manually applied value, simply use an exclamation mark before the `path-cost` property. This property has no effect when `protocol-mode` is set to `none`. `/interface/bridge/port/set [find interface=sfp28-1] !path-cost` Use [port monitor](index.md#bridge-port-monitoring) to observe the applied path-cost. | | **point-to-point** (*auto \| yes \| no*; Default: **auto**) | Specifies if a bridge port is connected to a bridge using a point-to-point link for faster convergence in case of failure. By setting this property to `yes`, you are forcing the link to be a point-to-point link, which will skip the checking mechanism, which detects and waits for BPDUs from other devices on this single link. By setting this property to `no`, you are expecting that a link can receive BPDUs from multiple devices. By setting the property to `yes`, you are significantly improving (R/M)STP convergence time. In general, you should only set this property to `no` if it is possible that another device can be connected to a link. This is mostly relevant to Wireless mediums and Ethernet hubs. If the Ethernet link is full-duplex, `auto` enables point-to-point functionality. This property has no effect when `protocol-mode` is set to `none`. | | **priority** (*0x00 \| 0x10 \| 0x20 \| 0x30 \| 0x40 \| 0x50 \| 0x60 \| 0x70 \| 0x80 \| 0x90 \| 0xa0 \| 0xb0 \| 0xc0 \| 0xd0 \| 0xe0 \| 0xf0*; Default: **0x80**) | The priority of the interface, used by STP to determine the root port, used by MSTP to determine the root port between regions. Must be set in steps of 16 (0x10). | | **pvid** (*integer 1..4094*; Default: **1**) | Port VLAN ID (pvid) specifies which VLAN the untagged ingress traffic is assigned to. This property only has an effect when `vlan-filtering` is set to `yes`. | | **restricted-role** (*yes \| no*; Default: **no**) | Enables or disables the restricted role on a port. When enabled, it prevents the port from becoming the root port for the CIST or any MSTI, regardless of its best spanning tree priority vector. Such a port will be selected as an Alternate Port (discarding state) and remains so as long as it continues to receive superior BPDUs. It will automatically transition to the forwarding state when it no longer detects a superior root path. Network administrators may enable this setting to safeguard against external bridges influencing the active spanning tree, a feature also known as root-guard or root-protection. This property has an effect when `protocol-mode` is set to `stp`, `rstp`, or `mstp` (support for STP and RSTP is available since RouterOS v7.14). | | **restricted-tcn** (*yes \| no*; Default: **no**) | Enables or disables topology change notification (TCN) handling on a port. When enabled, it causes the port not to propagate received topology change notifications to other ports, and any changes caused by the port itself do not result in topology change notification to other ports. This parameter is disabled by default. It can be set by a network administrator to prevent external bridges from causing MAC address flushing in the local network. This property has an effect when `protocol-mode` is set to `stp`, `rstp`, or `mstp` (support for STP and RSTP is available since RouterOS v7.14). | | **tag-stacking** (*yes \| no*; Default: **no**) | Forces all packets to be treated as untagged packets. Packets on the ingress port will be tagged with another VLAN tag regardless of whether a VLAN tag already exists. Packets will be tagged with a VLAN ID that matches the `pvid`value and will use EtherType that is specified in `ether-type`. This property only has an effect when `vlan-filtering` is set to `yes`. | | **trusted** (*yes \| no*; Default: **no**) | When enabled, it allows forwarding DHCP packets towards the DHCP server through this port. Mainly used to prevent unauthorized servers from providing malicious information for users. This property only has an effect when `dhcp-snooping` is set to `yes`. | | **trusted-dhcpv6**(*yes \| no*; Default: **no**) | When enabled, it allows forwarding DHCPv6 packets towards the DHCP server through this port. Mainly used to prevent unauthorized servers from providing malicious information for users. This property only has an effect when `dhcpv6-snooping` is set to `yes`. | | **trusted-ra** (*yes \| no*; Default: **no**) | Specifies whether the port is permitted to forward IPv6 Router Advertisement messages; set to **yes** for ports connected to legitimate routers and **no** to block unauthorized sources. This property only has an effect when `ra-guard` is set to `yes`. | | **unknown-multicast-flood** (*yes \| no*; Default: **yes**) | Changes the multicast flood option on the bridge port and only controls the egress traffic. When enabled, the bridge allows flooding multicast packets to the specified bridge port, but when disabled, the bridge restricts multicast traffic from being flooded to the specified bridge port. The setting affects all multicast traffic. This includes non-IP, IPv4, IPv6 and the link-local multicast ranges (e.g. 224.0.0.0/24 and ff02::1). Note that when `igmp-snooping` is enabled and an IGMP/MLD querier is detected, the bridge will automatically restrict unknown IP multicast from being flooded, so the setting is not mandatory for IGMP/MLD snooping setups. When using this setting together with `igmp-snooping`, the only multicast traffic that is allowed on the bridge port is the known multicast from the MDB table. | | **unknown-unicast-flood** (*yes \| no*; Default: **yes**) | Changes the unknown unicast flood option on the bridge port and only controls the egress traffic. When enabled, the bridge allows flooding unknown unicast packets to the specified bridge port, but when disabled, the bridge restricts unknown unicast traffic from being flooded to the specified bridge port. If a MAC address is not learned in the host table, then the traffic is considered unknown unicast traffic and will be flooded to all ports. MAC address is learned as soon as a packet on a bridge port is received and the source MAC address is added to the bridge host table. Since it is required for the bridge to receive at least one packet on the bridge port to learn the MAC address, it is recommended to use static bridge host entries to avoid packets being dropped until the MAC address has been learned. | :::info RouterOS can handle a maximum of 1024 bridged interfaces per bridge; this limit is fixed and cannot be modified. If you try to add more interfaces as bridge ports, it may lead to unpredictable behavior. ::: ### Example This example demonstrates how to add Ethernet ports to an existing bridge interface to create a simple Layer 2 switching setup. By adding **ether1** and **ether2** to **bridge1**, these physical ports become part of a single switched network segment, allowing devices connected to either port to communicate with each other as if they were on the same LAN. First, add each port to the bridge interface: ```ros [admin@MikroTik] /interface/bridge/port/add bridge=bridge1 interface=ether1 [admin@MikroTik] /interface/bridge/port/add bridge=bridge1 interface=ether2 ``` Verify the configuration by displaying the bridge port table: ```ros [admin@MikroTik] /interface/bridge/port/print Flags: X - disabled, I - inactive, D - dynamic, H - hw-offload # INTERFACE BRIDGE HW PVID PRIORITY PATH-COST INTERNAL-PATH-COST HORIZON 0 ether1 bridge1 yes 100 0x80 10 10 none 1 ether2 bridge1 yes 200 0x80 10 10 none ``` The output confirms both ports are now bridged together. The **H** flag indicates that hardware offloading is active, meaning the switch chip is handling packet forwarding for optimal performance. Each port is assigned a default PVID (Port VLAN ID) of 100 and 200 respectively, and both use the standard STP priority of 0x80. ### Interface Lists Starting with RouterOS v6.41, interface lists can be added as bridge ports and sorted. Interface lists simplify firewall rule configuration by grouping multiple interfaces together. The following example demonstrates how to add an interface list to a bridge: ```ros /interface/list add name=LAN1 add name=LAN2 /interface/list/member add interface=ether1 list=LAN1 add interface=ether2 list=LAN1 add interface=ether3 list=LAN2 add interface=ether4 list=LAN2 /interface/bridge/port add bridge=bridge1 interface=LAN1 add bridge=bridge1 interface=LAN2 ``` When interface lists are added to a bridge, the individual ports from those lists appear as dynamic ports entries: ```ros [admin@MikroTik] /interface/bridge/port> pr Flags: X - disabled, I - inactive, D - dynamic, H - hw-offload # INTERFACE BRIDGE HW PVID PRIORITY PATH-COST INTERNAL-PATH-COST HORIZON 0 LAN1 bridge1 yes 1 0x80 10 10 none 1 D ether1 bridge1 yes 1 0x80 10 10 none 2 D ether2 bridge1 yes 1 0x80 10 10 none 3 LAN2 bridge1 yes 1 0x80 10 10 none 4 D ether3 bridge1 yes 1 0x80 10 10 none 5 D ether4 bridge1 yes 1 0x80 10 10 none ``` The order in which interface lists appear can be rearranged using the `move` command. The second parameter specifies the position before which the selected interface list should be placed. The following example demonstrates how to sort interface lists: ```ros [admin@MikroTik] > /interface/bridge/port/move 3 0 [admin@MikroTik] > /interface/bridge/port/print Flags: X - disabled, I - inactive, D - dynamic, H - hw-offload # INTERFACE BRIDGE HW PVID PRIORITY PATH-COST INTERNAL-PATH-COST HORIZON 0 LAN2 bridge1 yes 1 0x80 10 10 none 1 D ether3 bridge1 yes 1 0x80 10 10 none 2 D ether4 bridge1 yes 1 0x80 10 10 none 3 LAN1 bridge1 yes 1 0x80 10 10 none 4 D ether1 bridge1 yes 1 0x80 10 10 none 5 D ether2 bridge1 yes 1 0x80 10 10 none ``` :::warning When using the `move` command, the second parameter represents the "before id" position, which determines where the selected interface list will be moved. If the first interface list is moved to the position of the second interface list, the command has no effect since the first list would already be positioned before the second list. ::: ### Interface Lists in VLAN Table Starting from RouterOS version 7.17, you can use interface lists for the `tagged` and `untagged` properties in the bridge VLAN table. This enhancement allows for more flexible VLAN assignment to ports by simply modifying the interface list members, rather than updating each bridge VLAN entry individually. If different interface lists are specified for the `tagged` and `untagged` settings, and there is overlap between the interface members, the `untagged` list takes priority. You can check the current interface configuration using the `current-tagged` and `current-untagged` properties with the `print` command. The following example demonstrates how new interfaces can be added to existing interface lists, automatically updating the bridge port and VLAN table without directly modifying settings in those menus: ```ros /interface/list add name=vlan10_untagged add name=vlan20_untagged add name=vlan_tagged /interface/list/member add interface=ether2 list=vlan10_untagged add interface=ether3 list=vlan10_untagged add interface=ether4 list=vlan20_untagged add interface=sfp-sfpplus1 list=vlan_tagged /interface/bridge add frame-types=admit-only-vlan-tagged name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 frame-types=admit-only-untagged-and-priority-tagged interface=vlan10_untagged pvid=10 add bridge=bridge1 frame-types=admit-only-untagged-and-priority-tagged interface=vlan20_untagged pvid=20 add bridge=bridge1 frame-types=admit-only-vlan-tagged interface=vlan_tagged /interface/bridge/vlan add bridge=bridge1 tagged=vlan_tagged vlan-ids=10 add bridge=bridge1 tagged=vlan_tagged vlan-ids=20 [admin@MikroTik] /interface/bridge/port/print Flags: D - DYNAMIC; H - HW-OFFLOAD Columns: INTERFACE, BRIDGE, HW, PVID, PRIORITY, HORIZON # INTERFACE BRIDGE HW PVID PRIORITY HORIZON 0 vlan10_untagged bridge1 yes 10 0x80 none 1 DH ether2 bridge1 yes 10 0x80 none 2 DH ether3 bridge1 yes 10 0x80 none 3 vlan20_untagged bridge1 yes 20 0x80 none 4 DH ether4 bridge1 yes 20 0x80 none 5 vlan_tagged bridge1 yes 1 0x80 none 6 DH sfp-sfpplus1 bridge1 yes 1 0x80 none [admin@MikroTik] /interface/bridge/vlan/print Flags: D - DYNAMIC Columns: BRIDGE, VLAN-IDS, CURRENT-TAGGED, CURRENT-UNTAGGED # BRIDGE VLAN-IDS CURRENT-TAGGED CURRENT-UNTAGGED ;;; added by pvid 0 D bridge1 10 ether2 ether3 ;;; added by pvid 1 D bridge1 20 ether4 2 bridge1 10 sfp-sfpplus1 3 bridge1 20 sfp-sfpplus1 # make necessary changes to interface list members: /interface/list/member/add list=vlan20_untagged interface=ether5 /interface/list/member/add list=vlan_tagged interface=sfp-sfpplus2 # verify changes in bridge port and vlan menus: [admin@MikroTik] > /interface/bridge/port/print Flags: D - DYNAMIC; H - HW-OFFLOAD Columns: INTERFACE, BRIDGE, HW, PVID, PRIORITY, HORIZON # INTERFACE BRIDGE HW PVID PRIORITY HORIZON 0 vlan10_untagged bridge1 yes 10 0x80 none 1 DH ether2 bridge1 yes 10 0x80 none 2 DH ether3 bridge1 yes 10 0x80 none 3 vlan20_untagged bridge1 yes 20 0x80 none 4 DH ether4 bridge1 yes 20 0x80 none 5 DH ether5 bridge1 yes 20 0x80 none 6 vlan_tagged bridge1 yes 1 0x80 none 7 DH sfp-sfpplus1 bridge1 yes 1 0x80 none 8 DH sfp-sfpplus2 bridge1 yes 1 0x80 none [admin@MikroTik] > /interface/bridge/vlan/print Flags: D - DYNAMIC Columns: BRIDGE, VLAN-IDS, CURRENT-TAGGED, CURRENT-UNTAGGED # BRIDGE VLAN-IDS CURRENT-TAGGED CURRENT-UNTAGGED ;;; added by pvid 0 D bridge1 10 ether2 ether3 ;;; added by pvid 1 D bridge1 20 ether4 ether5 2 bridge1 10 sfp-sfpplus1 sfp-sfpplus2 3 bridge1 20 sfp-sfpplus1 sfp-sfpplus2 ``` ### Bridge Port Monitoring To monitor the current status of bridge ports, use the `monitor` command. **Sub-menu:** `/interface/bridge/port/monitor` | Property | Description | | :-- | :-- | | **actual-path-cost** (*integer: 1..200000000*) | Shows the actual port path-cost. Either manually applied or automatically determined based on the interface speed and the `port-cost-mode` setting. | | **declared-vlan-ids** (*integer 1..4094*) | VLANs declared by the interface via [MVRP Protocol](./index.md#mvrp). | | **designated-bridge-id** (*priority.MAC address*) | Shows the designated bridge identifier, as determined from the port's priority vector. | | **designated-cost** (*integer*) | Shows the designated root-path-cost, as determined from the port's priority vector. | | **designated-internal-cost** (*integer*) | Shows the designated internal-root-path-cost, as determined from the port's priority vector. | | **designated-message-age**(*time)* | Shows the designated message age, as determined from the port's priority vector. | | **designated-max-age** (*time)* | Shows the designated max age, as determined from the port's priority vector. The BPDU packet can pass as many bridges as specified in the `max-message-age` parameter. | | **designated-port-id** (*priority*.*integer*) | Shows the designated port identifier, as determined from the port's priority vector. | | **designated-remaining-hops** (*integer*) | Shows the designated remaining hops, as determined from the port's priority vector. Number of hops that a packet is allowed to traverse before reaching its destination. | | **discard-transitions** (*integer*) | Counter, registering how often port transitions into discarding state. | | **edge-port** (*yes \| no*) | Whether the port is an edge port or not. | | **edge-port-discovery** (*yes \| no*) | Whether the port is set to automatically detect edge ports. | | **external-fdb** (*yes \| no*) | Whether the registration table is used instead of a forwarding database. | | **forwarding** (*yes \| no*) | Shows if the port is not blocked by (R/M)STP. | | **forward-transitions** (*integer*) | Counter, registering how often port transitions into forwarding state | | **hw-offload-group** (*switchX*) | Switch chip used by the port. | | **interface** (*name*) | Interface name. | | **last-topology-change** (*time)* | Last topology change timer, records time since the last change. | | **learning** (*yes \| no*) | Shows whether the port is capable of learning MAC addresses. | | **multicast-router** (*yes \| no*) | Shows if a multicast router is detected on the port. Monitoring value appears only when `igmp-snooping` is enabled. | | **registered-vlan-ids** (*integer 1..4094*) | VLANs where the interface is registered via [MVRP Protocol](./index.md#mvrp). | | **port-id** (*priority*.*integer*) | In Spanning Tree Protocol each port has a unique Port Identifier. Priority[hex] + port number. | | **point-to-point-port** (*yes \| no*) | Whether the port is connected to a bridge port using full-duplex (yes) or half-duplex (no). | | **role** (*designated \| root-port \| alternate \| backup \| disabled*) | (R/M)STP algorithm assigned port role: disabled-port - disabled or inactive port.root-port - port that is facing towards the root bridge and has the best (lowest cost) path to the root bridge. Only one root port is elected per bridge (except the root bridge itself).alternative-port - port that is facing towards the root bridge, but is not going to forward traffic. Port provides a backup path to the root bridge if the current root port fails.designated-port - port that is facing away from the root bridge and forwards traffic away from the root bridge to downstream devices.backup-port - port that is facing away from the root bridge, but is going to forward traffic. Port that serves as a backup for a designated port on the same segment. In RouterOS, the **role** monitoring property displays RSTP roles, such as `alternate-port` and `backup-port`, even when STP mode is enabled. While this is technically incorrect, it does not affect the operation of STP. This is because STP treats all blocked ports the same, without differentiating their purpose (e.g., as potential backup paths). The displayed roles are simply a reflection of RSTP functionality and have no practical impact when STP is in use. See more details on [STP and RSTP page](./user-guides/spanning-tree-protocol.md#stp-and-rstp). | | **root-path-cost** (*integer*) | The total cost of the path to the root-bridge. | | **sending-rstp** (*yes \| no*) | Whether the port is using RSTP or MSTP BPDU types. A port will transit to STP type when RSTP/MSTP enabled port receives an STP BPDU. This setting **does not** indicate whether the BPDUs are actually sent. | | **status** (*in-bridge \| inactive*) | Port status:in-bridge - port is enabledinactive - port is disabled. | | **tx-rx-bpdu** (*integer*) | Sent/received bpdu messages counter. | | **tx-rx-tc** (*integer*) | Topology change messages transmitted/received. | | **topology-changes** (*integer*) | Topology change counter. | ```ros [admin@MikroTik] /interface/bridge/port/monitor [find interface=ether1] interface: ether1 status: in-bridge port-id: 0x80.1 role: root-port edge-port: no edge-port-discovery: yes point-to-point-port: yes external-fdb: no sending-rstp: yes learning: yes forwarding: yes actual-path-cost: 20000 internal-root-path-cost: 20000 designated-bridge-id: 0x1000.2C:C8:1B:FF:92:F4 designated-internal-cost: 0 designated-port-id: 0x80.1 designated-remaining-hops: 20 tx-rx-bpdu: 3/63 discard-transitions: 0 forward-transitions: 1 tx-rx-tc: 2/0 topology-changes: 1 last-topology-change: 2m5s multicast-router: no hw-offload-group: switch1 declared-vlan-ids: 1 registered-vlan-ids: 1 ``` ## Hosts Table --- The hosts table displays MAC addresses that have been learned on a bridge interface. This table also shows various flags that provide additional information about each host entry. Access the hosts table through the `/interface/bridge/host` submenu. **Sub-menu:** `/interface/bridge/host` | Property | Description | | :-- | :-- | | **bridge** (*read-only: name*) | The bridge to which the host entry belongs | | **disabled** (*read-only: flag*) | Indicates whether the static host entry is disabled | | **dynamic** (*read-only: flag*) | Indicates whether the host was dynamically learned | | **external** (*read-only: flag*) | Indicates whether the host was learned from an external table, such as a switch chip or Wireless registration table. Static host entries added on hardware-offloaded bridge ports do not display this flag | | **invalid** (*read-only: flag*) | Indicates whether the host entry is invalid. This flag may appear for statically configured hosts on an interface that has been removed | | **local** (*read-only: flag*) | Indicates whether the host entry was created from the bridge itself, which displays all local interfaces | | **mac-address** (*read-only: MAC address*) | The MAC address of the host | | **on-interface** (*read-only: name*) | The bridge port to which the host is connected | ### Monitoring To view the active hosts table, use the `print` command. The table displays all MAC addresses that have been learned on the bridge interface, along with flags indicators and connection details. ```ros [admin@MikroTik] /interface/bridge/host/print Flags: X - disabled, I - invalid, D - dynamic, L - local, E - external # MAC-ADDRESS VID ON-INTERFACE BRIDGE 0 D B8:69:F4:C9:EE:D7 ether1 bridge1 1 D B8:69:F4:C9:EE:D8 ether2 bridge1 2 DL CC:2D:E0:E4:B3:38 bridge1 bridge1 3 DL CC:2D:E0:E4:B3:39 ether2 bridge1 ``` The output shows: - **D** flag: Dynamically learned MAC addresses - **DL** flag: Local interface MAC addresses (the bridge itself and its ports interfaces) - **VID**: VLAN ID associated with the host entry - **ON-INTERFACE**: The bridge port where the host was learned - **BRIDGE**: The bridge interface the host belongs to ### Static Entries The bridge host table supports static MAC address entries configuration. Static entries is useful in two primary scenarios: directing specific traffic through a designated port, and securing device resources by disabling dynamic MAC learning while relying solely on pre-configured static entries. The following table lists all configurable parameters for static MAC address entries: **Sub-menu:** `/interface/bridge/host` | Property | Description | | :-- | :-- | | **bridge** (*name*; Default: **none**) | The bridge interface to which the MAC address is assigned. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables the static MAC address entry. | | **interface** (*name*; Default: **none**) | Name of the interface where the MAC address traffic is forwarded. | | **mac-address** (*MAC address*; Default: ) | The MAC address to be added to the host table statically. | | **vid** (*integer: 1..4094*; Default: ) | VLAN ID associated with the static MAC address entry. | **Example:** To forward all traffic destined for MAC address **4C:5E:0C:4D:12:43** exclusively through **ether2**, use the following command: ```ros /interface/bridge/host add bridge=bridge1 interface=ether2 mac-address=4C:5E:0C:4D:12:43 ``` ## Multicast Table --- The Multicast Table displays multicast group membership information learned through IGMP/MLD snooping. When IGMP/MLD snooping is enabled on a bridge, the device actively monitors IGMP/MLD network communications to build a Multicast Database (MDB) of active multicast groups and their subscribed ports members. The bridge then uses this information to intelligently forward multicast traffic only to ports where interested receivers devices are connected, rather than flooding all ports with multicast traffic. Note that packets addressed to link-local multicast groups 224.0.0.0/24 and ff02::1 are exceptions to this behavior - these addresses are always flooded to all ports and VLANs without restriction, as they are used for network protocol operations. To view the current multicast database entries table, use the `print` command in the multicast database submenu. **Sub-menu:** `/interface/bridge/mdb` | Property | Description | | :-- | :-- | | **bridge** (*read-only: name*) | Shows the bridge interface the entry belongs to. | | **group** (*read-only:*ipv4 | ipv6 | MAC address*) | Shows a multicast group address. | | **on-interface** (*read-only: name*) | Shows the bridge ports which are subscribed to the multicast group. | | **vid** (*read-only: integer*) | Shows the VLAN ID for the multicast group, only applies when `vlan-filtering` is enabled. | ```ros [admin@MikroTik] /interface/bridge/mdb/print Flags: D - DYNAMIC Columns: GROUP, VID, ON-PORTS, BRIDGE # GROUP VID ON-PORTS BRIDGE 0 D ff02::2 1 bridge1 bridge1 1 D ff02::6a 1 bridge1 bridge1 2 D ff02::1:ff00:0 1 bridge1 bridge1 3 D ff02::1:ff01:6a43 1 bridge1 bridge1 4 D 229.1.1.1 10 ether2 bridge1 5 D 229.2.2.2 10 ether3 bridge1 ether2 6 D ff02::2 10 ether5 bridge1 ether3 ether2 ether4 ``` ### Static entries Since RouterOS version 7.7, it is possible to create static MDB entries for IPv4 and IPv6 multicast groups. **Sub-menu:** `/interface/bridge/mdb` | Property | Description | | :-- | :-- | | **bridge** (*name*; Default: ) | The bridge interface to which the MDB entry is going to be assigned. | | **disabled** (*yes \| no*; Default: **no**) | Disables or enables the static MDB entry. | | **group** (*ipv4 \| ipv6 \| MAC address*; Default: ) | The IPv4, IPv6 or MAC multicast address. Static entries for link-local multicast groups 224.0.0.0/24 and ff02::1 cannot be created, as these packets are always flooded on all ports and VLANs. | | **interface** (*name*; Default: ) | The list of bridge ports to which the multicast group will be forwarded. | | **vid** (*integer: 1..4094*; Default: ) | The VLAN ID on which the MDB entry will be created only applies when `vlan-filtering` is enabled. When VLAN ID is not specified, the entry will work in shared-VLAN mode and dynamically apply to all defined VLAN IDs for particular ports. | For example, to create a static MDB entry for multicast group 229.10.10.10 on ports ether2 and ether3 on VLAN 10, use the command below: ```ros /interface/bridge/mdb add bridge=bridge1 group=229.10.10.10 interface=ether2,ether3 vid=10 ``` Verify the results with the `print` command: ```ros [admin@MikroTik] > /interface/bridge/mdb/print where group=229.10.10.10 Columns: GROUP, VID, ON-PORTS, BRIDGE # GROUP VID ON-PORTS BRIDGE 12 229.10.10.10 10 ether2 bridge1 ether3 ``` In case a certain IPv6 multicast group does not need to be snooped and it is desired for it to be flooded on all ports and VLANs, it is possible to create a static MDB entry on all VLANs and ports, including the bridge interface itself. Use the command below to create a static MDB entry for multicast group ff02::2 on all VLANs and ports (modify the `ports` setting for your particular setup): ```ros /interface/bridge/mdb add bridge=bridge1 group=ff02::2 interface=bridge1,ether2,ether3,ether4,ether5 [admin@MikroTik] > /interface/bridge/mdb/print where group=ff02::2 Flags: D - DYNAMIC Columns: GROUP, VID, ON-PORTS, BRIDGE # GROUP VID ON-PORTS BRIDGE 0 ff02::2 bridge1 15 D ff02::2 1 bridge1 bridge1 16 D ff02::2 10 bridge1 bridge1 ether2 ether3 ether4 ether5 17 D ff02::2 20 bridge1 bridge1 ether2 ether3 18 D ff02::2 30 bridge1 bridge1 ether2 ether3 ``` ## Bridge Hardware Offloading --- It is possible to switch multiple ports together if a device has a built-in switch chip. While a bridge is a software feature that will consume CPU's resources, the bridge hardware offloading feature will allow you to use the built-in switch chip to forward packets. This allows you to achieve higher throughput if configured correctly. In previous versions (prior to RouterOS v6.41) you had to use the master-port property to switch multiple ports together, but in RouterOS v6.41 this property is replaced with the bridge hardware offloading feature, which allows you to switch ports and use some of the bridge features, for example, [Spanning Tree Protocol](./user-guides/spanning-tree-protocol.md). :::warning When upgrading from previous versions (before RouterOS v6.41), the old master-port configuration is automatically converted to the new **Bridge Hardware Offloading** configuration. When downgrading from newer versions (RouterOS v6.41 and newer) to older versions (before RouterOS v6.41), the configuration is not converted back, a bridge without hardware offloading will exist instead, in such a case you need to reconfigure your device to use the old master-port configuration. ::: Below is a list of devices and features that support hardware offloading (+) or disable hardware offloading (-): | RouterBoard/[Switch Chip] Model | Features in Switch menu | STP/RSTP | MSTP | VLAN Filtering | IGMP Snooping | DHCP Snooping | DHCPv6 Snooping | RA Guard | Bonding 1, 2 | MLAG | Horizon 1 | | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | | [MikroTik devices with Marvell Prestera switch](./marvell-prestera-switch-chip-features.md) | **+** | **+** | **+** | **+** | **+** | **+** | **+** | **+** | **+ 3** | **+** | **-** | | [88E6393X, 88E6191X, 88E6190] | **+** | **+** | **+** | **+ 6** | **+ 5** | **+ 5** | **-** | **-** | **+ 4** | **-** | **-** | | [MT7621, MT7531, EN7523] | **+** | **+** | **+** | **+ 6** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | | [RTL8367] | **+** | **+** | **+** | **+ 6** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | | CRS1xx/CRS2xx series | **+** | **+** | **-** | **-** | **+ 7** | **+ 8** | **-** | **-** | **-** | **-** | **-** | | [QCA8337] | **+** | **+** | **-** | **-** | **-** | **+ 7** | **-** | **-** | **-** | **-** | **-** | | [Atheros8327] | **+** | **+** | **-** | **-** | **-** | **+ 7** | **-** | **-** | **-** | **-** | **-** | | [Atheros8316] | **+** | **+** | **-** | **-** | **-** | **+ 7** | **-** | **-** | **-** | **-** | **-** | | [Atheros8227] | **+** | **+** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | | [Atheros7240] | **+** | **+** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | | [IPQ-PPE] | **+ 9** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | | [ICPlus175D] | **+** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | **-** | Footnotes: 1. The HW offloading will be disabled only for the specific bridge port, not the entire bridge. 2. Only `802.3ad` (LACP), `balance-xor` (static LAG) and `active-backup` bonding modes are hardware offloaded. Other bonding modes do not support HW offloading. 3. MikroTik devices with Marvell Prestera switch will always use Layer2+Layer3+Layer4 for a transmit hash policy. Changing the transmit hash policy manually while HW offloading is used will have no effect. 4. The 88E6393X, 88E6191X, 88E6190 switch chips are limited to Layer2 transmit hash. Changing the transmit hash policy manually while HW offloading is used will have no effect. 5. The 88E6393X, 88E6191X, 88E6190 switch chips do not support QinQ configurations. They are limited to parsing only the first VLAN tag, any feature that requires reading data after the VLAN tag, such as `dhcp-snooping` or `igmp-snooping`, will not function properly in QinQ setups. As a result, double-tagged DHCP or IGMP packets may be forwarded to incorrect switch ports and may lead to inaccurate MDB entries, causing multicast traffic to be flooded incorrectly. 6. The switch does not support `ether-type` 0x88a8 or 0x9100 (only 0x8100 is supported) and has no `tag-stacking` support. Using these features will disable HW offload. 7. The feature will not work properly in VLAN switching setups. 8. The feature will not work properly in VLAN switching setups. It is possible to correctly snoop DHCP packets only for a single VLAN, but this requires that these DHCP messages get tagged with the correct VLAN tag using an ACL rule, for example, `/interface/ethernet/switch/acl/add dst-l3-port=67-68 ip-protocol=udp mac-protocol=ip new-customer-vid=10 src-ports=switch1-cpu`. DHCP Option 82 will not contain any information regarding VLAN-ID. 9. Currently, HW offloaded bridge support for the IPQ-PPE switch chip is still a work in progress. We recommend using the default non-HW offloaded bridge (enabled RSTP). :::warning When upgrading from older versions (before RouterOS v6.41), only the master-port configuration is converted. For each master-port a bridge will be created. VLAN configuration is not converted and should not be changed. Check the [Basic VLAN switching](./user-guides/basic-vlan-switching.md) guide to be sure how VLAN switching should be configured for your device. ::: Bridge Hardware Offloading should be considered as port switching, but with more possible features. By enabling hardware offloading you are allowing a built-in switch chip to process packets using its switching logic. The diagram below illustrates that switching occurs before any software related action. ![HWoffloading_diagram](./img/index-02.webp) A packet that is received by one of the ports always passes through the switch logic first. Switch logic decides which ports the packet should be going to (most commonly this decision is made based on the destination MAC address of a packet, but there might be other criteria that might be involved based on the packet and the configuration). In most cases the packet will not be visible to RouterOS (only statistics will show that a packet has passed through). This is because the packet was already processed by the switch chip and never reached the CPU. Though it is possible in certain situations to allow a packet to be processed by the CPU, this is usually called packet forwarding to the switch CPU port (or the bridge interface in bridge VLAN filtering scenario). This allows the CPU to process the packet and lets the CPU forward the packet. Passing the packet to the CPU port will give you the opportunity to route packets to different networks, perform traffic control and other software-related packet processing actions. To allow a packet to be processed by the CPU, you need to make certain configuration changes depending on your needs and on the device you are using (most commonly passing packets to the CPU is required for VLAN filtering setups). Check the manual page for your specific device: - [CRS1xx/2xx series switches](./user-guides/crs1xx-2xx-series-switches-examples.md) - [Marvell Prestera switch chip features](./marvell-prestera-switch-chip-features.md) - [Non-CRS series switches](./switch-chip-features.md) :::danger Certain bridge and Ethernet port properties are directly related to switch chip settings. Changing such properties can trigger a **switch chip reset**, temporarily disabling all Ethernet ports that are on the switch chip for the settings to take effect. This must be taken into account whenever changing properties in production environments. Such properties include DHCP Snooping, IGMP Snooping, VLAN filtering, L2MTU, Flow Control, and others. The exact settings that can trigger a switch chip reset depend on the device's model. ::: :::warning The [CRS1xx/2xx series switches](./crs1xx-and-2xx-series-switches.md#multiple-switch-groups) support multiple hardware offloaded bridges per switch chip. All other devices support only one hardware offloaded bridge per switch chip. Use the hw=yes/no parameter to select which bridge will use hardware offloading. ::: ### Example The following example demonstrates how to configure port switching using a bridge with hardware offloading enabled. This configuration creates a bridge interface and adds multiple Ethernet ports as bridge ports with hardware offloading enabled. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether3 hw=yes add bridge=bridge1 interface=ether4 hw=yes add bridge=bridge1 interface=ether5 hw=yes ``` Verify that hardware offloading is active by checking the **H** flag in the bridge port table: ```ros [admin@MikroTik] /interface/bridge/port/print Flags: X - disabled, I - inactive, D - dynamic, H - hw-offload # INTERFACE BRIDGE HW PVID PRIORITY PATH-COST INTERNAL-PATH-COST HORIZON 0 H ether2 bridge1 yes 1 0x80 10 10 none 1 H ether3 bridge1 yes 1 0x80 10 10 none 2 H ether4 bridge1 yes 1 0x80 10 10 none 3 H ether5 bridge1 yes 1 0x80 10 10 none ``` :::warning Port switching in RouterOS v6.41 and newer is done using the bridge configuration. Prior to RouterOS v6.41, port switching was done using the master-port property. ::: ## Bridge VLAN Filtering --- Bridge VLAN Filtering enables VLAN-aware Layer 2 forwarding and allows VLAN tag modification within the bridge. This feature makes the bridge operate more like a traditional Ethernet switch and helps resolve Spanning Tree compatibility issues that can occur when VLAN interfaces are bridged. Configuring Bridge VLAN Filtering is highly recommended to comply with STP (IEEE 802.1D) and RSTP (IEEE 802.1W) standards, and it is mandatory to enable MSTP (IEEE 802.1s) support in RouterOS. The primary VLAN setting is `vlan-filtering`, which globally controls VLAN awareness and VLAN tag processing for the bridge. When `vlan-filtering` is set to `no`, the bridge ignores VLAN tags, operates in shared-VLAN-learning (SVL) mode, and cannot modify VLAN tags of packets. Enabling `vlan-filtering` activates all bridge VLAN-related functionality and switches to independent-VLAN-learning (IVL) mode. In addition to joining ports for Layer 2 forwarding, the bridge itself functions as an interface and therefore has a Port VLAN ID (pvid). :::warning Currently, MikroTik devices with Marvell Prestera switch and RTL8367, 88E6393X, 88E6191X, 88E6190, MT7621, MT7531, and EN7523 switch chips (since RouterOS v7) can use bridge VLAN filtering and hardware offloading simultaneously. Other devices cannot utilize the benefits of a built-in switch chip when bridge VLAN filtering is enabled. These devices should be configured according to the method described in the Basic VLAN switching guide. Using an improper configuration method can cause throughput issues in your network. ::: ### Bridge VLAN Table The Bridge VLAN table defines per-VLAN port membership and specifies the VLAN tag action for egress traffic. Ports configured as `tagged` transmit frames with their corresponding VLAN ID, while ports configured as `untagged` remove the VLAN tag before transmitting frames. Bridge ports with `frame-types` set to `admit-all` or `admit-only-untagged-and-priority-tagged` are automatically added as untagged ports for their configured PVID. **Sub-menu:** `/interface/bridge/vlan` | Property | Description | | :-- | :-- | | **bridge** (*name*; Default: **none**) | The bridge interface to which this VLAN entry applies. | | **disabled** (*yes* | *no*; Default: **no**) | Enables or disables the VLAN entry. | | **tagged** (*interface*; Default: **none**) | Interfaces or [interface list](../system-information-and-utilities/interface-lists.md) that transmit frames with a VLAN tag. This setting accepts comma-separated values, for example `tagged=ether1,ether2`. | | **untagged** (*interface*; Default: **none**) | Interfaces or [interface list](../system-information-and-utilities/interface-lists.md) that transmit frames without a VLAN tag. This setting accepts comma-separated values, for example `untagged=ether3,ether4`. | | **vlan-ids** (*integer 1..4094*; Default: **1**) | The VLAN ID or list of VLAN IDs for this port configuration. This setting accepts VLAN ID ranges as well as comma-separated values, for example `vlan-ids=100-115,120,122,128-130`. | :::danger The `vlan-ids` parameter can specify a set or range of VLANs, but this should only be used for tagged ports configurations. When multiple VLANs are specified for access ports configurations, tagged packets may be sent as untagged packets through the wrong access port, regardless of the PVID value. ::: :::warning Ensure all required interfaces are added to the bridge VLAN table when using bridge VLAN filtering. For routing functions to work properly on the same device through ports using bridge VLAN filtering, you must allow access to the bridge interface (this includes the switch-cpu port when hardware-offloaded VLAN filtering is used). This can be done manually by adding the bridge interface itself to the VLAN table as a tagged port. Since RouterOS v7.16, this is done automatically when adding a VLAN interface to a bridge with VLAN filtering enabled (a dynamic entry with the comment "added by vlan on bridge" appears under the `/interface/bridge/vlan` menu). Additional examples can be found in the inter-VLAN routing and management access sections. Since RouterOS 7.20, a dynamic tagged entry named "added by switch-cpu" is added when the same VLAN ID spans multiple switch chips or is used on both hardware and software ports. ::: :::danger When allowing access to the CPU, you are permitting access from a specific port to the router/switch itself. This is not always desirable. Ensure you implement proper firewall filter rules to secure your device when CPU access is allowed from a specific VLAN ID and port. Use firewall filter rules to allow access only to required services. ::: :::warning Improperly configured bridge VLAN filtering can cause security issues. Ensure you fully understand how the [Bridge VLAN table](./user-guides/bridge-vlan-table.md) operates before deploying your device in a production environment. ::: ### Bridge Port Settings Each bridge port has multiple VLAN-related settings that control untagged VLAN membership, VLAN tagging and untagging behavior, and packet filtering based on VLAN tag presence. **Sub-menu:** `/interface/bridge/port` | Property | Description | | :-- | :-- | | **frame-types** (*admit-all* | *admit-only-untagged-and-priority-tagged* | *admit-only-vlan-tagged*; Default: **admit-all**) | Specifies allowed ingress frame types on a bridge port. This property only has an effect when `vlan-filtering` is set to `yes`. | | **ingress-filtering** (*yes* | *no*; Default: **yes**) | Enables or disables VLAN ingress filtering, which checks if the ingress port is a member of the received VLAN ID in the bridge VLAN table. Should be used with `frame-types` to specify if the ingress traffic should be tagged or untagged. This property only has an effect when `vlan-filtering` is set to `yes`. The setting is enabled by default since RouterOS v7. | | **pvid** (*integer: 1..4094*; Default: **1**) | Port VLAN ID (pvid) specifies which VLAN the untagged ingress traffic is assigned to. This property only has an effect when `vlan-filtering` is set to `yes`. | | **tag-stacking** (*yes* | *no*; Default: **no**) | Forces all packets to be treated as untagged packets. Packets on the ingress port will be tagged with another VLAN tag regardless of whether a VLAN tag already exists; packets will be tagged with a VLAN ID that matches the `pvid` value and will use EtherType that is specified in `ether-type`. This property only has an effect when `vlan-filtering` is set to `yes`. | ### Bridge host table The Bridge host table displays MAC addresses that have been learned on a bridge interface. When vlan-filtering is enabled, the table also shows the VLAN ID associated with each learned MAC address, enabling independent VLAN learning (IVL) mode. ```ros [admin@MikroTik] > /interface/bridge/host/print where !local Flags: X - disabled, I - invalid, D - dynamic, L - local, E - external # MAC-ADDRESS VID ON-INTERFACE BRIDGE 0 D CC:2D:E0:E4:B3:AA 300 ether3 bridge1 1 D CC:2D:E0:E4:B3:AB 400 ether4 bridge1 ``` ### VLAN Example: Trunk and Access Ports This section demonstrates how to configure a basic VLAN setup with one trunk port and multiple access ports. The trunk port (ether2) carries tagged VLAN traffic between switches or to a router, while access ports (ether6, ether7, ether8) connect to end devices and use untagged VLAN traffic. ![access_ports](./img/index-03.webp) #### Step 1: Create the Bridge Interface Create a bridge interface with `vlan-filtering` disabled. This is important because enabling VLAN filtering immediately restricts traffic, which could lock you out of the device before the configuration is complete. For detailed information on managing access to the device during VLAN configuration, refer to the [Management access configuration](#management-access-configuration) section. ```ros /interface/bridge add name=bridge1 vlan-filtering=no ``` #### Step 2: Add Bridge Ports and Configure PVID Add the physical interfaces to the bridge and configure the Port VLAN ID (pvid) for access ports. The pvid determines which VLAN untagged traffic is assigned to when entering the bridge. The `frame-types` setting controls what kind of traffic each port accepts: tagged only, untagged only, or both. ```ros /interface/bridge/port add bridge=bridge1 interface=ether2 frame-types=admit-only-vlan-tagged add bridge=bridge1 interface=ether6 pvid=200 frame-types=admit-only-untagged-and-priority-tagged add bridge=bridge1 interface=ether7 pvid=300 frame-types=admit-only-untagged-and-priority-tagged add bridge=bridge1 interface=ether8 pvid=400 frame-types=admit-only-untagged-and-priority-tagged ``` #### Step 3: Create Bridge VLAN Table Entries Create the bridge VLAN table entries. The trunk port (ether2) must be configured as a tagged member, meaning it will send and receive frames with VLAN tags. Access ports are automatically added as untagged members based on their pvid setting, so you only need to specify the tagged port in each VLAN entry. ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether2 vlan-ids=200 add bridge=bridge1 tagged=ether2 vlan-ids=300 add bridge=bridge1 tagged=ether2 vlan-ids=400 ``` #### Step 4: Enable VLAN Filtering Once all VLAN settings are configured, enable VLAN filtering on the bridge to activate the VLAN functionality. ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` #### Step 5: (Optional) Reject Untagged Traffic As an optional security measure, you can set the bridge to reject untagged traffic by changing the frame-type. This prevents the default VLAN 1 (pvid=1) from being used and ensures only properly tagged traffic is accepted. ```ros /interface/bridge/set bridge1 frame-types=admit-only-vlan-tagged ``` ### VLAN Example - Trunk and Hybrid Ports ![hybrid_ports](./img/index-04.webp) Create a bridge with disabled `vlan-filtering` to avoid losing access to the router before VLANs are completely configured. If you need management access to the bridge, see the [Management access configuration](index.md#management-access-configuration) section. ```ros /interface/bridge add name=bridge1 vlan-filtering=no ``` Add bridge ports and specify `pvid` on hybrid VLAN ports to assign untagged traffic to the intended VLAN. Use the `frame-types` setting to accept only tagged packets on ether2. ```ros /interface/bridge/port add bridge=bridge1 interface=ether2 frame-types=admit-only-vlan-tagged add bridge=bridge1 interface=ether6 pvid=200 add bridge=bridge1 interface=ether7 pvid=300 add bridge=bridge1 interface=ether8 pvid=400 ``` Add Bridge VLAN entries and specify tagged ports in them. In this example, egress VLAN tagging is done on ether6, ether7, ether8 ports too, making them into hybrid ports. Bridge ports with `frame-types` set to `admit-all` will be automatically added as untagged ports for the `pvid` VLAN. ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether2,ether7,ether8 vlan-ids=200 add bridge=bridge1 tagged=ether2,ether6,ether8 vlan-ids=300 add bridge=bridge1 tagged=ether2,ether6,ether7 vlan-ids=400 ``` In the end, when VLAN configuration is complete, enable Bridge VLAN Filtering. ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` An Optional step is to set `frame-types=admit-only-vlan-tagged` on the bridge interface in order to disable the default untagged VLAN 1 (`pvid=1`). ```ros /interface/bridge/set bridge1 frame-types=admit-only-vlan-tagged ``` :::danger You don't have to add access ports as untagged ports, because they will be added dynamically as untagged ports with the VLAN ID that is specified in `pvid`, you can specify just the trunk port as a tagged port. All ports that have the same `pvid` set will be added as untagged ports in a single entry. You must take into account that the bridge itself is a port and it also has a `pvid` value, this means that the bridge port also will be added as an untagged port for the ports that have the same `pvid`. You can circumvent this behavior by either setting different `pvid` on all ports (even the trunk port and bridge itself), or using `frame-type` set to `accept-only-vlan-tagged`. ::: ### VLAN Example - InterVLAN Routing by Bridge ![vlan_routing](./img/index-05.webp) Create a bridge with disabled `vlan-filtering` to avoid losing access to the router before VLANs are completely configured. If you need management access to the bridge, see the [Management access configuration](index.md#management-access-configuration) section. ```ros /interface/bridge add name=bridge1 vlan-filtering=no ``` Add bridge ports and specify `pvid` for VLAN access ports to assign their untagged traffic to the intended VLAN. Use the `frame-types` setting to accept only untagged packets. ```ros /interface/bridge/port add bridge=bridge1 interface=ether6 pvid=200 frame-types=admit-only-untagged-and-priority-tagged add bridge=bridge1 interface=ether7 pvid=300 frame-types=admit-only-untagged-and-priority-tagged add bridge=bridge1 interface=ether8 pvid=400 frame-types=admit-only-untagged-and-priority-tagged ``` Add Bridge VLAN entries and specify tagged ports in them. In this example **bridge1** interface is the VLAN trunk that will send traffic further to do InterVLAN routing. Bridge ports with `frame-types` set to `admit-only-untagged-and-priority-tagged` will be automatically added as untagged ports for the `pvid` VLAN. ```ros /interface/bridge/vlan add bridge=bridge1 tagged=bridge1 vlan-ids=200 add bridge=bridge1 tagged=bridge1 vlan-ids=300 add bridge=bridge1 tagged=bridge1 vlan-ids=400 ``` Configure VLAN interfaces on the **bridge1** to allow handling of tagged VLAN traffic at the routing level and set IP addresses to ensure routing between VLANs as planned. ```ros /interface/vlan add interface=bridge1 name=VLAN200 vlan-id=200 add interface=bridge1 name=VLAN300 vlan-id=300 add interface=bridge1 name=VLAN400 vlan-id=400 /ip/address add address=20.0.0.1/24 interface=VLAN200 add address=30.0.0.1/24 interface=VLAN300 add address=40.0.0.1/24 interface=VLAN400 ``` In the end, when VLAN configuration is complete, enable Bridge VLAN Filtering: ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` An optional step is to set `frame-types=admit-only-vlan-tagged` on the bridge interface in order to disable the default untagged VLAN 1 (`pvid=1`). ```ros /interface/bridge/set bridge1 frame-types=admit-only-vlan-tagged ``` Since RouterOS v7, it is possible to route traffic using L3 HW offloading on certain devices. See more details on [L3 Hardware Offloading](./l3-hardware-offloading.md). ### Management access configuration There are multiple ways to set up management access on a device that uses bridge VLAN filtering. Below are some of the most popular approaches to properly enable access to a router/switch. Start by creating a bridge without VLAN filtering enabled: ```ros /interface/bridge add name=bridge1 vlan-filtering=no ``` #### Untagged Access Without VLAN Filtering In cases where VLAN filtering is not enabled on the bridge and management access via untagged traffic is required, the configuration is straightforward. The only necessary step is to assign an IP address directly to the bridge interface itself. Since the bridge operates at Layer 2 without VLAN tagging, any untagged traffic entering the bridge ports will be able to communicate with the IP address assigned to the bridge interface without additional configuration. ```ros /ip/address add address=192.168.99.1/24 interface=bridge1 ``` This approach provides the simplest method for accessing the router or switch for management purposes when VLAN filtering is not part of the network design. #### Tagged Access Without VLAN Filtering This method is used when you want to manage the router/switch using tagged VLAN traffic, but without enabling bridge VLAN filtering. In this scenario, a separate VLAN interface is created on top of the bridge to handle the tagged management traffic. This approach is useful when you need to access the device through a specific VLAN ID while keeping the bridge configuration simple and straightforward. To configure tagged management access, first create a VLAN interface on the bridge with the desired VLAN ID, then assign an IP address to that VLAN interface. This allows the router to be reachable through the tagged VLAN while maintaining the bridge in its default state (without VLAN filtering enabled). The VLAN interface acts as a logical sub-interface that inherits the MAC address from the parent bridge interface. ```ros /interface/vlan add interface=bridge1 name=MGMT vlan-id=99 /ip/address add address=192.168.99.1/24 interface=MGMT ``` This configuration creates a management VLAN (VLAN 99) on the bridge, making the device accessible at IP address 192.168.99.1 through any port that carries VLAN 99 tagged traffic. #### Tagged Access with VLAN Filtering In scenarios where VLAN filtering is enabled on the bridge and management access through tagged traffic is required, additional configuration steps are necessary. This method allows you to reach the router/switch management interface using a specific VLAN ID (VLAN 99 in this example) through tagged traffic on designated ports. First, create a VLAN interface on top of the bridge and assign an IP address to it. This VLAN interface will handle the tagged management traffic: ```ros /interface/vlan add interface=bridge1 name=MGMT vlan-id=99 /ip/address add address=192.168.99.1/24 interface=MGMT ``` Next, you must add the appropriate entries to the bridge VLAN table to permit tagged traffic on the ports where management access will be initiated. For instance, if you need to access the device from ports **ether3**, **ether4**, and **sfp-sfpplus1** using VLAN 99 tagged traffic, include the **bridge1** interface itself in the tagged port list (the bridge interface must be tagged to allow the VLAN interface to communicate with the switch CPU): ```ros /interface/bridge/vlan add bridge=bridge1 tagged=bridge1,ether3,ether4,sfp-sfpplus1 vlan-ids=99 ``` Once the VLAN table is properly configured, you can enable VLAN filtering on the bridge: ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` This configuration enables management access through tagged VLAN 99 traffic while maintaining the security benefits of VLAN filtering. The bridge interface itself is included as a tagged member to ensure proper communication between the VLAN interface and the switch CPU for routing and management purposes. ### Untagged Access with VLAN Filtering When bridge VLAN filtering is enabled and you need to access the device using untagged traffic, you must ensure that the management VLAN interface uses the same VLAN ID as the untagged port VLAN ID (configured via the `pvid` parameter). This ensures that untagged traffic from access ports can properly communicate with the router's management interface. First, create a VLAN interface on the bridge and assign an IP address to it, just as you would in the previous example. This VLAN interface will handle the management traffic: ```ros /interface/vlan add interface=bridge1 name=MGMT vlan-id=99 /ip/address add address=192.168.99.1/24 interface=MGMT ``` For example, if you want untagged ports **ether2** and **ether3** to be able to communicate with the VLAN 99 management interface, these ports must be configured with a `pvid` value that matches the management VLAN ID. Additionally, you need to add the bridge interface itself as a tagged port member in the VLAN table, which allows the router to process the tagged management traffic. You can also add additional tagged ports if needed for your specific network topology (see the previous examples for more details on tagged port configuration): ```ros /interface/bridge/port set [find interface=ether2] pvid=99 set [find interface=ether3] pvid=99 /interface/bridge/vlan add bridge=bridge1 tagged=bridge1 untagged=ether2,ether3 vlan-ids=99 ``` Once you have completed the VLAN table configuration, you can enable VLAN filtering on the bridge. This will activate all VLAN-related functionality and begin filtering traffic based on your VLAN settings: ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` #### Changing untagged VLAN for the bridge interface In case VLAN filtering is used, it is possible to change the untagged VLAN ID for the bridge interface using the `pvid` setting. Note that creating routable VLAN interfaces and allowing tagged traffic on the bridge is a more flexible and generally recommended option. First, create an IP address on the bridge interface. ```ros /ip/address add address=192.168.99.1/24 interface=bridge1 ``` For example, untagged **bridge1** traffic should be able to communicate with untagged **ether2** and **ether3** ports and tagged **sfp-sfpplus1** port in VLAN 99. In order to achieve this, **bridge1**, **ether2**, **ether3** should be configured with the same `pvid` and sfp-sfpplus1 should be added as a tagged member. ```ros /interface/bridge set [find name=bridge1] pvid=99 /interface/bridge/port set [find interface=ether2] pvid=99 set [find interface=ether3] pvid=99 /interface/bridge/vlan add bridge=bridge1 tagged=sfp-sfpplus1 untagged=bridge1,ether2,ether3 vlan-ids=99 ``` After that you can enable VLAN filtering: ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` :::warning If the connection to the router/switch through an IP address is not required, then steps for adding an IP address can be skipped since a connection to the router/switch through Layer2 protocols (e.g. MAC-telnet) will be working either way. ::: ### VLAN Tunneling (QinQ) Since RouterOS v6.43 the RouterOS bridge is IEEE 802.1ad compliant and it is possible to filter VLAN IDs based on Service VLAN ID (0x88a8) rather than Customer VLAN ID (0x8100). The same principles can be applied as with IEEE 802.1Q VLAN filtering (the same setup examples can be used). Below is a topology for a common **Provider bridge**: ![Provider_bridge](./img/index-06.webp) In this example, **R1**, **R2**, **R3,** and **R4** might be sending any VLAN tagged traffic by 802.1Q (CVID), but **SW1** and **SW2** need to isolate traffic between routers in a way that **R1** is able to communicate only with **R3**, and **R2** is only able to communicate with **R4**. To do so, you can tag all ingress traffic with an SVID and only allow these VLANs on certain ports. Start by enabling the service tag 0x88a8, introduced by `802.1ad`, on the bridge. Use these commands on **SW1** and **SW2**: ```ros /interface/bridge add name=bridge1 vlan-filtering=no ether-type=0x88a8 ``` In this setup, **ether1** and **ether2** are going to be access ports (untagged), use the `pvid` parameter to tag all ingress traffic on each port, use these commands on **SW1** and **SW2**: ```ros /interface/bridge/port add interface=ether1 bridge=bridge1 pvid=200 add interface=ether2 bridge=bridge1 pvid=300 add interface=ether3 bridge=bridge1 ``` Specify tagged and untagged ports in the bridge VLAN table. Use these commands on **SW1** and **SW2**: ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether3 untagged=ether1 vlan-ids=200 add bridge=bridge1 tagged=ether3 untagged=ether2 vlan-ids=300 ``` When the bridge VLAN table is configured, you can enable bridge VLAN filtering. Use these commands on **SW1** and **SW2:** ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` :::danger By enabling vlan-filtering you will be filtering out traffic destined to the CPU. Before enabling VLAN filtering you should make sure that you set up a Management port. Note that if you are using the new EtherType/TPID 0x88a8 (service tag) and you also need a VLAN interface for your Service VLAN, you will also have to apply the `use-service-tag` parameter on the VLAN interface. ::: :::danger When `ether-type=0x8100` is configured, the bridge checks the outer VLAN tag to see if it is using EtherType `0x8100`. If the bridge receives a packet with an outer tag that has a different EtherType, it will mark the packet as `untagged`. Since RouterOS only checks the outer tag of a packet, it is not possible to filter 802.1Q packets when the 802.1ad protocol is used. ::: :::warning Currently, only MikroTik devices with Marvell Prestera switch are capable of hardware offloaded VLAN filtering using the Service tag, EtherType/TPID `0x88a8`. ::: :::danger Devices with switch chip Marvell-98DX3257 (e.g. CRS354 series) do not support VLAN filtering on 1Gbps Ethernet interfaces for other VLAN types (`0x88a8` and `0x9100`). ::: ### Tag stacking Since RouterOS v6.43 it is possible to forcefully add a new VLAN tag over any existing VLAN tags. This feature can be used to achieve a CVID stacking setup, where a CVID (0x8100) tag is added before an existing CVID tag. This type of setup is very similar to the Provider bridge setup. To achieve the same setup but with multiple CVID tags (CVID stacking) we can use the same topology: ![Tag_stacking](./img/index-07.webp) In this example **R1**, **R2**, **R3,** and **R4** might be sending any VLAN tagged traffic, it can be 802.1ad, 802.1Q or any other type of traffic, but **SW1** and **SW2** need to isolate traffic between routers in a way that **R1** is able to communicate only with **R3**, and **R2** is only able to communicate with **R4**. To do so, you can tag all ingress traffic with a new CVID tag and only allow these VLANs on certain ports. Start by selecting the proper EtherType, use these commands on **SW1** and **SW2**: ```ros /interface/bridge add name=bridge1 vlan-filtering=no ether-type=0x8100 ``` In this setup, **ether1** and **ether2** will ignore any VLAN tags that are present and add a new VLAN tag. Use the `pvid` parameter to tag all ingress traffic on each port and allow `tag-stacking` on these ports. Use these commands on **SW1** and **SW2**: ```ros /interface/bridge/port add interface=ether1 bridge=bridge1 pvid=200 tag-stacking=yes add interface=ether2 bridge=bridge1 pvid=300 tag-stacking=yes add interface=ether3 bridge=bridge1 ``` Specify tagged and untagged ports in the bridge VLAN table. You only need to specify the VLAN ID of the outer tag. Use these commands on **SW1** and **SW2**: ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether3 untagged=ether1 vlan-ids=200 add bridge=bridge1 tagged=ether3 untagged=ether2 vlan-ids=300 ``` When the bridge VLAN table is configured, you can enable bridge VLAN filtering, which is required in order for the pvid parameter to have any effect. Use these commands on **SW1** and **SW2:** ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` :::danger By enabling vlan-filtering you will be filtering out traffic destined to the CPU; before enabling VLAN filtering you should make sure that you set up a Management port. ::: ### MVRP Multiple VLAN Registration Protocol (MVRP) is a protocol based on Multiple Registration Protocol (MRP) which allows registering attributes (VLAN IDs in the case of MVRP) with other members of a Bridged LAN. An MRP application can make or withdraw declarations of attributes which result in registration or leaving of those attributes with other MRP participants. Here's how it works. MRP consists of two parts: - **Applicant** - responsible for sending declarations (or leaves). Its behavior can be configured on a per-port basis using the setting called `mvrp-applicant-state`, and per-VLAN using the `mvrp-forbidden` setting. - **Registrar** - responsible for registering incoming declarations. Its configuration can be set per-port using the `mvrp-registrar-state` setting, and per-VLAN using the `mvrp-forbidden` setting. **Registration Propagation:** Incoming registration on a bridge port dynamically makes that specific port a tagged VLAN member. Additionally, the attributes associated with this registration are spread to all active (forwarding) bridge ports as a declaration. **Declaration Operation:** In case of MVRP, the configured VLANs get declared on each port, but they will only get configured as members of those VLANs when a declaration is received from the LAN (Registrar will register the VLAN). From the perspective of an end-station, a single declaration will be registered on each upstream port across the entire LAN. When another end-station declares the same attribute, a path of registrations will be made between the two (or more) end stations, see the picture below. MVRP helps to dynamically propagate VLAN information throughout the bridged network and configure VLANs only on the needed ports. This makes the network efficient by avoiding unnecessary traffic flooding. As noted before, MVRP is only active on ports that are forwarding. In the case of MSTP, declarations and registrations are made only if the port is forwarding in the MSTI in which the VLAN is mapped. The point-to-point ports speed up the process of registration (or leaving). Manually configuring `point-to-point=yes` can be advantageous for non-Ethernet interfaces. ![MVRP](./img/index-08.webp) #### Property Reference **Sub-menu:** `/interface/bridge` | Property | Description | | :-- | :-- | | **mvrp** (*yes* \| *no*; Default: **no**) | Enables MVRP for bridge. It ensures that the MAC address 01:80:C2:00:00:21 is trapped and not forwarded. The `vlan-filtering` must be enabled. | **Sub-menu:** `/interface/bridge/port` The port menu enables control over the applicant and registrar settings on a per-port basis. | Property | Description | | :-- | :-- | | **mvrp-applicant-state** (*non-participant \| normal-participant;* Default: **normal-participant**) | MVRP applicant options: non-participant - port does not send any MRP messages;normal-participant - port participates normally in MRP exchanges. | | **mvrp-registrar-state** (*fixed \| normal*; Default: **normal**) | MVRP registrar options: fixed - port ignores all MRP messages, and remains Registered (IN) in all configured vlans.normal - port receives MRP messages and handles them according to the standard. | To monitor the currently declared and registered VLAN IDs, use the `monitor` command. ```ros [admin@MikroTik] > /interface/bridge/port/monitor [find interface=sfp-sfpplus1] interface: sfp-sfpplus1 status: in-bridge port-number: 1 role: designated-port edge-port: no edge-port-discovery: yes point-to-point-port: yes external-fdb: no sending-rstp: yes learning: yes forwarding: yes actual-path-cost: 2000 hw-offload-group: switch1 declared-vlan-ids: 1,10,20-21 registered-vlan-ids: 1,10,20,30-33 ``` **Sub-menu:** `/interface/bridge/vlan` All ports that are members of static VLANs or dynamic untagged VLANs created by the port `pvid` setting are treated as "fixed." This means the registrar disregards all MRP messages and remains registered (IN) for those VLANs. When a VLAN is neither manually configured nor created by the port `pvid` setting, incoming registrations on a bridge port can dynamically designate that specific port as a tagged VLAN member. The `mvrp-forbidden` feature allows creating a list of ports that are restricted from registering for a specific VLAN ID. VLANs that are static or dynamic will be declared by the applicants unless this functionality is disabled by the port's `mvrp-applicant-state`, or by the VLAN's `mvrp-forbidden` setting. | Property | Description | | :-- | :-- | | **mvrp-forbidden** (*interfaces*; Default: ) | Ports that ignore all MRP messages and remain Not Registered (MT), as well as disable applicant from declaring specific VLAN ID. | **Sub-menu:** `/interface/bridge/vlan/mvrp` The MVRP attributes menu can be used to see internal MVRP attribute states, as specified in the IEEE 802.1Q-2011. | Property | Description | | :-- | :-- | | **applicant-state** | The Applicant state machine that declares attributes. Its state can be VO, VP, VN, AN, AA, QA, LA, AO, QO, AP, QP, or LO. Each state consists of two letters. The first letter indicates the state: V—Very anxious;A—Anxious;Q—Quiet;L—Leaving. The second letter indicates the membership state: A - Active member;P - Passive member;O - Observer;N - New. For example, VP indicates "Very anxious, Passive member." | | **registrar-state** | The Registrar state machine that records the registration state of attributes declared by other participants. Its state can be IN, LV, or MT: IN—Registered;LV—Previously registered, but now being timed out;MT—Not registered. | ```ros [admin@Mikrotik] /interface/bridge/vlan/mvrp/print where vlan-id=10 Columns: BRIDGE, PORT, VLAN-ID, REGISTRAR-STATE, APPLICANT-STATE, LAST-EVENT # BRIDGE PORT VLAN-ID REGISTRAR-STATE APPLICANT-STATE LAST-EVENT 1 bridge67 sfp-sfpplus1 10 IN Quiet Active JoinIn 9 bridge67 sfp-sfpplus5 10 MT Quiet Active JoinEmpty 17 bridge67 sfp-sfpplus9 10 MT Quiet Active JoinEmpty 25 bridge67 sfp-sfpplus13 10 IN Quiet Active JoinIn ``` ## Fast Forward --- Fast Forward allows forwarding packets faster under special conditions. When Fast Forward is enabled, then the bridge can process packets even faster since it can skip multiple bridge-related checks, including MAC learning. Below you can find a list of conditions that **MUST** be met in order for Fast Forward to be active: - Bridge has `fast-forward` set to `yes`. - Bridge has only 2 running ports. - Both bridge ports support [Fast Path](../firewall-and-quality-of-service/packet-flow-in-routeros.md#fast-path), Fast Path is active on ports and globally on the bridge. - Bridge Hardware Offloading is disabled. - Bridge VLAN Filtering is disabled. - Bridge DHCP snooping is disabled. - `unknown-multicast-flood` is set to `yes`. - `unknown-unicast-flood` is set to `yes`. - `broadcast-flood` is set to `yes`. - MAC address for the bridge matches a MAC address from one of the bridge slave ports. - `horizon` for both ports is set to `none`. :::warning Fast Forward disables MAC learning; this is by design to achieve faster packet forwarding. MAC learning prevents traffic from flooding multiple interfaces, but MAC learning is not needed when a packet can only be sent out through just one interface. ::: :::danger Fast Forward is disabled when hardware offloading is enabled. Hardware offloading can achieve full wire-speed performance when it is active since it will use the built-in switch chip (if such exists on your device). Fast forward uses the CPU to forward packets. When comparing throughput results, you would get such results: Hardware offloading > Fast Forward > Fast Path > Slow Path. ::: It is possible to check how many packets were processed by Fast Forward: ```ros [admin@MikroTik] /interface/bridge/settings> pr use-ip-firewall: no use-ip-firewall-for-vlan: no use-ip-firewall-for-pppoe: no allow-fast-path: yes bridge-fast-path-active: yes bridge-fast-path-packets: 0 bridge-fast-path-bytes: 0 bridge-fast-forward-packets: 16423 bridge-fast-forward-bytes: 24864422 ``` :::warning If packets are processed by Fast Path, then Fast Forward is not active. Packet count can be used as an indicator of whether Fast Forward is active or not. ::: Since RouterOS 6.44 it is possible to monitor Fast Forward status, for example: ```ros [admin@MikroTik] /interface/bridge/monitor bridge1 state: enabled current-mac-address: B8:69:F4:C9:EE:D7 root-bridge: yes root-bridge-id: 0x8000.B8:69:F4:C9:EE:D7 root-path-cost: 0 root-port: none port-count: 2 designated-port-count: 2 fast-forward: yes ``` :::danger Disabling or enabling fast-forward will temporarily disable all bridge ports for settings to take effect. This must be taken into account whenever changing this property in production environments since it can cause all packets to be temporarily dropped. ::: ## IGMP/MLD Snooping --- The bridge supports IGMP/MLD snooping. It controls multicast streams and prevents multicast flooding on unnecessary ports. Its settings are placed in the bridge menu and it works independently on every bridge interface. Software-driven implementation works on all devices with RouterOS, but MikroTik devices with Marvell Prestera switch, and 88E6393X, 88E6191X, 88E6190 switch chips also support IGMP/MLD snooping with hardware offloading. See more details on [IGMP/MLD snooping manual](./user-guides/bridge-igmp-mld-snooping.md). ## DHCP Snooping and DHCP Option 82 --- DHCP Snooping and DHCP Option 82 are supported by bridge. The DHCP Snooping is a Layer2 security feature that prevents unauthorized DHCP servers from providing malicious information to users. In RouterOS, you can specify which bridge ports are trusted (where a known DHCP server resides and DHCP messages should be forwarded) and which are untrusted (usually used for access ports, received DHCP server messages will be dropped). The DHCP Option 82 is additional information (Agent Circuit ID and Agent Remote ID) provided by DHCP Snooping enabled devices that allows identifying the device itself and DHCP clients. ![Dhcp_snooping](./img/index-09.webp) In this example, SW1 and SW2 are DHCP Snooping and Option 82-enabled devices. First, we need to create a bridge, assign interfaces and mark trusted ports. Use these commands on **SW1**: ```ros /interface/bridge add name=bridge /interface/bridge/port add bridge=bridge interface=ether1 add bridge=bridge interface=ether2 trusted=yes ``` For SW2, the configuration will be similar, but we also need to mark ether1 as trusted, because this interface is going to receive DHCP messages with Option 82 already added. You need to mark all ports as trusted if they are going to receive DHCP messages with added Option 82, otherwise these messages will be dropped. Also, we add ether3 to the same bridge and leave this port untrusted, imagining there is an unauthorized (rogue) DHCP server. Use these commands on **SW2**: ```ros /interface/bridge add name=bridge /interface/bridge/port add bridge=bridge interface=ether1 trusted=yes add bridge=bridge interface=ether2 trusted=yes add bridge=bridge interface=ether3 ``` Then we need to enable DHCP Snooping and configure Option 82. Starting from RouterOS version 7.23, it is possible to configure custom Remote ID and Circuit ID values using predefined variables (such as BRIDGEMAC, HOSTNAME, INTERFACE, VID). See the `dhcp-agent-circuit-id`, `dhcp-agent-remote-id` properties for more details. In case your DHCP server does not support DHCP Option 82 or you do not implement any Option 82-related policies, this step is not mandatory. In this configuration example, we are using these commands on **SW1** and **SW2**: ```ros /interface/bridge set [find where name="bridge"] dhcp-snooping=yes dhcp-agent-circuit-id="interface: \$(INTERFACE), vlan: \$(VID)" dhcp-agent-remote-id="ip: 192.168.88.1, identity: \$(HOSTNAME), mac: \$(BRIDGEMAC)" ``` Now both devices will analyze what DHCP messages are received on bridge ports. The **SW1** is responsible for adding and removing the DHCP Option 82. The **SW2** will limit rogue DHCP servers from receiving any discovery messages and drop malicious DHCP server messages from ether3. :::warning Currently, MikroTik devices with Marvell Prestera switch and 88E6393X, 88E6191X, 88E6190 switch chips fully support hardware offloaded DHCP Snooping and Option 82. For CRS1xx and CRS2xx series switches, it is possible to use DHCP Snooping along with VLAN switching, but then you need to make sure that DHCP packets are sent out with the correct VLAN tag using egress ACL rules. Other devices are capable of using DHCP Snooping and Option 82 features along with hardware offloading, but you must make sure that there is no VLAN-related configuration applied to the device, otherwise, DHCP Snooping and Option 82 might not work properly. See the Bridge Hardware Offloading section with supported features. ::: :::info Starting from RouterOS v7.17, DHCP snooping is supported with hardware offloading on bonding interfaces. ::: ## DHCPv6 Snooping / DHCPv6 Shield DHCPv6 Snooping is a Layer2 security feature that prevents unauthorized DHCPv6 servers from providing malicious information to users. In RouterOS, you can specify which bridge ports are trusted (where the known DHCPv6 server resides and DHCPv6 messages should be forwarded) and which are untrusted (usually used for access ports, received DHCPv6 server messages will be dropped, effectively implementing DHCPv6-Shield). The DHCPv6 Option 18 (Interface-Id) and Option 37 (Remote-Id) are additional information provided by DHCPv6 Snooping enabled devices that allow identifying the device itself and DHCPv6 clients. IPv6 allows a more granular approach as well as flexibility with the DHCPv6 Relay agent process. Functionally, these serve the exact same purpose as IPv4's Option 82: Option 18 acts as the Circuit ID (identifying the specific port/VLAN the client is attached to), and Option 37 acts as the Remote ID (identifying the relay agent or switch hardware itself). - Option 18 - identifies the specific interface (port) on which the client's message was received. It ensures the server knows exactly where the request came through so it can apply the correct policy. - Option 37 - identifies the relay agent (the switch or router) itself. It contains a unique caller ID (like the DUID—DHCP Unique Identifier). It tells the server which specific device in the network is talking to it. ## RA Guard --- The RA guard feature is intended for discarding IPv6 packets containing router advertisement (RA) messages arriving on bridge ports specified by the user as untrusted ones, thereby allowing one to prevent potential rogue RA message-based attacks or accidental network misconfiguration. When enabled, it is possible to set each bridge port either as trusted or untrusted (by default all the bridge ports are set as RA untrusted). Here are the network scheme and core principle behind IPv6 RA Guard (Router Advertisement Guard). ![RAguard](./img/index-10.webp) | | | :-- | | `#Layer 2 Access Switch - enabling RA guard on the main bridge``/interface/bridge``add name=bridge``/interface/bridge``set [find where name="bridge"] ra-guard=yes``/interface/bridge/port``add bridge=bridge interface=etherUplink Trusted RA=yes``add bridge=bridge interface=etherX``add bridge=bridge interface=etherY``add bridge=bridge interface=etherZ` | ### The Problem: Why is this needed? In IPv6, devices use ICMPv6 to auto-configure themselves. Router Advertisements (Type 134): Routers broadcast these messages to tell hosts: "I am the gateway, and here is your network prefix." The Threat: If a user accidentally connects a consumer router (like a home Wi-Fi router) or a malicious actor launches a tool (like `Rogue RA`) on an access port, that device will start broadcasting RAs. The Result: Other hosts on the network will auto-configure their IPv6 addresses based on the rogue device and set the rogue device as their default gateway. This causes a Man-in-the-Middle attack or a complete denial of service. Here is the network scheme and the core principle behind IPv6 RA Guard (Router Advertisement Guard). ### The Core Principle: "Trust vs. Untrust" The fundamental principle of IPv6 RA Guard is logically identical to DHCP Snooping in IPv4. It creates a security boundary within the Layer 2 switch infrastructure by categorizing switch ports into two roles: - Trusted Ports: Ports connected to legitimate, authorized IPv6 routers. These ports are allowed to send Router Advertisement (RA) packets. - Untrusted Ports: Ports connected to end-user hosts. These ports are blocked from sending RA packets. ### Packet parsing process For ports not configured as RA Trusted, the RA Guard parser traverses the extension header chain until it encounters a non-extension header. The parsing process and subsequent actions are governed by the following rules: **Transport Layer Termination**: If the parser encounters a valid transport layer header—such as TCP, UDP, ESP, RSVP, or an encapsulated IPv4/IPv6 header—parsing terminates and the packet is forwarded (subject to standard bridge checks). - Drop Conditions - The packet is discarded if: 1. It fails to contain a transport layer header. 2. The final extension header in the chain does not specify NO\_NEXT\_HEADER (59) in its "Next Header" field. 3. If the ICMP message type is found to be 134, the packet is dropped. - Fragmentation Handling: These parsing rules apply exclusively to the first fragment of fragmented IPv6 packets. Subsequent fragments are forwarded regardless of their content, as they do not contain the protocol headers necessary for RA identification. ## Bridge Firewall --- The bridge firewall implements packet filtering and thereby provides security functions that are used to manage data flow to, from, and through the bridge. [Packet flow diagram](../firewall-and-quality-of-service/packet-flow-in-routeros.md) shows how packets are processed through the router. It is possible to force bridge traffic to go through `/ip/firewall/filter` rules (see the bridge settings). There are two bridge firewall tables: - **filter** - bridge firewall with three predefined chains: - **input** - filters packets, where the destination is the bridge (including those packets that will be routed, as they are destined to the bridge MAC address anyway). - **output** - filters packets, which come from the bridge (including those packets that have been routed normally). - **forward** - filters packets, which are to be bridged (note: this chain is not applied to the packets that should be routed through the router, just to those that are traversing between the ports of the same bridge). - **nat** - bridge network address translation provides ways for changing source/destination MAC addresses of the packets traversing a bridge. Has two built-in chains: - **srcnat** - used for "hiding" a host or a network behind a different MAC address. This chain is applied to the packets leaving the router through a bridged interface. - **dstnat** - used for redirecting some packets to other destinations. You can put packet marks in the bridge firewall (filter and NAT), which are the same as the packet marks in the IP firewall configured by `'/ip/firewall/mangle'`. In this way, packet marks put by the bridge firewall can be used in the 'IP firewall', and vice versa. General bridge firewall properties are described in this section. Some parameters that differ between nat and filter rules are described in further sections. **Sub-menu:** `/interface/bridge/filter, /interface/bridge/nat` | Property | Description | | :-- | :-- | | **802.3-sap** (*integer*; Default: ) | DSAP (Destination Service Access Point) and SSAP (Source Service Access Point) are 2 one-byte fields, which identify the network protocol entities which use the link-layer service. These bytes are always equal. Two hexadecimal digits may be specified here to match an SAP byte. | | **802.3-type** (*integer*; Default: ) | Ethernet protocol type, placed after the IEEE 802.2 frame header. Works only if 802.3-sap is 0xAA (SNAP - Sub-Network Attachment Point header). For example, AppleTalk can be indicated by the SAP code of 0xAA followed by a SNAP type code of 0x809B. | | **action** (*accept \| drop \| jump \| log \| mark-packet \| passthrough \| return \| set-priority*; Default: ) | Action to take if the packet is matched by the rule:accept - accept the packet. The packet is not passed to the next firewall ruledrop - silently drop the packetjump - jump to the user-defined chain specified by the value of jump-target parameterlog - add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port and length of the packet. After the packet is matched it is passed to the next rule in the list, similar as passthroughmark-packet - place a mark specified by the new-packet-mark parameter on a packet that matches the rulepassthrough - if the packet is matched by the rule, increase counter and go to next rule (useful for statistics)return - passes control back to the chain from where the jump took placeset-priority - set priority specified by the new-priority parameter on the packets sent out through a link that is capable of transporting priority (VLAN or WMM-enabled wireless interface). Read more | | **arp-dst-address** (*IP address*; Default: ) | ARP destination IP address. | | **arp-dst-mac-address** (*MAC address*; Default: ) | ARP destination MAC address. | | **arp-gratuitous** (*yes \| no*; Default: ) | Matches ARP gratuitous packets. | | **arp-hardware-type** (*integer*; Default: **1**) | ARP hardware type. This is normally Ethernet (Type 1). | | **arp-opcode** (*arp-nak \| drarp-error \| drarp-reply \| drarp-request \| inarp-reply \| inarp-request \| reply \| reply-reverse \| request \| request-reverse*; Default: ) | ARP opcode (packet type)arp-nak - negative ARP reply (rarely used, mostly in ATM networks)drarp-error - Dynamic RARP error code, saying that an IP address for the given MAC address can not be allocateddrarp-reply - Dynamic RARP reply, with a temporary IP address assignment for a hostdrarp-request - Dynamic RARP request to assign a temporary IP address for the given MAC addressinarp-reply - InverseARP Replyinarp-request - InverseARP Requestreply - standard ARP reply with a MAC addressreply-reverse - reverse ARP (RARP) reply with an IP address assignedrequest - standard ARP request to a known IP address to find out unknown MAC addressrequest-reverse - reverse ARP (RARP) request to a known MAC address to find out the unknown IP address (intended to be used by hosts to find out their own IP address, similarly to DHCP service) | | **arp-packet-type** (*integer 0..65535 \| hex 0x0000-0xffff*; Default: ) | ARP Packet Type. | | **arp-src-address** (*IP address*; Default: ) | ARP source IP address. | | **arp-src-mac-address** (*MAC addres*; Default: ) | ARP source MAC address. | | **chain** (*text*; Default: ) | Bridge firewall chain, which the filter is functioning in (either a built-in one, or a user-defined one). | | **dst-address** (*IP address*; Default: ) | Destination IP address (only if MAC protocol is set to IP). | | **dst-address6** (*IPv6 address*; Default: ) | Destination IPv6 address (only if MAC protocol is set to IPv6). | | **dst-mac-address** (*MAC address*; Default: ) | Destination MAC address. | | **dst-port** (*integer 0..65535*; Default: ) | Destination port number or range (only for TCP or UDP protocols). | | **in-bridge** (*name*; Default: ) | Bridge interface through which the packet is coming in. | | **in-bridge-list** (*name*; Default: ) | Set of bridge interfaces defined in interface list. Works the same as `in-bridge`. | | **in-interface** (*name*; Default: ) | Physical interface (i.e., bridge port) through which the packet is coming in. | | **in-interface-list** (*name*; Default: ) | Set of interfaces defined in interface list. Works the same as `in-interface`. | | **ingress-priority** (*integer 0..63*; Default: ) | Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP or MPLS EXP bit. [read more](./user-guides/wmm-and-vlan-priority.md) | | **ip-protocol** (*dccp \| ddp \| egp \| encap \| etherip \| ggp \| gre \| hmp \| icmp \| icmpv6 \| idpr-cmtp \| igmp \| ipencap \| ipip \| ipsec-ah \| ipsec-esp \| ipv6 \| ipv6-frag \| ipv6-nonxt \| ipv6-opts \| ipv6-route \| iso-tp4 \| l2tp \| ospf \| pim \| pup \| rdp \| rspf \| rsvp \| sctp \| st \| tcp \| udp \| udp-lite \| vmtp \| vrrp \| xns-idp \| xtp*; Default: ) | IP protocol (only if MAC protocol is set to IPv4)dccp - Datagram Congestion Control Protocolddp - Datagram Delivery Protocolegp - Exterior Gateway Protocolencap - Encapsulation Headeretherip - Ethernet-within-IP Encapsulationggp - Gateway-to-Gateway Protocolgre - Generic Routing Encapsulationhmp - Host Monitoring Protocolicmp - IPv4 Internet Control Message Protocolicmpv6 - IPv6 Internet Control Message Protocolidpr-cmtp - Inter-Domain Policy Routing Control Message Transport Protocoligmp - Internet Group Management Protocolipencap - IP in IP (encapsulation)ipip - IP-within-IP Encapsulation Protocolipsec-ah - IPsec Authentication Headeripsec-esp - IPsec Encapsulating Security Payloadipv6 - Internet Protocol version 6ipv6-frag - Fragment Header for IPv6ipv6-nonxt - No Next Header for IPv6ipv6-opts - Destination Options for IPv6ipv6-route - Routing Header for IPv6iso-tp4 - ISO Transport Protocol Class 4l2tp - Layer Two Tunneling Protocolospf - Open Shortest Path Firstpim - Protocol Independent Multicastpup - PARC Universal Packetrdp - Reliable Data Protocolrspf - Radio Shortest Path Firstrsvp - Reservation Protocolsctp - Stream Control Transmission Protocolst - Internet Stream Protocoltcp - Transmission Control Protocoludp - User Datagram Protocoludp-lite - Lightweight User Datagram Protocolvmtp - Versatile Message Transaction Protocolvrrp - Virtual Router Redundancy Protocolxns-idp - Xerox Network Systems Internet Datagram Protocolxtp - Xpress Transport Protocol | | **jump-target** (*name*; Default: ) | If `action=jump` specified, then specifies the user-defined firewall chain to process the packet. | | **limit** (*integer/time,integer*; Default: ) | Matches packets up to a limited rate. A rule using this matcher will match until this limit is reached. count - maximum average packet rate, measured in packets per second (pps), unless followed by Time optiontime - specifies the time interval over which the packet rate is measuredburst - number of packets to match in a burst | | **log**(*yes \| no; Default:***no**) | Add a message to the system log containing the following data: in-interface, out-interface, src-mac, dst-mac, eth-protocol, ip-protocol, src-ip:port->dst-ip:port, and length of the packet. | | **log-prefix** (*text*; Default: ) | Defines the prefix to be printed before the logging information. | | **mac-protocol** (*802.2 \| arp \| capsman \| dot1x \| homeplug-av \| ip \| ipv6 \| ipx \| lacp \| length \| lldp \| loop-protect \| macsec \| mpls-multicast \| mpls-unicast \| mvrp \| packing-compr \| packing-simple \| pppoe \| pppoe-discovery \| rarp \| romon \| service-vlan \| vlan \| integer 0..65535 \| hex 0x0000-0xffff*; Default: ) | Ethernet payload type (MAC-level protocol). To match protocol type for VLAN encapsulated frames (0x8100 or 0x88a8), a vlan-encap property should be used.802.2 - 802.2 Frames (0x0004)arp - Address Resolution Protocol (0x0806)homeplug-av - HomePlug AV MME (0x88E1)ip - Internet Protocol version 4 (0x0800)ipv6 - Internet Protocol Version 6 (0x86DD)ipx - Internetwork Packet Exchange (0x8137)length - Packets with length field (0x0000-0x05DC)lldp - Link Layer Discovery Protocol (0x88CC)loop-protect - Loop Protect Protocol (0x9003)mpls-multicast - MPLS multicast (0x8848)mpls-unicast - MPLS unicast (0x8847)mvrp - Multiple VLAN Registration protocol (0x88F5)packing-compr - Encapsulated packets with compressed IP packing (0x9001)packing-simple - Encapsulated packets with simple IP packing (0x9000)pppoe - PPPoE Session Stage (0x8864)pppoe-discovery - PPPoE Discovery Stage (0x8863)rarp - Reverse Address Resolution Protocol (0x8035)service-vlan - Provider Bridging (IEEE 802.1ad) & Shortest Path Bridging IEEE 802.1aq (0x88A8)vlan - VLAN-tagged frame (IEEE 802.1Q) and Shortest Path Bridging IEEE 802.1aq with NNI compatibility (0x8100) | | **new-packet-mark** (*string*; Default: ) | Sets a new packet-mark value. | | **new-priority** (*integer \| from-ingress*; Default: ) | Sets a new priority for a packet. This can be the VLAN, WMM or MPLS EXP priority [Read more](./user-guides/wmm-and-vlan-priority.md). This property can also be used to set an internal priori | | **out-bridge** (*name*; Default: ) | Outgoing bridge interface. | | **out-bridge-list** (*name*; Default: ) | Set of bridge interfaces defined in interface list. Works the same as `out-bridge`. | | **out-interface** (*name*; Default: ) | Interface that the packet is leaving the bridge through. | | **out-interface-list** (*name*; Default: ) | Set of interfaces defined in [interface list](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md). Works the same as `out-interface`. | | **packet-mark** (*name*; Default: ) | Match packets with a certain packet mark. | | **packet-type** (*broadcast \| host \| multicast \| other-host*; Default: ) | MAC frame type:broadcast - broadcast MAC packethost - packet is destined to the bridge itselfmulticast - multicast MAC packetother-host - packet is destined to some other unicast address, not to the bridge itself | | **src-address** (*IP address*; Default: ) | Source IP address (only if MAC protocol is set to IPv4). | | **src-address6** (*IPv6 address*; Default: ) | Source IPv6 address (only if MAC protocol is set to IPv6). | | **src-mac-address** (*MAC address*; Default: ) | Source MAC address. | | **src-port** (*integer 0..65535*; Default: ) | Source port number or range (only for TCP or UDP protocols). | | **stp-flags** (*topology-change \| topology-change-ack*; Default: ) | The BPDU (Bridge Protocol Data Unit) flags. Bridges exchange configuration messages named BPDU periodically for preventing loopstopology-change - topology change flag is set when a bridge detects port state change, to force all other bridges to drop their host tables and recalculate network topologytopology-change-ack - topology change acknowledgment flag is sent in replies to the notification packets | | **stp-forward-delay** (*integer 0..65535*; Default: ) | Forward delay timer. | | **stp-hello-time** (*integer 0..65535*; Default: ) | STP hello packets time. | | **stp-max-age** (*integer 0..65535*; Default: ) | Maximal STP message age. | | **stp-msg-age** (*integer 0..65535*; Default: ) | STP message age. | | **stp-port** (*integer 0..65535*; Default: ) | STP port identifier. | | **stp-root-address** (*MAC address*; Default: ) | Root bridge MAC address. | | **stp-root-cost** (*integer 0..65535*; Default: ) | Root bridge cost. | | **stp-root-priority** (*integer 0..65535*; Default: ) | Root bridge priority. | | **stp-sender-address** (*MAC address*; Default: ) | STP message sender MAC address. | | **stp-sender-priority** (*integer 0..65535*; Default: ) | STP sender priority. | | **stp-type** (*config \| tcn*; Default: ) | The BPDU type:config - configuration BPDUtcn - topology change notification | | **tls-host** (*string*; Default: ) | Allows matching https traffic based on TLS SNI hostname. Accepts [GLOB syntax](https://en.wikipedia.org/wiki/Glob_(programming)) for wildcard matching. Note that the matcher will not be able to match the hostname if the TLS handshake frame is fragmented into multiple TCP segments (packets). | | **vlan-encap** (*802.2 \| arp \| ip \| ipv6 \| ipx \| length \| mpls-multicast \| mpls-unicast \| pppoe \| pppoe-discovery \| rarp \| vlan \| integer 0..65535 \| hex 0x0000-0xffff*; Default: ) | Matches the MAC protocol type encapsulated in the VLAN frame. | | **vlan-id** (*integer 0..4095*; Default: ) | Matches the VLAN identifier field. | | **vlan-priority** (*integer 0..7*; Default: ) | Matches the VLAN priority (priority code point) | Footnotes: - STP matchers are only valid if the destination MAC address is `01:80:C2:00:00:00/FF:FF:FF:FF:FF:FF` (Bridge Group address), also STP should be enabled. - ARP matchers are only valid if mac-protocol is `arp` or `rarp`. - VLAN matchers are only valid for `0x8100` or `0x88a8` ethernet protocols. - IP or IPv6 related matchers are only valid if mac-protocol is either set to `ip` or `ipv6`. - 802.3 matchers are only consulted if the actual frame is compliant with IEEE 802.2 and IEEE 802.3 standards. These matchers are ignored for other packets. ### Bridge Packet Filter This section describes specific bridge filter options. **Sub-menu:** `/interface/bridge/filter` | Property | Description | | :-- | :-- | | **action** (*accept \| drop \| jump \| log \| mark-packet \| passthrough \| return \| set-priority*; Default: **accept**) | Action to take if the packet is matched by the rule:accept - accept the packet. No action, i.e., the packet is passed through without undertaking any action, and no more rules are processed in the relevant list/chaindrop - silently drop the packet (without sending the ICMP reject message)jump - jump to the chain specified by the value of the jump-target argumentlog - add a message to the system log containing the following data: in-interface, out-interface, src-mac, dst-mac, eth-proto, protocol, src-ip:port->dst-ip:port and length of the packet. After the packet is matched it is passed to the next rule in the list, similar to passthroughmark - mark the packet to use the mark laterpassthrough - ignore this rule and go on to the next one. Acts the same way as a disabled rule, except for the ability to count packetsreturn - return to the previous chain, from where the jump took placeset-priority - set priority specified by the new-priority parameter on the packets sent out through a link that is capable of transporting priority (VLAN or WMM-enabled wireless interface). Read more | ### Bridge NAT This section describes specific bridge NAT options. **Sub-menu:** `/interface/bridge/nat` | Property | Description | | :-- | :-- | | **action** (*accept \| drop \| jump \| mark-packet \| redirect \| set-priority \| arp-reply \| dst-nat \| log \| passthrough \| return \| src-nat*; Default: **accept**) | Action to take if the packet is matched by the rule:accept - accept the packet. No action, i.e., the packet is passed through without undertaking any action, and no more rules are processed in the relevant list/chainarp-reply - send a reply to an ARP request (any other packets will be ignored by this rule) with the specified MAC address (only valid in dstnat chain)drop - silently drop the packet (without sending the ICMP reject message)dst-nat - change the destination MAC address of a packet (only valid in dstnat chain)jump - jump to the chain specified by the value of the jump-target argumentlog - log the packetmark - mark the packet to use the mark laterpassthrough - ignore this rule and go on to the next one. Acts the same way as a disabled rule, except for the ability to count packetsredirect - redirect the packet to the bridge itself (only valid in dstnat chain)return - return to the previous chain, from where the jump took placeset-priority - set the priority specified by the new-priority parameter on the packets sent out through a link that is capable of transporting priority (VLAN or WMM-enabled wireless interface). Read moresrc-nat - change the source MAC address of a packet (only valid in srcnat chain) | | **to-arp-reply-mac-address** (*MAC address*; Default: ) | Source MAC address to put in the Ethernet frame and the ARP payload, when `action=arp-reply` is selected | | **to-dst-mac-address** (*MAC address*; Default: ) | Destination MAC address to put in Ethernet frames, when `action=dst-nat` is selected | | **to-src-mac-address** (*MAC address*; Default: ) | Source MAC address to put in Ethernet frames, when `action=src-nat` is selected | ## See also --- - [CRS1xx/2xx series switches](./crs1xx-and-2xx-series-switches.md) - [Marvell Prestera switch chip features](./marvell-prestera-switch-chip-features.md) - [Switch chip features](./switch-chip-features.md) - [MTU on RouterBOARD](../hardware/mtu-in-routeros.md) - [Layer2 misconfiguration](./user-guides/layer2-misconfiguration.md) - [Bridge VLAN Table](./user-guides/bridge-vlan-table.md) --- ## L3 Hardware Offloading import WideTable from '@site/src/components/WideTable'; # L3 Hardware Offloading **Layer 3 Hardware Offloading** (**L3HW**, otherwise known as IP switching or HW routing) allows offloading some router features onto the switch chip. This allows reaching wire speeds when routing packets, which would simply not be possible with the CPU. ## Switch Configuration To enable Layer 3 Hardware Offloading, set `l3-hw-offloading=yes` for the switch: ```ros /interface/ethernet/switch/set 0 l3-hw-offloading=yes ``` ### Switch Port Configuration Layer 3 Hardware Offloading can be configured for each physical switch port. For example: ```ros /interface/ethernet/switch/port/set sfp-sfpplus1 l3-hw-offloading=yes ``` Note that l3hw settings for switch and ports are different: - Setting `l3-hw-offloading``=no` for the switch completely disables offloading - all packets will be routed by the CPU. - However, setting `l3-hw-offloading``=no` for a switch port only disables hardware routing from/to this particular port. Moreover, the port can still participate in Fasttrack connection offloading. To enable full hardware routing, enable l3hw on all switch ports: ```ros /interface/ethernet/switch/set 0 l3-hw-offloading=yes /interface/ethernet/switch/port/set [find] l3-hw-offloading=yes ``` To make all packets go through the CPU first, and offload only the Fasttrack connections, disable l3hw on all ports but keep it enabled on the switch chip itself: ```ros /interface/ethernet/switch/set 0 l3-hw-offloading=yes /interface/ethernet/switch/port/set [find] l3-hw-offloading=no ``` :::info **Packets are routed by hardware when both the ingress and egress ports have `l3-hw-offloading=yes`.** If both ingress and egress ports have `l3-hw-offloading=no`, packets will go through the CPU/Firewall while offloading only the Fasttrack connections. It is possible to direct packets to go through the CPU/Firewall by setting `l3-hw-offloading=no` on just the egress port. However, setting `l3-hw-offloading=no` only the ingress port may cause unpredictable behavior, for example, packets might still be routed by hardware and completely bypass the CPU/firewall. ::: The next example enables hardware routing on all ports but the upstream port (sfp-sfpplus16). Packets going to/from sfp-sfpplus16 will enter the CPU and, therefore, be subject to Firewall/NAT processing. ```ros /interface/ethernet/switch/set 0 l3-hw-offloading=yes /interface/ethernet/switch/port/set [find] l3-hw-offloading=yes /interface/ethernet/switch/port/set sfp-sfpplus16 l3-hw-offloading=no ``` :::warning The existing connections may be unaffected by the `l3-hw-offloading` setting change. ::: ### L3HW Settings The L3HW Settings menu allows configuring global parameters for the Layer 3 Hardware Offloading driver. **Sub-menu:** `/interface/ethernet/switch/l3hw-settings` | Property | Description | | :--- | :--- | #### Basic Settings The L3HW Settings menu has been introduced in RouterOS version 7.6. **Sub-menu:** `/interface/ethernet/switch/l3hw-settings` | Property | Description | | :-- | :-- | | **autorestart** (*yes \| no*; Default: **no**) | Automatically restarts the l3hw driver in case of an error. Otherwise, if an error occurs, `l3-hw-offloading` gets disabled, and the error code is displayed in the switch settings and [#monitor](./l3-hardware-offloading.md#monitor). Autorestart does not work for system failures, such as OOM (Out Of Memory). | | **fasttrack-hw** (*yes \| no*; Default: **yes**(if supported)) | Enables or disables FastTrack HW Offloading. Keep it enabled unless HW TCAM memory reservation is required, e.g., for dynamic switch ACL rules creation. Not all switch chips support FastTrack HW Offloading (see **hw-supports-fasttrack**). | | **ipv6-hw** (*yes \| no*; Default: **no**) | Enables or disables IPv6 Hardware Offloading. Since IPv6 routes occupy a lot of HW memory, enable it only if IPv6 traffic speed is significant enough to benefit from hardware routing. | | **icmp-reply-on-error** (*yes \| no*; Default: **yes**) | Since the hardware cannot send ICMP messages, the packet must be redirected to the CPU to send an ICMP reply in case of an error (e.g., "Time Exceeded", "Fragmentation required", etc.). Enabling icmp-reply-on-error helps with network diagnostics but may open potential vulnerabilities for DDoS attacks. Disabling icmp-reply-on-error silently drops the packets on the hardware level in case of an error. | **Read-Only Properties** | Property | Description | | :-- | :-- | | **hw-supports-fasttrack** (**yes \| no**) | Indicates if the hardware (switch chip) supports FastTrack HW Offloading. | #### Advanced Settings This menu allows tweaking l3hw settings for specific use cases. :::danger It is NOT recommended to change the advanced L3HW settings unless instructed by MikroTik Support or a MikroTik Certified Routing Engineer. Applying incorrect settings may break the L3HW operation. ::: **Sub-menu:** `/interface/ethernet/switch/l3hw-settings` | Property | Description | | :-- | :-- | | **route-queue-limit-high** (*number*; Default: **256**) | The switch driver stops route indexing when **route-queue-size** (see [#monitor](./l3-hardware-offloading.md#monitor) exceeds this value. Lowering this value leads to faster route processing but increases the lag between a route's appearance in RouterOS and hardware memory. Setting **route-queue-limit-high=0** disables route indexing when there are any routes in the processing queue - the most efficient CPU usage but the longest delay before hardware offloading. Useful when there are static routes only. Not recommended together with routing protocols (such as BGP or OSPF) when there are frequent routing table changes. | | **route-queue-limit-low** (*number*; Default: **0**) | Re-enable route indexing when **route-queue-size** drops down to this value. Must not exceed the high limit. Setting **route-queue-limit-low=0** tells the switch driver to process all pending routes before the next hw-offloading attempt. While this is the desired behavior, it may completely block the hw-offloading under a constant BGP feed. | | **shwp-reset-counter** (*number*; Default: **128**) | Reset the Shortest HW Prefix (see **ipv4-shortest-hw-prefix** / **ipv6-shortest-hw-prefix** in [#monitor](./l3-hardware-offloading.md#monitor) and try the full route table offloading after this number of changes in the routing table. At a partial offload, when the entire routing table does not fit into the hardware memory and shorter prefixes are redirected to the CPU, there is no need to try offloading route prefixes shorter than SHWP since those will get redirected to the CPU anyway, theoretically. However, significant changes to the routing table may lead to a different index layout and, therefore, a different number of routes that can be hw-offloaded. That's why it is recommended to do the full table re-indexing occasionally. Lowering this value may allow more routes to be hw-offloaded but increases CPU usage and vice-versa. Setting **shwp-reset-counter=0** always does full re-indexing after each routing table change. This setting is used only during Partial Offloading and has no effect when **ipv4-shortest-hw-prefix=0** (and ipv6, respectively). | | **partial-offload-chunk** (*number*; Default: **1024**, min: 16) | The minimum number of routes for incremental adding in Partial Offloading. Depending on the switch chip model, routes are offloaded either as-is (each routing entry in RouterOS corresponds to an entry in the hardware memory) or get indexed, and the index entries are the ones that are written into the hardware memory. This setting is used only for the latter during Partial Offloading. Depending on index fragmentation, a single IPv4 route addition can occupy from -3 to +6 LPM blocks of HW memory (some route additions may lower the amount of required HW memory thanks to index defragmentation). Hence, it is impossible to predict the exact number of routes that may fit in the hardware memory. The switch driver uses a binary split algorithm to find the maximum number of routes that fit in the hardware. Let's imagine 128k routes, all of them not fitting into the hardware memory. The algorithm halves the number and tries offloading 64k routes. Let's say offloading succeeded. In the next iteration, the algorithm picks 96k, let's say it fails; then 80k - fails again, 72k - succeeds, 76k, etc. until the difference between succeeded and failed numbers drops below the **partial-offload-chunk** value. Lowering the **partial-offload-chunk** value increases the number of hw-offloaded routes but also raises CPU usage and vice-versa. | | **route-index-delay-min** (*time*; Default: **1s**) | The minimum delay between route processing and its offloading. The delay allows processing more routes together and offloading them at once, saving CPU usage. It also makes offloading the entire routing table faster by reducing the per-route processing work. On the other hand, it slows down the offloading of an individual route. If an additional route is received during the delay, the latter resets to the **route-index-delay-min** value**.** Adding more and more routes within the delay keeps resetting the timer until the **route-index-delay-max** is reached. | | **route-index-delay-max** (*time*; Default: **10s**) | The maximum delay between route processing and its offloading. When the maximum delay is reached, the processed routes get offloaded despite more routes pending. However, **route-queue-limit-high**has higher priority than this, meaning that the indexing/offloading gets paused anyway when a certain queue size is reached. | | **neigh-keepalive-interval** (*time*; Default: **15s**, min: 5s) | Neighbor (host) keepalive interval. When a host (IP neighbor) gets hw-offloaded, all traffic from/to it is routed by the switch chip, and RouterOS may think the neighbor is inactive and delete it. To prevent that, the switch driver must keep the offloaded neighbors alive by sending periodic refreshes to RouterOS. | | **neigh-discovery-interval** (*time*; Default: **1m37s**, min: 30s) | Unfortunately, switch chips do not provide per-neighbor stats. Hence, the only way to check if the offloaded host is still active is by sending occasional ARP (IPv4) / Neighbor Discovery (IPv6) requests to the connected network. Increasing the value lowers the broadcast traffic but may leave inactive hosts in hardware memory for longer. Neighbor discovery is triggered within the neighbor keepalive work. Hence, the discovery time is rounded up to the next keepalive session. Choose a value for **neigh-discovery-interval** not divisible by **neigh-keepalive-interval** to send ARP/ND requests in various sessions, preventing broadcast bursts. | | **neigh-discovery-burst-limit**(*number*; Default: **64**) | The maximum number of ARP/ND requests that can be sent at once. | | **neigh-discovery-burst-delay** (*time*; Default: **300ms**, min: 10ms) | The delay between ARP/ND subsequent bursts if the number of requests exceeds **neigh-discovery-burst-limit****.** | :::info Some settings only apply to certain switch models. ::: #### Monitor The L3HW Monitor feature has been introduced in RouterOS version 7.10. It allows monitoring of switch chip and driver stats related to L3HW. ```ros /interface/ethernet/switch/l3hw-settings/monitor ipv4-routes-total: 99363 ipv4-routes-hw: 61250 ipv4-routes-cpu: 38112 ipv4-shortest-hw-prefix: 24 ipv4-hosts: 87 ipv6-routes-total: 15 ipv6-routes-hw: 11 ipv6-routes-cpu: 4 ipv6-shortest-hw-prefix: 0 ipv6-hosts: 7 route-queue-size: 118 fasttrack-ipv4-conns: 2031 fasttrack-hw-min-speed: 0 nexthop-cap: 8192 nexthop-usage: 93 vxlan-mtu-packet-drop: 0 ``` **Stats** | Property | Description | | :-- | :-- | | Property | Description | | :--- | :--- | | **ipv4-routes-total** | The total number of IPv4 routes handled by the switch driver. | | **ipv4-routes-hw** | The number of hardware-offloaded IPv4 routes (a.k.a. hardware routes) | | **ipv4-routes-cpu** | The number of IPv4 routes redirected to the CPU (a.k.a. software routes) | | **ipv4-shortest-hw-prefix** | *Shortest Hardware Prefix (SHWP)* for IPv4. If the entire IPv4 routing table does not fit into the hardware memory, *partial offloading* is applied, where the longest prefixes are hw-offloaded while the shorter ones are redirected to the CPU. This field shows the shortest route prefix (/x) that is offloaded to the hardware memory. All prefixes shorter than this are processed by the CPU. `ipv4-shortest-hw-prefix=0` means the entire IPv4 routing table is offloaded to the hardware memory. | | **ipv4-hosts** | The number of hardware-offloaded IPv4 hosts (/32 routes) | | **ipv6-routes-total** 1 | The total number of IPv6 routes handled by the switch driver. | | **ipv6-routes-hw** 1 | The number of hardware-offloaded IPv6 routes (a.k.a. hardware routes) | | **ipv6-routes-cpu** 1 | The number of IPv6 routes redirected to the CPU (a.k.a. software routes) | | **ipv6-shortest-hw-prefix** 1 | *Shortest Hardware Prefix (SHWP)* for IPv6. If the entire IPv6 routing table does not fit into the hardware memory, *partial offloading* is applied, where the longest prefixes are hw-offloaded while the shorter ones are redirected to the CPU. This field shows the shortest route prefix (/x) that is offloaded to the hardware memory. All prefixes shorter than this are processed by the CPU. `ipv6-shortest-hw-prefix=0` means the entire IPv6 routing table is offloaded to the hardware memory. | | **ipv6-hosts** 1 | The number of hardware-offloaded IPv6 hosts (/128 routes) | | **route-queue-size** | The number of routes in the queue for processing by the switch chip driver. Under normal working conditions, this field is 0, meaning that all routes are processed by the driver. | | **nexthop-cap** | The nexthop capacity. | | **nexthop-usage** | The number of currently used nexthops. | | **vxlan-mtu-packet-drop** | The number of dropped VXLAN packets due to exceeded interface MTU settings. | | **fasttrack-ipv4-conns** 2 | The number of hardware-offloaded FastTrack connections. | | **fasttrack-hw-min-speed** 2 | When the hardware memory for storing FastTrack is full, this field shows the minimum speed (in bytes per second) of a hw-offloaded FastTrack connection. Slower connections are routed by the CPU. | --- 1 IPv6 stats appear only when IPv6 hardware routing is enabled (`ipv6-hw=yes`) 2 FastTrack stats appear only when hardware offloading of FastTrack connections is enabled (`fasttrack-hw=yes`) #### Advanced Monitor An enhanced version of Monitor with extra telemetry data for advanced users. Advanced Monitor contains all data from the basic monitor plus the fields listed below. ```ros /interface/ethernet/switch/l3hw-settings/advanced> monitor once ipv4-routes-total: 29968 ipv4-routes-hw: 29957 ipv4-routes-cpu: 11 ipv4-shortest-hw-prefix: 0 ipv4-hosts: 3 ipv6-routes-total: 4 ipv6-routes-hw: 0 ipv6-routes-cpu: 4 ipv6-shortest-hw-prefix: 0 ipv6-hosts: 0 route-queue-size: 0 route-queue-rate: 0 route-process-rate: 0 fasttrack-ipv4-conns: 0 fasttrack-queue-size: 0 fasttrack-queue-rate: 0 fasttrack-process-rate: 0 fasttrack-hw-min-speed: 0 fasttrack-hw-offloaded: 0 fasttrack-hw-unloaded: 0 lpm-cap: 54560 lpm-usage: 31931 lpm-bank-cap: 2728 lpm-bank-usage: 46,0,0,0,2589,2591,1983,0,2728,2728,2728,2728,2728,2728,2728,2728,2728,170,0,0 pbr-cap: 8192 pbr-usage: 0 pbr-lpm-bank: 3 nat-usage: 0 nexthop-cap: 8192 nexthop-usage: 85 ``` **Stats** | Property | Description | | :-- | :-- | | **route-queue-rate** | The rate at which routes are added to the queue for processing by the switch driver. In other words, the growth rate of **route-queue-size** (routes per second) | | **route-process-rate** | The rate at which previously queued routes are processed by the switch driver. In other words, the shrink rate of **route-queue-size** (routes per second) | | **fasttrack-queue-size** | The number of FastTrack connections in the queue for processing by the switch chip driver. | | **fasttrack-queue-rate** | The rate at which FastTrack connections are added to the queue for processing by the switch driver. In other words, the growth rate of **fasttrack-queue-size** (connections per second) | | **fasttrack-process-rate** | The rate at which previously queued FastTrack connections are processed by the switch driver. In other words, the shrink rate of **fasttrack-queue-size** (connections per second) | | **fasttrack-hw-offloaded** | The number of FastTrack connections offloaded to the hardware. The counter resets every second (or every monitor interval). | | **fasttrack-hw-unloaded** | The number of FastTrack connections unloaded from the hardware (redirected to software routing). The counter resets every second (or every monitor interval). | | **lpm-cap** | The size of the LPM hardware table (LPM = Longest Prefix Match). LPM stores route indexes for hardware routing. Not every switch chip model uses LPM. Others use TCAM. | | **lpm-usage** | The number of used LPM blocks. **lpm-usage**/ **lpm-cap** = usage percentage. | | **lpm-bank-cap** | LPM memory is organized in banks - special memory units. The bank size depends on the switch chip model. This value shows the size of a single bank (in LPM blocks). **lpm-cap** / **lpm-bank-cap** = the number of banks (usually, 20). | | **lpm-bank-usage** | Per-bank LPM usage (in LPM blocks) | | **pbr-cap** | The size of the Policy-Based Routing (PBR) hardware table. PBR is used for NAT offloading of FastTrack connections. | | **pbr-usage** | The number of used PBR entries. **pbr-usage**/ **pbr-cap** = usage percentage. | | **pbr-lpm-bank** | PBR shares LPM memory banks with routing tables. This value shows the LPM bank index shared with PBR (0 = the first bank). | | **nat-usage** | The number of used NAT hardware entries (for FastTrack connections). | ### Interface Lists It is impossible to use interface lists directly to control `l3-hw-offloading` because an interface list may contain virtual interfaces (such as VLAN) while the `l3-hw-offloading` setting must be applied to physical switch ports only. For example, if there are two VLAN interfaces (vlan20 and vlan30) running on the same switch port (trunk port), it is impossible to enable hardware routing on vlan20 but keep it disabled on vlan30. However, an interface list may be used as a port selector. The following example demonstrates how to enable hardware routing on LAN ports (ports that belong to the "LAN" interface list) and disable it on WAN ports: ```ros :foreach i in=[/interface/list/member/find where list=LAN] do={ /interface/ethernet/switch/port/set [/interface/list/member/get $i interface] l3-hw-offloading=yes } :foreach i in=[/interface/list/member/find where list=WAN] do={ /interface/ethernet/switch/port/set [/interface/list/member/get $i interface] l3-hw-offloading=no } ``` Please take into account that since interface lists are not directly used in hardware routing control, **modifying the interface list also does not automatically reflect in l3hw changes**. For instance, adding a switch port to the "LAN" interface list does not automatically enable `l3-hw-offloading` on it. The user has to rerun the above script to apply the changes. ### MTU The hardware supports up to 8 MTU profiles, meaning that the user can set up to 8 different MTU values for interfaces: the default 1500 + seven custom ones. :::tip It is recommended to disable `l3-hw-offloading` while changing the MTU/L2MTU values on the interfaces. ::: **MTU Change Example** ```ros /interface/ethernet/switch/set 0 l3-hw-offloading=no /interface/set sfp-sfpplus1 mtu=9000 l2mtu=9022 /interface/set sfp-sfpplus2 mtu=9000 l2mtu=9022 /interface/set sfp-sfpplus3 mtu=10000 l2mtu=10022 /interface/ethernet/switch/set 0 l3-hw-offloading=yes ``` ### Layer 2 Dependency Layer 3 hardware processing lies on top of Layer 2 hardware processing. Therefore, L3HW offloading requires L2HW offloading on the underlying interfaces. The latter is enabled by default, but there are some exceptions. For example, MikroTik devices with Marvell Prestera switch support only one hardware bridge. If there are multiple bridges, others are processed by the CPU and are not subject to L3HW. Another example is ACL rules. If a rule redirects traffic to the CPU for software processing, then hardware routing (L3HW) is not triggered: #### ACL rule to disable hardware processing on a specific port ```ros /interface/ethernet/switch/rule/add switch=switch1 ports=ether1 redirect-to-cpu=yes ``` :::tip It is recommended to turn off L3HW offloading during L2 configuration. ::: To make sure that Layer 3 is in sync with Layer 2 on both the software and hardware sides, we recommend disabling L3HW while configuring Layer 2 features. The recommendation applies to the following configuration: - Adding/removing/enabling/disabling bridges. - Adding/removing switch ports to/from the bridge. - Bonding switch ports / removing bonds. - Changing VLAN settings. - Changing MTU/L2MTU on switch ports. - Changing ethernet (MAC) addresses. In short, disable `l3-hw-offloading` while making changes under `/interface/bridge/` and `/interface/vlan/`: #### Layer 2 Configuration Template ```ros /interface/ethernet/switch/set 0 l3-hw-offloading=no /interface/bridge # put bridge configuration changes here /interface/vlan # define/change VLAN interfaces /interface/ethernet/switch/set 0 l3-hw-offloading=yes ``` ### MAC telnet There is a limitation for MAC telnet when L3HW offloading is enabled on **98DX8xxx**, **98DX4xxx,** or **98DX325x** switch chips. Packets from MAC Telnet are dropped and do not reach the CPU, thus access to the device will fail. If MAC telnet is desired in combination with L3HW, a certain ACL rule can be created to force these packets to the CPU. For example, if MAC telnet access on sfp-sfpplus1 and sfp-sfpplus2 is needed, you will need to add this ACL rule. It is possible to select even more interfaces with the `ports` setting. ```ros /interface/ethernet/switch/rule add dst-port=20561 ports=sfp-sfpplus1,sfp-sfpplus2 protocol=udp redirect-to-cpu=yes switch=switch1 ``` ### Inter-VLAN Routing Since L3HW depends on L2HW, and L2HW is the one that does VLAN processing, Inter-VLAN *hardware* routing requires a hardware bridge underneath. Even if a particular VLAN has only one tagged port member, the port must be a bridge member. Do not assign a VLAN interface directly to a switch port! Otherwise, L3HW offloading fails and the traffic will get processed by the CPU: `/interface/vlan/add interface=ether2 name=vlan20 vlan-id=20` Assign the VLAN interface to the bridge instead. This way, VLAN configuration gets offloaded to the hardware, and, with L3HW enabled, the traffic is subject to inter-VLAN hardware routing. #### VLAN Configuration Example ```ros /interface/ethernet/switch/set 0 l3-hw-offloading=no /interface/bridge/port/add bridge=bridge interface=ether2 /interface/bridge/vlan/add bridge=bridge tagged=bridge,ether2 vlan-ids=20 /interface/vlan/add interface=bridge name=vlan20 vlan-id=20 /ip/address/add address=192.0.2.1/24 interface=vlan20 /interface/bridge/set bridge vlan-filtering=yes /interface/ethernet/switch/set 0 l3-hw-offloading=yes ``` :::info For Inter-VLAN routing, the bridge interface must be a tagged member of every routable `/interface/bridge/vlan/` entry. ::: ### Per-VLAN offloading Since RouterOS 7.21, it is possible to configure L3HW offloading per individual VLAN interface using the `l3-hw-offloading=yes|no` setting in the `/interface/vlan` menu. This provides finer control over which VLANs (and their related routes) are offloaded to the switch chip, and which are processed by the CPU. It is no longer necessary to disable L3HW on a switch port in order to disable L3HW routing for specific VLANs. VLAN interface gets offloaded (receives the H flag) only when ALL the following conditions are met: - VLAN interface has `l3-hw-offloading=yes`. - VLAN interface is created on a hardware-offloaded, vlan-filtering bridge. - All switch ports that are the members of the VLAN have l3-hw-offloading=yes. For inter-VLAN routing, both ingress and egress VLANs must be hw-offloaded, otherwise, packets are sent to the CPU. :::info If a switch port carries multiple VLANs with different L3HW settings, keep the port's `l3-hw-enabled=yes`. ::: ### L3HW MAC Address Range Limitation (DX2000/DX3000 series only) Marvell Prestera DX2000 and DX3000 switch chips have a hardware limitation that allows configuring only the last (least significant) octet of the MAC address for each interface. The other five (most significant) octets are configured globally and, therefore, must be equal for all interfaces (switch ports, bridge, VLANs). In other words, the MAC addresses must be in the format "**XX:XX:XX:XX:XX:??**", where: - "**XX:XX:XX:XX:XX**" part is common for all interfaces. - "**??**" is a variable part. **This requirement applies only to Layer 3 (routing).** Layer 2 (bridging) does not use the switch's ethernet addresses. Moreover, it does not apply to bridge ports because they use the bridge's MAC address. The requirement for common five octets applies to: - Standalone switch ports (not bridge members) with hardware routing enabled (`l3-hw-offloading=yes`). - Bridge itself. - VLAN interfaces (those that use the bridge's MAC address by default). ## Route Configuration --- ### Suppressing HW Offload By default, all the routes are hardware candidate routes. To further fine-tune which traffic to offload, there is an option for each route to disable/enable **`suppress-hw-offload`**. For example, if we know that the majority of traffic flows to the network where servers are located, we can enable offloading only to that specific destination: ```ros /ip/route/set [find where static && dst-address!="192.168.3.0/24"] suppress-hw-offload=yes ``` Now only the route to 192.168.3.0/24 has H-flag, indicating that it will be the only one eligible to be selected for HW offloading: ```ros [admin@MikroTik] > /ip/route/print where static Flags: A - ACTIVE; s - STATIC, y - COPY; H - HW-OFFLOADED Columns: DST-ADDRESS, GATEWAY, DISTANCE # DST-ADDRESS GATEWAY D 0 As 0.0.0.0/0 172.16.2.1 1 1 As 10.0.0.0/8 10.155.121.254 1 2 AsH 192.168.3.0/24 172.16.2.1 1 ``` :::danger H-flag does not indicate that the route is actually HW offloaded; it indicates only that the route can be selected to be HW offloaded. ::: ### Routing Filters For dynamic routing protocols like OSPF and BGP, it is possible to suppress HW offloading using [routing filters](../user-guides/routing-and-networking-protocols/route-selection-and-filtering.md). For example, to suppress HW offloading on all OSPF instance routes, use the "**`suppress-hw-offload yes`**" property: ```ros /routing/ospf/instance set [find name=instance1] in-filter-chain=ospf-input /routing/filter/rule add chain="ospf-input" rule="set suppress-hw-offload yes; accept" ``` ### Offloading Fasttrack Connections Firewall filter rules have the **`hw-offload`** option for Fasttrack, allowing fine-tuning connection offloading. Since the hardware memory for Fasttrack connections is very limited, we can choose what type of connections to offload and, therefore, benefit from near-the-wire-speed traffic. The next example offloads only TCP connections while UDP packets are routed via the CPU and do not occupy HW memory: ```ros /ip/firewall/filter add action=fasttrack-connection chain=forward connection-state=established,related hw-offload=yes protocol=tcp add action=fasttrack-connection chain=forward connection-state=established,related hw-offload=no add action=accept chain=forward connection-state=established,related ``` ### Stateless Hardware Firewall While connection tracking and stateful firewalling can be performed only by the CPU, the hardware can perform stateless firewalling via [switch rules (ACL)](./marvell-prestera-switch-chip-features.md#switch-rules-acl). The next example prevents (on a hardware level) accessing a MySQL server from ether1, and redirects packets from ether2 and ether3 to the CPU/Firewall: ```ros /interface/ethernet/switch/rule add switch=switch1 dst-address=10.0.1.2/32 dst-port=3306 ports=ether1 new-dst-ports="" add switch=switch1 dst-address=10.0.1.2/32 dst-port=3306 ports=ether2,ether3 redirect-to-cpu=yes ``` ### Switch Rules (ACL) vs. Fasttrack HW Offloading Some firewall rules may be implemented via both [switch rules (ACL)](./marvell-prestera-switch-chip-features.md#switch-rules-acl) and CPU [Firewall Filter](../firewall-and-quality-of-service/firewall/filter.md) + Fasttrack HW Offloading. Both options grant near-the-wire-speed performance. So the question is which one to use? First, [not all devices support Fasttrack HW Offloading](./l3-hardware-offloading.md#l3hw-device-support), and without HW offloading, Firewall Filter uses only software routing, which is dramatically slower than its hardware counterpart. Second, even if Fasttrack HW Offloading is an option, a rule of thumb is: :::tip Always use Switch Rules (ACL), if possible. ::: Switch rules share the hardware memory with Fasttrack connections. However, hardware resources are allocated for each Fasttrack connection while a single ACL rule can match multiple connections. For example, if you have a guest WiFi network connected to sfp-sfpplus1 VLAN 10 and you don't want it to access your internal network, simply create an ACL rule: ```ros /interface/ethernet/switch/rule add switch=switch1 ports=sfp-sfpplus1 vlan-id=10 dst-address=10.0.0.0/8 new-dst-ports="" ``` The matched packets will be dropped on the hardware level. It is much better than letting *all* guest packets go to the CPU for Firewall filtering. Of course, ACL rules cannot match everything. For instance, ACL rules cannot filter connection states: accept established, drop others. That is where Fasttrack HW Offloading gets into action - redirect the packets to the CPU by default for firewall filtering, then offload the established Fasttrack connections. However, disabling `l3-hw-offloading` for the entire switch or port is not the only option. :::info Define ACL rules with `redirect-to-cpu=yes` instead of setting `l3-hw-offloading=no` on the switch port for narrowing down the traffic that goes to the CPU. ::: ## Configuration Examples --- ### Inter-VLAN Routing with Upstream Port Behind Firewall/NAT This example demonstrates how to benefit from near-to-wire-speed inter-VLAN routing while keeping Firewall and NAT running on the upstream port. Moreover, Fasttrack connections to the upstream port get offloaded to hardware as well, boosting the traffic speed close to wire-level. Inter-VLAN traffic is fully routed by the hardware, not entering the CPU/Firewall, and, therefore, not occupying the hardware memory of Fasttrack connections. We use the **CRS317-1G-16S+** model with the following setup: - sfp1-sfp4 - bridged ports, VLAN ID 20, untagged. - sfp5-sfp8 - bridged ports, VLAN ID 30, untagged. - sfp16 - the upstream port. - ether1 - management port. Set up interface lists for easy access: ### Interface Lists ```ros /interface/list add name=LAN add name=WAN add name=MGMT /interface/list/member add interface=sfp-sfpplus1 list=LAN add interface=sfp-sfpplus2 list=LAN add interface=sfp-sfpplus3 list=LAN add interface=sfp-sfpplus4 list=LAN add interface=sfp-sfpplus5 list=LAN add interface=sfp-sfpplus6 list=LAN add interface=sfp-sfpplus7 list=LAN add interface=sfp-sfpplus8 list=LAN add interface=sfp-sfpplus16 list=WAN add interface=ether1 list=MGMT ``` ### Bridge Setup ```ros /interface/bridge add name=bridge vlan-filtering=yes /interface/bridge/port add bridge=bridge interface=sfp-sfpplus1 pvid=20 add bridge=bridge interface=sfp-sfpplus2 pvid=20 add bridge=bridge interface=sfp-sfpplus3 pvid=20 add bridge=bridge interface=sfp-sfpplus4 pvid=20 add bridge=bridge interface=sfp-sfpplus5 pvid=30 add bridge=bridge interface=sfp-sfpplus6 pvid=30 add bridge=bridge interface=sfp-sfpplus7 pvid=30 add bridge=bridge interface=sfp-sfpplus8 pvid=30 /interface/bridge/vlan add bridge=bridge tagged=bridge untagged=sfp-sfpplus1,sfp-sfpplus2,sfp-sfpplus3,sfp-sfpplus4 vlan-ids=20 add bridge=bridge tagged=bridge untagged=sfp-sfpplus5,sfp-sfpplus6,sfp-sfpplus7,sfp-sfpplus8 vlan-ids=30 ``` Routing requires dedicated VLAN interfaces. For standard L2 VLAN bridging (without inter-VLAN routing), the next step can be omitted. #### VLAN Interface Setup for Routing ```ros /interface/vlan add interface=bridge name=vlan20 vlan-id=20 add interface=bridge name=vlan30 vlan-id=30 /ip/address add address=192.168.20.17/24 interface=vlan20 network=192.168.20.0 add address=192.168.30.17/24 interface=vlan30 network=192.168.30.0 ``` Configure management and upstream ports, a basic firewall, NAT, and enable hardware offloading of Fasttrack connections: #### Firewall Setup ```ros /ip/address add address=192.168.88.1/24 interface=ether1 add address=10.0.0.17/24 interface=sfp-sfpplus16 /ip/route add gateway=10.0.0.1 /ip/firewall/filter add action=fasttrack-connection chain=forward connection-state=established,related hw-offload=yes add action=accept chain=forward connection-state=established,related /ip/firewall/nat add action=masquerade chain=srcnat out-interface-list=WAN ``` At this moment, all routing still is performed by the CPU. Enable hardware routing on the switch chip: #### Enable Layer 3 Hardware Offloading ```ros # Enable full hardware routing on LAN ports :foreach i in=[/interface/list/member/find where list=LAN] do={ /interface/ethernet/switch/port/set [/interface/list/member/get $i interface] l3-hw-offloading=yes } # Disable full hardware routing on WAN or Management ports :foreach i in=[/interface/list/member/find where list=WAN or list=MGMT] do={ /interface/ethernet/switch/port/set [/interface/list/member/get $i interface] l3-hw-offloading=no } # Activate Layer 3 Hardware Offloading on the switch chip /interface/ethernet/switch/set 0 l3-hw-offloading=yes ``` Results: - Within the same VLAN (e.g., sfp1-sfp4), traffic is forwarded by the hardware on Layer 2 *(L2HW)*. - Inter-VLAN traffic (e.g. sfp1-sfp5) is routed by the hardware on Layer 3 *(L3HW).* - Traffic from/to the WAN port gets processed by the CPU/Firewall first. Then Fasttrack connections get offloaded to the hardware *(Hardware-Accelerated L4 Stateful Firewall).* NAT applies both on CPU- and HW-processed packets. - Traffic to the management port is protected by the Firewall. ## Typical Misconfiguration --- Below are typical user errors in configuring Layer 3 Hardware Offloading. ### VLAN interface on a switch port or bond ```ros /interface/vlan add name=vlan10 vlan-id=10 interface=sfp-sfpplus1 add name=vlan20 vlan-id=20 interface=bond1 ``` Due to Layer 2 dependency, only VLAN interfaces created on a hardware-offloaded, vlan-filtering bridge is capable of L3HW offloading. The correct configuration is: ```ros /interface/bridge/port add bridge=bridge1 interface=sfp-sfpplus1 frame-types=admit-only-vlan-tagged add bridge=bridge1 interface=bond1 frame-types=admit-only-vlan-tagged /interface/bridge/vlan add bridge=bridge1 tagged=bridge1,sfp-sfpplus1 vlan-ids=10 add bridge=bridge1 tagged=bridge1,bond1 vlan-ids=20 /interface/vlan add name=vlan10 vlan-id=10 interface=bridge1 add name=vlan20 vlan-id=20 interface=bridge1 ``` :::warning If VLAN interfaces are created directly on Ethernet or bonding interfaces, packets may be offloaded incorrectly - bypassing CPU processing (such as firewall and NAT) and causing undefined behavior. If this type of configuration is required, L3HW offloading must be disabled on the related switch ports under the `/interface/ethernet/switch/port` menu by setting `l3-hw-offloading=no`. ::: ### Not adding the bridge interface to /interface/bridge/vlan/ For Inter-VLAN routing, the bridge interface itself needs to be added to the tagged members of the given VLANs. In the next example, Inter-VLAN routing works between VLAN 10 and 11, but packets are NOT routed to VLAN 20. ```ros /interface/bridge/vlan add bridge=bridge1 vlan-ids=10 tagged=bridge1,sfp-sfpplus1 add bridge=bridge1 vlan-ids=11 tagged=bridge1 untagged=sfp-sfpplus2,sfp-sfpplus3 add bridge=bridge1 vlan-ids=20 tagged=sfp-sfpplus1 untagged=sfp-sfpplus4,sfp-sfpplus5 ``` The above example does not always mean an error. Sometimes, you may want the device to act as a simple L2 switch in some/all VLANs. Just make sure you set such behavior on purpose, not due to a mistake. ### Creating multiple bridges The devices support only one hardware bridge. If there are multiple bridges created, only one gets hardware offloading. While for L2 that means software forwarding for other bridges, in the case of L3HW, multiple bridges may lead to undefined behavior. :::tip Instead of creating multiple bridges, create one and segregate L2 networks with VLAN filtering. ::: ### Using ports that do not belong to the switch Some devices have two switch chips or the management port directly connected to the CPU. For example, **CRS312-4C+8XG** has an **ether9** port connected to a separate switch chip. Trying to add this port to a bridge or involve it in the L3HW setup leads to unexpected results. Leave the management port for management! ```ros [admin@crs312] /interface/ethernet/switch> print Columns: NAME, TYPE, L3-HW-OFFLOADING # NAME TYPE L3-HW-OFFLOADING 0 switch1 Marvell-98DX8212 yes 1 switch2 Atheros-8227 no [admin@crs312] /interface/ethernet/switch> port print Columns: NAME, SWITCH, L3-HW-OFFLOADING, STORM-RATE # NAME SWITCH L3-HW-OFFLOADING STORM-RATE 0 ether9 switch2 1 ether1 switch1 yes 100 2 ether2 switch1 yes 100 3 ether3 switch1 yes 100 4 ether4 switch1 yes 100 5 ether5 switch1 yes 100 6 ether6 switch1 yes 100 7 ether7 switch1 yes 100 8 ether8 switch1 yes 100 9 combo1 switch1 yes 100 10 combo2 switch1 yes 100 11 combo3 switch1 yes 100 12 combo4 switch1 yes 100 13 switch1-cpu switch1 100 14 switch2-cpu switch2 ``` ### Relying on Fasttrack HW Offloading too much Since Fasttrack HW Offloading offers near-the-wire-speed performance at zero configuration overhead, users are tempted to use it as the default solution. However, the number of HW Fasttrack connections is very limited, leaving the other traffic for the CPU. Try using the hardware routing as much as possible, reduce the CPU traffic to the minimum via switch ACL rules, and then fine-tune which Fasttrack connections to offload with firewall filter rules. ### Trying to offload slow-path connections Using certain configurations (e.g. enabling bridge "**use-ip-firewall**" setting, creating bridge nat/filter rules) or running specific features like sniffer or torch can disable RouterOS [FastPath](../firewall-and-quality-of-service/packet-flow-in-routeros.md#fast-path), which will affect the ability to properly FastTrack and HW offload connections. If HW offloaded Fasttrack is required, make sure that there are no settings that disable the FastPath and verify that connections are getting the "H" flag or use the L3HW [monitor](./l3-hardware-offloading.md#monitor) command to see the number of HW offloaded connections. ## L3HW Feature Support - **HW** - The feature is supported and offloaded to the hardware. - **CPU** - The feature is supported but performed by software (CPU). - **N/A** - The feature is not available together with L3HW. Layer 3 hardware offloading must be completely disabled (**switch** `l3-hw-offloading=no`) to make this feature work. - **FW** - The feature requires `l3-hw-offloading=no` for a given **switch port**. On the **switch** level, `l3-hw-offloading=yes`. | Feature | Support | Comments | Release | | :-- | :-- | :-- | :-- | | IPv4 Unicast Routing | **HW** | | 7.1 | | IPv6 Unicast Routing | **HW** | `/interface/ethernet/switch/l3hw-settings/set ipv6-hw=yes` | 7.6 | | IPv4 Multicast Routing | **CPU** | | | | IPv6 Multicast Routing | **CPU** | | | | ECMP | **HW** | Multipath routing | 7.1 | | Blackholes | **HW** | `/ip/route/add dst-address=10.0.99.0/24 blackhole` | 7.1 | | `gateway=` | **CPU/HW** | `/ip/route/add dst-address=10.0.0.0/24 gateway=ether1` This works only for directly connected networks. Since HW does not know how to send ARP requests, CPU sends an ARP request and waits for a reply to find out the DST MAC address on the first received packet of the connection that matches a DST IP address. After DST MAC is determined, HW entry is added and all further packets will be processed by the switch chip. | 7.1 | | Bridge | **HW** | Routing from/to [hardware-offloaded bridge](./#bridge-hardware-offloading) interface. | 7.1 | | VLAN | **HW** | Routing between VLAN interfaces that are created on hardware-offloaded bridge interface with [vlan-filtering](index.md#bridge-vlan-filtering). `/interface/vlan` | 7.1 | | Bonding | **HW** | Routing between bonding interfaces. `/interface/bonding` Only `802.3ad` and `balance-xor` bonding modes are hardware offloaded. | 7.1 | | IPv4 Firewall | **FW** | Users must choose either HW-accelerated routing or firewall. Firewall rules get processed by the CPU. ***Fasttrack*** connections get offloaded to HW. | 7.1 | | IPv4 NAT | **FW** | NAT rules applied to the offloaded ***Fasttrack*** connections get processed by HW too. | 7.1 | | MLAG | **N/A** | | | | VRF | **N/A** | Only the **main** routing table gets offloaded. If VRF is used together with L3HW and packets arrive on a switch port with `l3-hw-offloading=yes`, packets can be incorrectly routed through the main routing table. To avoid this, disable L3HW on needed switch ports or use ACL rules to redirect specific traffic to the CPU. | | | VRRP | **N/A** | | | | Controller Bridge and Port Extender | **N/A** | | | | Traffic-Flow | **N/A** | L3HW offloaded traffic is not reported through [Traffic Flow](../diagnostics-monitoring-and-troubleshooting/traffic-flow/index.md). | | | VXLAN | **HW** | Support for hardware-offloaded [VXLAN](./vxlan.md) data plane, VXLAN encapsulation and decapsulation. This allows for static one-to-one VLAN-to-VXLAN mappings within a vlan-filtering bridge. At this point, some known features are not yet implemented. **Underlay (routing encapsulated VXLAN packets):** 1. VTEPs are not supported over ECMP 2. VTEPs are not supported over bond, bridge, VLAN interfaces (only stand-alone routed Ethernet interfaces are supported) 3. VTEPs are not supported over multicast 4. VTEPs cannot operate within VRFs 5. VTEPs are not supported with IPv6 **Overlay (forwarding between Ethernet and VXLAN):** 1. VLAN tagging over VXLAN is not supported 2. Routing between different VXLAN VNIs is not supported 3. VTEPs are isolated, and there is no mechanism to control "horizon" between them. 4. Bridged VXLAN interfaces do not support IGMP snooping. When snooping is enabled, MDB entries on VXLAN are not offloaded, and multicast traffic gets restricted between Ethernet and VXLAN. 5. Bridged VXLAN interfaces are not supported by MLAG. `/interface/vxlan` | 7.18 | | MTU | **HW** | The hardware supports up to 8 MTU profiles. | 7.1 | | QinQ Routing | **CPU** | Stacked routable VLAN interfaces will lose L3HW offloading, while routable VLAN interfaces created directly on the bridge interface can still use HW offloading. | | Only the devices listed in the table below support L3 HW Offloading. ## L3HW Device Support Only the devices listed in the table below support L3 HW Offloading. ### CRS3xx: Switch 98DX3xxx and 98DX2xxx Series The devices below are based on **Marvell **98DX224S, 98DX226S****, **98DX2528,** or **98DX3236** switch chip models. :::info The **98DX3255** and **98DX3257** models are exceptions, which have a feature set of the 98DX8xxx rather than the 98DX3xxx series. **Caution:** Below are some important features that these devices are missing when compared to other switch models: - Fasttrack and NAT connection offloading; - per-VLAN packet and byte counters; - VXLAN offloading. ::: | Switch Chip | Models | IPv4 Route Prefixes 1 | IPv6 Route Prefixes 2 | Nexthops | ECMP paths per prefix 3 | | :--- | :--- | :---: | :---: | :---: | :---: | | **98DX3236** | CRS305-1G-4S+IN CRS326-24G-2S+ (RM/IN) CRS328-24P-4S+RM CRS328-4C-20S-4S+RM | 13312 | 3328 | 4K | 8 | | **98DX226S** | CRS305-1G-4S+OUT (FiberBox Plus) CRS310-1G-5S-4S+ (netFiber 9/IN) CRS310-8G+2S+IN CRS318-16P-2S+OUT (netPower 16P) CRS320-8P-8B-4S+RM CRS418-8P-8G-2S+RM CRS418-8P-8G-2S+5axQ2axQ-RM | 13312 | 3328 | 4K | 8 | | **98DX224S** | CRS318-1Fi-15Fr-2S-OUT (netPower 15FR) | 13312 | 3328 | 4K | 8 | | **98DX2528** | CRS304-4XG-IN | 13312 | 3328 | 4K | 8 | --- 1 Since the total number of routes that can be offloaded is limited, prefixes with higher netmask are preferred to be forwarded by hardware (e.g., /32, /30, /29, etc.). Any other prefixes that do not fit in the HW table will be processed by the CPU. Directly connected hosts are offloaded as /32 (IPv4) or /128 (IPv6) route prefixes. The number of hosts is also limited by max-neighbor-entries in [IP Settings](../cli-reference/ip/settings.md) / [IPv6 Settings](../cli-reference/ipv6/settings.md). 2 IPv4 and IPv6 routing tables share the same hardware memory. 3 If a route has more paths than the hardware ECMP limit (X), only the first X paths get offloaded. #### Partial offloading In the case of **98DX3xxx**, **98DX2xxx** switch chip series, it is quite simple: one RouterOS route entry (/ip/route/) reflects into one HW IPv4 route prefix entry. Connected hosts (/32 routes) also occupy the same table. As long as the total number of routes ("/ip/route/print count-only") + connected host count ("/ip/arp/print count-only where status=reachable or status=stale"), does not exceed **13312 (13k)**, everything gets offloaded. Exceeding the number, routes with *shorter* prefixes stay on the CPU. ### CCR2xxx, CRS3xx, CRS5xx: Switch 98DX8xxx and 98DX4xxx Series The devices below are based on **Marvell 98DX8xxx**, **98DX4xxx** switch chips, or **98DX325x** model. | Switch Chip | Models | IPv4 Routes 1 | IPv4 Hosts 5 | IPv6 Routes 1 | IPv6 Hosts 5 | Nexthops | IPv4 Fasttrack connections 2, 3, 4 | IPv4 NAT entries 2, 4 | IPv4 Fasttrack/NAT, VXLAN offloading Per-VLAN packet/byte counters | | :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | | **98DX8208** | CRS309-1G-8S+IN | up to 36K | up to 16K | up to 6K | up to 12K | 8K | 4.5K | 3.9K | + | | **98DX8212** | CRS312-4C+8XG-RM | up to 36K | up to 16K | up to 6K | up to 12K | 8K | 2.25K | 2.25K | + | | **98DX8216** | CRS317-1G-16S+RM | up to 240K | up to 64K | up to 40K | up to 48K | 8K | 4.5K | 4K | + | | **98DX8332** | CRS326-24S+2Q+RM CRS326-4C+20G+2Q+RM | up to 36K | up to 16K | up to 6K | up to 12K | 8K | 2.25K | 2.25K | + | | **98DX3257** 6 | CRS354-48G-4S+2Q+RM CRS354-48P-4S+2Q+RM | up to 36K | up to 16K | up to 6K | up to 12K | 8K | 2.25K | 2.25K | + | | **98DX4310** | CRS504-4XQ (IN/OUT) CRS510-8XS-2XQ-IN RDS2216-2XG-4S+4XS-2XQ | up to 120K | up to 64K | up to 20K | up to 48K | 8K | 4.5K | 4K | + | | **98CX8410** | CRS520-4XS-16XQ-RM | up to 240K | up to 64K | up to 40K | up to 48K | 8K | 4.5K | 4K | + | | **98DX3255** 6 | CCR2116-12G-4S+ | up to 36K | up to 16K | up to 6K | up to 12K | 8K | 2.25K | 2.25K | + | | **98DX8525** | CCR2216-1G-12XS-2XQ CRS518-16XS-2XQ-RM | up to 120K | up to 64K | up to 20K | up to 48K | 8K | 4.5K | 4K | + | 1 Depends on the complexity of the routing table. Whole-byte IP prefixes (/8, /16, /24, etc.) occupy less HW space than others (e.g., /22). When the Routing HW table gets full, only routes with longer subnet prefixes are offloaded (/30, /29, /28, etc.) while the CPU processes the shorter prefixes. Users can fine-tune what routes to offload via routing filters (for dynamic routes) or suppressing hardware offload per switch port, static route or VLAN. IPv4 and IPv6 routing tables share the same hardware memory. 2 When the HW limit of Fasttrack or NAT entries is reached, other connections will fall back to the CPU. MikroTik's smart connection offload algorithm ensures that the connections with the most traffic are offloaded to the hardware. 3 Fasttrack connections share the same HW memory with ACL rules. Depending on the complexity, one ACL rule may occupy the memory of 3-6 Fasttrack connections. 4 If a Fasttrack connection requires Network Address Translation, a hardware NAT entry is created. The hardware supports both SRCNAT and DSTNAT. 5 DX4000/DX8000 switch chips store directly connected hosts, IPv4 /32, and IPv6 /128 route entries in the FDB table rather than the routing table. The HW memory is shared between regular FDB L2 entries (MAC), IPv4, and IPv6 addresses. The number of hosts is also limited by max-neighbor-entries in [IP Settings](../cli-reference/ip/settings.md) / [IPv6 Settings](../cli-reference/ipv6/settings.md). 6 The switch chip has a feature set of the DX8000 series. #### Partial offloading The **98DX8xxx**, **98DX4xxx** have entirely different routing tables. Instead of prefixes, we have to offload route indexes. The entire IPv4 address range (same for IPv6) must be indexed, i.e., 0.0.0.0 - 255.255.255.255. Adding new route entries causes an index rebuild, increasing hardware memory by 0-5 entries depending on the complexity of the routing table. That's why no exact numbers are given. For example, some routing tables containing 240K entries can be fully offloaded to CRS317 HW, while others with 160K entries barely fit. And you will never know until you try. When indexing the entire IP address range (0.0.0.0 - 255.255.255.255), you can offload as many routes as needed, as long as you also have a default route (0.0.0.0/0) using the same next-hop. For example, on a CCR2216 router around 950k routes with a /30 prefix are created, all using the same next-hop along with a default route. As a result, all routes were offloaded, while the lpm-usage remained minimal. ```routeros [admin@MikroTik] > /interface/ethernet/switch/l3hw-settings/advanced/monitor ipv4-routes-total: 942338 ipv4-routes-hw: 942326 ipv4-routes-cpu: 11 ipv4-shortest-hw-prefix: 0 ipv4-hosts: 1 route-queue-size: 0 route-queue-rate: 0 route-process-rate: 0 nexthop-cap: 8192 nexthop-usage: 85 vxlan-mtu-packet-drop: 0 fasttrack-ipv4-conns: 0 fasttrack-queue-size: 0 fasttrack-queue-rate: 0 fasttrack-process-rate: 0 fasttrack-hw-min-speed: 0 fasttrack-hw-offloaded: 0 fasttrack-hw-unloaded: 0 lpm-cap: 27200 lpm-usage: 11 lpm-bank-cap: 1360 lpm-bank-usage: 1 0 0 0 1 0 0 0 4 0 0 0 5 0 0 0 0 0 0 0 pbr-cap: 8192 pbr-usage: 0 pbr-lpm-bank: 2 nat-usage: 0 ``` However, if there are "gaps" in the address range, such as not using a default route or having multiple next-hops, this consumes HW table. When the routing HW table gets full, only routes with longer subnet prefixes are offloaded (/30, /29, /28, etc.) while the CPU processes the shorter prefixes. Here is what happens when the default route gets disabled or different next-hops are used: only 37k routes with a /30 prefix fit in the HW table. This is the worst-case scenario for the CCR2216. ```routeros [admin@MikroTik] > /interface/ethernet/switch/l3hw-settings/advanced/monitor ipv4-routes-total: 942337 ipv4-routes-hw: 37729 ipv4-routes-cpu: 904608 ipv4-shortest-hw-prefix: 30 ipv4-hosts: 1 route-queue-size: 0 route-queue-rate: 0 route-process-rate: 0 nexthop-cap: 8192 nexthop-usage: 85 vxlan-mtu-packet-drop: 0 fasttrack-ipv4-conns: 0 fasttrack-queue-size: 0 fasttrack-queue-rate: 0 fasttrack-process-rate: 0 fasttrack-hw-min-speed: 0 fasttrack-hw-offloaded: 0 fasttrack-hw-unloaded: 0 lpm-cap: 27200 lpm-usage: 22392 lpm-bank-cap: 1360 lpm-bank-usage: 1022 1033 1027 1028 1221 1033 1040 678 1358 1245 1254 1242 1246 1249 1273 1260 1101 1024 1031 1027 pbr-cap: 8192 pbr-usage: 0 pbr-lpm-bank: 2 nat-usage: 0 ``` In many cases, the default behavior "offloading only routes with longer subnet prefixes" is not optimal, especially if the ratio of CPU-handled routes to HW-offloaded routes is too high. When this happens, the chances of a packet being hardware-forwarded drop significantly. If HW memory is insufficient and partial offloading occurs, a better approach for you as a network administrator would be to offload only the routes that carry the most traffic while keeping less demanding routes on the CPU, and not letting the partial offloading happen. Fortunately, there are several ways to manage this. There is per-switch-port and static route suppression, and [filtering dynamic routes using a wide range of attributes](../user-guides/routing-and-networking-protocols/route-selection-and-filtering.md). One example is to use as-path to filter most demanding prefixes (Google, Meta), while all other routes get L3HW suppressed. ### CRS8xx: Switch 98DX7xxx Series The devices below are based on **Marvell 98DX7xxx** switch chip models. :::danger The software support for the following features is still in development and not available yet: - FastTrack and NAT connection offloading - VXLAN offloading ::: | Switch Chip | Models | IPv4 Routes 1 | IPv4 Hosts 2 | IPv6 Routes 1 | IPv6 Hosts 2 | Nexthops | IPv4 Fasttrack connections | IPv4 NAT entries | VXLAN offloading | Per-VLAN packet/byte counters | | :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | | **98DX7335** | CRS812-8DS-2DQ-2DDQ-RM | up to 240K | up to 64K | up to 40K | up to 48K | 16K | to be announced | to be announced | to be announced | + | | **98DX7335** | CRS804-4DDQ-hRM | up to 240K | up to 64K | up to 40K | up to 48K | 16K | to be announced | to be announced | to be announced | + | --- 1 Depends on the complexity of the routing table. Whole-byte IP prefixes (/8, /16, /24, etc.) occupy less HW space than others (e.g., /22). When the Routing HW table gets full, only routes with longer subnet prefixes are offloaded (/30, /29, /28, etc.) while the CPU processes the shorter prefixes. Users can fine-tune what routes to offload via routing filters (for dynamic routes) or suppressing hardware offload of static routes. IPv4 and IPv6 routing tables share the same hardware memory. 2 98DX7xxx switch chips store directly connected hosts, IPv4 /32 route entries, and IPv6 /128 route entries in the FDB table rather than the routing table. The HW memory is shared between regular FDB L2 entries (MAC), IPv4 addresses, and IPv6 addresses. The number of hosts is also limited by max-neighbor-entries in [IP Settings](../cli-reference/ip/settings.md) / [IPv6 Settings](../cli-reference/ipv6/settings.md). --- ## MACsec The MACsec (Media Access Control Security) protocol is a standard security technology employed in Ethernet networks to ensure the confidentiality, integrity, and authenticity of data transmitted over the physical medium. MACsec is defined by IEEE standard 802.1AE. MACsec utilizes GCM-AES-128 encryption over Ethernet and secures all LAN traffic, including DHCP, ARP, LLDP, and higher-layer protocols. :::warning RouterOS MACsec implementation is in the early stage; it **does not support** dynamic key management via [Dot1x](../authentication-authorization-accounting/dot1x.md) (manual key configuration is required) and hardware-accelerated encryption is only being rolled out on select products. ::: ## Basic Configuration Example Imagine Host1 ether1 is connected to Switch ether1 and Host2 ether1 is connected to Switch ether2. In this example, we will create two MACsec interface pairs and use a bridge to create a secure Layer2 connection between both end devices. First, configure MACsec interfaces on Host1 and Host2. We can specify only the Ethernet interface and RouterOS will automatically generate the Connectivity Association Key (CAK) and connectivity association name (CKN). Use the `print` command to see the values: ```ros # Host1 /interface/macsec add interface=ether1 name=macsec1 [admin@Host1] /interface/macsec/print show-sensitive Flags: I - inactive, X - disabled, R - running 0 name="macsec1" mtu=1468 interface=ether1 status="negotiating" cak=71a7c363794da400dbde595d3926b0e9 ckn=f2c4660060169391d29d8db8a1f06e5d4b84a128bad06ad43ea2bd4f7d21968f profile=default # Host2 /interface/macsec add interface=ether1 name=macsec1 [admin@Host2] /interface/macsec/print show-sensitive Flags: I - inactive, X - disabled, R - running 0 name="macsec1" mtu=1468 interface=ether1 status="negotiating" cak=dc47d94291d19a6bb26a0c393a1af9a4 ckn=e9bd0811dad1e56f06876aa7715de1855f1aee0baf5982ac8b508d4fc0f162d9 profile=default ``` On the Switch device, to enable MACsec we need to configure the matching CAK and CKN values for the appropriate Ethernet interface: ```ros # Switch /interface/macsec add comment=Host1 cak=71a7c363794da400dbde595d3926b0e9 ckn=f2c4660060169391d29d8db8a1f06e5d4b84a128bad06ad43ea2bd4f7d21968f interface=ether1 name=macsec1 add comment=Host2 cak=dc47d94291d19a6bb26a0c393a1af9a4 ckn=e9bd0811dad1e56f06876aa7715de1855f1aee0baf5982ac8b508d4fc0f162d9 interface=ether2 name=macsec2 ``` Once the pre-shared keys are successfully exchanged, the MACsec Key Agreement (MKA) protocol is activated. MKA is responsible for ensuring the continuity of MACsec on the link and determines which side becomes the key server in a point-to-point connection. The key server generates a Secure Association Key (SAK) that is shared exclusively with the device on the other end of the link. This SAK is used to secure all data traffic passing through the link. Periodically, the key server generates a new randomly-created SAK and shares it over the point-to-point link to maintain MACsec functionality. In RouterOS, the MACsec interface can be configured like any Ethernet interface. It can be used as a routable interface with an IP address, or placed inside a bridge. On Host1 and Host2 we will add an IP address from the same network. On Switch, we will use a bridge. ```ros # Host1 /ip/address add address=192.168.10.10/24 interface=macsec1 # Host2 /ip/address add address=192.168.10.20/24 interface=macsec1 # Switch /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=macsec1 add bridge=bridge1 interface=macsec2 ``` Last, confirm that Host1 can reach Host2 using a ping. ```ros [admin@Host1] > ping 192.168.10.20 SEQ HOST SIZE TTL TIME STATUS 0 192.168.10.20 56 64 1ms438us 1 192.168.10.20 56 64 818us 2 192.168.10.20 56 64 791us 3 192.168.10.20 56 64 817us 4 192.168.10.20 56 64 783us sent=5 received=5 packet-loss=0% min-rtt=783us avg-rtt=929us max-rtt=1ms438us ``` ## Property Reference ### Interface settings **Sub-menu:** `/interface/macsec` Configuration settings for the MACsec interface. | Property | Description | | :-- | :-- | | **cak** (*string*; Default: ) *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | A 16-byte pre-shared connectivity association key (CAK). To enable MACsec, configure the matching CAK and CKN on both ends of the link. When not specified, RouterOS will automatically generate a random value. | | **ckn**(*string*; Default: ) | A 32-byte connectivity association name (CKN). To enable MACsec, configure the matching CAK and CKN on both ends of the link. When not specified, RouterOS will automatically generate a random value. | | **comment** (*string*; Default: ) | Short description of the interface. | | **disabled** (*yes \| no*; Default: **no**) | Changes whether the interface is disabled. | | **interface** (*name*; Default: ) | Ethernet interface name where MACsec is created, limited to one MACsec interface per Ethernet. | | **mtu** (*integer*; Default: **1468**) | Sets the maximum transmission unit. The `l2mtu` will be set automatically according to the associated `interface` (subtracting 32 bytes corresponding to the MACsec encapsulation). The `l2mtu` cannot be changed. | | **name** (*string*; Default: **macsec1**) | Name of the interface. | | **profile** (*name*; Default: **default**) | Sets the MACsec profile, used for determining the key server in a point-to-point connection. | | **status** (*read-only: disabled \|initializing \| invalid \| negotiating \| open-encrypted*) | Shows the current MACsec interface status. | ### Profile settings **Sub-menu:** `/interface/macsec/profile` Configuration settings for the MACsec profile. | Property | Description | | :-- | :-- | | **name** (*string*; Default: ) | Name of the profile. | | **server-priority**(*integer: 0..255*; Default: **10**) | Sets the priority for determining the key server in a point-to-point connection. A lower value means higher priority. In case of a priority match, the interface with the lowest MAC address will be acting as a key server. | --- ## MACVLAN The MACVLAN provides a means to create multiple virtual network interfaces, each with its own unique Media Access Control (MAC) address, attached to a physical network interface. This technology is utilized to address specific network requirements, such as obtaining multiple IP addresses or establishing distinct PPPoE client connections from a single physical Ethernet interface while using different MAC addresses. Unlike traditional [VLAN](./vlan.md) (Virtual LAN) interfaces, which rely on Ethernet frames tagged with VLAN identifiers, MACVLAN operates at the MAC address level, making it a versatile and efficient solution for specific networking scenarios. :::info A MACVLAN interface can only receive broadcast packets, packets addressed to its own MAC address, and a limited number of multicast addresses. If the physical interface has a VLAN configured, the MACVLAN interface cannot receive packets from that VLAN. For bridging and more complex Layer2 solutions involving VLANs, a dedicated switch should be used instead. ::: ## Basic Configuration Example Picture a scenario where the ether1 interface connects to your ISP, and your router needs to lease two IP addresses, each with a distinct MAC address. Traditionally, this would require the use of two physical Ethernet interfaces and an additional switch. However, a more efficient solution is to create a virtual MACVLAN interface. To create a MACVLAN interface, select the needed Ethernet interface. A MAC address will be automatically assigned if not manually specified: ```ros /interface/macvlan add interface=ether1 name=macvlan1 /interface/macvlan/print Flags: R - RUNNING Columns: NAME, MTU, INTERFACE, MAC-ADDRESS, MODE # NAME MTU INTERFACE MAC-ADDRESS MODE 0 R macvlan1 1500 ether1 76:81:BF:68:69:83 bridge ``` Now, a DHCP client can be created on the ether1 and macvlan1 interfaces: ```ros /ip/dhcp-client add interface=ether1 add interface=macvlan1 ``` ## Property Reference **Sub-menu:** `/interface/macvlan` Configuration settings for the MACVLAN interface. | Property | Description | | :-- | :-- | | **arp** (*disabled \| enabled \| local-proxy-arp \| proxy-arp \| reply-only*; Default: **enabled**) | Address Resolution Protocol settingdisabled - the interface will not use ARPenabled - the interface will use ARPlocal-proxy-arp - the router performs proxy ARP on the interface and sends replies to the same interfaceproxy-arp - the router performs proxy ARP on the interface and sends replies to other interfacesreply-only - the interface will only reply to requests originating from matching IP address/MAC address combinations, which are entered as static entries in the IP/ARP table. No dynamic entries will be automatically stored in the IP/ARP table. Therefore, for communications to be successful, a valid static entry must already exist. | | **arp-timeout** (*auto \| integer*; Default: **auto**) | Sets how long the ARP record is kept in the ARP table after no packets are received from IP. Value `auto` equals the value of `arp-timeout` in `/ip/settings/`, default is 30s. | | **comment** (*string*; Default: ) | Short description of the interface. | | **disabled** (*yes \| no*; Default: **no**) | Changes whether the interface is disabled. | | **interface** (*name*; Default: ) | The name of the underlying interface on which the MACVLAN will operate. MACVLAN interfaces can be created on any interface that has a MAC address. **Warning:** Adding a VLAN interface on top of a MACVLAN interface is not supported.Adding MACVLAN on an interface which is already bridged or bonded is not supported. | | **loop-protect** (*on \| off \| default*; Default: **default**) | Enables or disables loop protect on the interface, the **default** works as turned off. | | **loop-protect-disable-time** (*time interval \| 0*; Default: **5m**) | Sets how long the selected interface is disabled when a loop is detected. **0** - forever. | | **loop-protect-send-interval** (*time interval*; Default: **5s**) | Sets how often loop protect packets are sent on the selected interface. | | **mac-address** (*MAC*; Default: ) | Static MAC address of the interface. A randomly generated MAC address will be assigned when not specified. | | **mode** (*private \| bridge*; Default: **bridge**) | Sets MACVLAN interface mode: private - does not allow communication between MACVLAN instances on the same parent interface.bridge - allows communication between MACVLAN instances on the same parent interface. | | **mtu** (*integer*; Default: **1500**) | Sets Layer 3 Maximum Transmission Unit. For the MACVLAN interface, it cannot be higher than the parent **interface**. | | **name** (*string*; Default: ) | Interface name. | --- ## Marvell Prestera switch chip features import WideTable from '@site/src/components/WideTable'; # Marvell Prestera switch chip features --- Some MikroTik devices use high-performance and feature-rich Marvell Prestera Ethernet switches. These devices can be designed into various Ethernet applications including unmanaged switch, Layer 2 managed switch, carrier switch, inter-VLAN router, and wired unified packet processor. :::warning This article applies only to MikroTik devices with Marvell Prestera switch, not to [CRS1xx/CRS2xx series switches](./crs1xx-and-2xx-series-switches.md). ::: ### Features | Features | Description | | :-- | :-- | | **Forwarding** | Configurable ports for switching or routingFull non-blocking wire-speed switchingLarge Unicast FDB for Layer 2 unicast forwardingForwarding Databases work based on IVLJumbo frame supportIGMP/MLD Snooping supportDHCP Snooping support with custom Option 82 (Circuit ID, Remote ID)DHCPv6 Snooping support with custom Option 18 (Interface ID) and Option 37 (Remote ID)RA Guard support | | **Routing** | Layer 3 Hardware Offloading:IPv4, IPv6 Unicast RoutingSupported on Ethernet, Bridge, Bonding, and VLAN interfacesECMPBlackholesOffloaded Fasttrack connections 1Offloaded NAT for Fasttrack connections 1Multiple MTU profiles**Important:** 1. Applies only to [certain switch models](./l3-hardware-offloading.md#l3hw-device-support) | | **Spanning Tree Protocol** | STPRSTPMSTPEdge port, BPDU Guard, Root Guard | | **Mirroring** | Various types of mirroring:Port based mirroringVLAN based mirroringMAC based mirroringRemote Switch Port Analyzer (RSPAN) | | **VLAN** | Fully compatible with IEEE802.1Q and IEEE802.1ad VLAN4k active VLANsFlexible VLAN assignment:Port based VLANProtocol based VLANMAC based VLANVLAN filteringIngress VLAN translationMultiple VLAN Registration protocol (MVRP) | | **Bonding** | Supports 802.3ad (LACP), balance-xor and active-backup modesUp to 8 member ports per bonding interfaceHardware automatic failover and load balancingMLAG | | **Quality of Service (QoS)** | Eight output queues per portDSCP and 802.1p PCP mappingPort based Layer2 and Layer3 trust settingsPort and Queue based egress rate limiterPolicy based QoS via ACL rulesStrict Priority (SP) and Shaped Deficit Weighted Round Robin (SDWRR) queuingEnhanced Transmission Selection (ETS) schedulingWeighted Random Early Detection (WRED) 1Explicit Congestion Notification (ECN) 1Priority-based Flow Control (PFC) 1Resource allocation control (queue, shared-pool and multicast based) with extensive monitoring capabilitiesCompatible with Dante environmentsCompatible with RDMA over Converged Ethernet (RoCE) environment 1Ingress traffic limiting (port based or via ACL rules)Traffic storm control**Important:** 1. Applies only to [certain switch models](./quality-of-service.md#qos-device-support) | | **Port isolation** | Applicable for Private VLAN implementation | | **Access Control List** | Ingress ACL tablesClassification based on ports, L2, L3, L4 protocol header fieldsACL actions include filtering, forwarding and modifying of the protocol header fields | | **PTP** | Two-step Ordinary Clock and Boundary Clock.Hardware timestamping, ensuring clock synchronization in the nanosecond(ns) range.IPv4 and Layer 2 (L2) multicast transport modes.End-to-End (E2E) and Peer-to-Peer (P2P) delay mechanisms.IEEE 1588-2008 (PTPv2).Profile Support for:802.1AS: Timing and synchronization for Audio Video Bridging (AVB) and Time-Sensitive Networking (TSN).AES67: High-performance audio-over-IP interoperability.G.8275.1: Frequency and phase synchronization in PTP-aware networks.SMPTE: Audio/video synchronization in professional broadcast environments.**Important:** PTP support is hardware-dependent, please refer to the list of [supported devices.](../system-information-and-utilities/precision-time-protocol.md#supported-devices) | :::info For L3 hardware offloading feature support and hardware limits, please refer to [Feature Support](./l3-hardware-offloading.md#l3hw-device-support) user manuals. ::: :::note For QoS hardware offloading feature support and hardware limits, please refer to the [Quality of Service (QoS)](./quality-of-service.md) user manuals. ::: ### Models This table clarifies the main differences between Cloud Router Switch models and CCR routers. | | | | | | | | | | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | **Model** | **Switch Chip** | **CPU** | **Size of RAM** | **Ethernet** | **[PoE out](../hardware/poe-out.mdx)** | **ACL rules** | **Unicast FDB entries** | **Jumbo Frame (Bytes)** | | **CRS318-1Fi-15Fr-2S-OUT (netPower 15FR)** | Marvell-98DX224S | ARM 2-core 800MHz | 256 MB | 16x 10/100M Ethernet 2x 1G SFP | 1x passive | 128 | up to 16K | 10218 | | **CRS318-16P-2S+OUT (netPower 16P)** | Marvell-98DX226S | ARM 2-core 800MHz | 256 MB | 16x 10/100/1000M Ethernet 2x 10G SFP+ | 16x 802.3af/at | 128 | up to 16K | 10218 | | **CRS310-1G-5S-4S+ (netFiber 9/IN)** | Marvell-98DX226S | ARM 2-core 800MHz | 256 MB | 1x 10/100/1000M Ethernet 5x 1G SFP 4x 10G SFP+ | | 128 | up to 16K | 10218 | | **CRS310-8G+2S+IN** | Marvell-98DX226S | ARM 2-core 800MHz | 256 MB | 8x 2.5G Ethernet 2x 10G SFP+ | | 128 | up to 16K | 10218 | | **CRS320-8P-8B-4S+RM** | Marvell-98DX226S | ARM 2-core 800MHz | 256 MB | 16x 10/100/1000M Ethernet 4x 10G SFP+ | 8x 802.3af/at 8x 802.3bt | 128 | up to 16K | 10218 | | **CRS304-4XG-IN** | Marvell-98DX2528 | ARM64 2-core 1200MHz | 512 MB | 4x 1/2.5/5/10G Ethernet | | 128 | up to 16K | 10218 | | **CRS326-24G-2S+ (RM/IN)** | Marvell-98DX3236 | ARM 2-core 800MHz | 512 MB | 24x 10/100/1000M Ethernet 2x 10G SFP+ | | 128 | up to 16K | 10218 | | **CRS328-24P-4S+RM** | Marvell-98DX3236 | ARM 1-core 800MHz | 512 MB | 24x 10/100/1000M Ethernet 4x 10G SFP+ | 24x 802.3af/at | 128 | up to 16K | 10218 | | **CRS328-4C-20S-4S+RM** | Marvell-98DX3236 | ARM 2-core 800MHz | 512 MB | 20x 1G SFP 4x 1G combo 4x 10G SFP+ | | 128 | up to 16K | 10218 | | **CRS305-1G-4S+IN** | Marvell-98DX3236 | ARM 2-core 800MHz | 512 MB | 1x 10/100/1000M Ethernet 4x 10G SFP+ | | 128 | up to 16K | 10218 | | **CRS305-1G-4S+OUT (FiberBox Plus)** | Marvell-98DX226S | ARM 2-core 800MHz | 256 MB | 1x 10/100/1000M Ethernet 4x 10G SFP+ | | 128 | up to 16K | 10218 | | **CRS309-1G-8S+IN** | Marvell-98DX8208 | ARM 2-core 800MHz | 512 MB | 1x 10/100/1000M Ethernet 8x 10G SFP+ | | 1024 | up to 32K | 10218 | | **CRS317-1G-16S+RM** | Marvell-98DX8216 | ARM 2-core 800MHz | 1 GB | 1x 10/100/1000M Ethernet 16x 10G SFP+ | | 1024 | up to 128K | 10218 | | **CRS312-4C+8XG-RM** | Marvell-98DX8212 | MIPSBE 1-core 650MHz | 64 MB | 4x 10G combo 8x 1/2.5/5/10G Ethernet | | 512 | up to 32K | 10218 | | **CRS326-24S+2Q+RM** | Marvell-98DX8332 | MIPSBE 1-core 650MHz | 128 MB | 24x 10G SFP+ 2x 40G QSFP+ | | 256 | up to 32K | 10218 | | **CRS326-4C+20G+2Q+RM** | Marvell-98DX8332 | MIPSBE 1-core 650MHz | 128 MB | 4x 2.5G Ethernet/10G SFP+ combo 20x 2.5G Ethernet 2x 40G QSFP+ | | 256 | up to 32K | 10218 | | **CRS354-48G-4S+2Q+RM** | Marvell-98DX3257 | MIPSBE 1-core 650MHz | 128 MB | 48x 10/100/1000M Ethernet 4x 10G SFP+ 2x 40G QSFP+ | | 170 | up to 32K | 10218 | | **CRS354-48P-4S+2Q+RM** | Marvell-98DX3257 | MIPSBE 1-core 650MHz | 128 MB | 48x 10/100/1000M Ethernet 4x 10G SFP+ 2x 40G QSFP+ | 48x 802.3af/at | 170 | up to 32K | 10218 | | **CRS418-8P-8G-2S+RM** **CRS418-8P-8G-2S+5axQ2axQ-RM** | Marvell-98DX226S | ARM64 4-core 2208MHz | 1 GB | 16x 10/100/1000M Ethernet 2x 10G SFP+ | 8x 802.3af/at | 128 | up to 16K | 10218 | | **CRS504-4XQ (IN/OUT)** | Marvell-98DX4310 | MIPSBE 1-core 650MHz | 64 MB | 4x 100G QSFP28 | | 1024 | up to 128K | 10218 | | **CRS510-8XS-2XQ-IN** | Marvell-98DX4310 | MIPSBE 1-core 650MHz | 128 MB | 8x 25G SFP28 2x 100G QSFP28 | | 1024 | up to 128K | 10218 | | **CRS518-16XS-2XQ-RM** | Marvell-98DX8525 | MIPSBE 1-core 650MHz | 64 MB | 16x 25G SFP28 2x 100G QSFP28 | | 1024 | up to 128K | 10218 | | **CRS520-4XS-16XQ-RM** | Marvell-98CX8410 | ARM64 4-core 2000MHz | 4 GB | 4x 25G SFP28 16x 100G QSFP28 | | 682 | up to 256K | 9570 | | **CRS812-8DS-2DQ-2DDQ-RM** | Marvell-98DX7335 | ARM64 4-core 2000MHz | 4 GB | 8x 50G SFP56 2x 200G QSFP56 2x 400G QSFP56-DD | | 1365 | up to 128K | 9570 | | **CRS804-4DDQ-hRM** | Marvell-98DX7335 | ARM64 4-core 2000MHz | 4 GB | 4x 400G QSFP56-DD | | 1365 | up to 128K | 9570 | | **CCR2116-12G-4S+** | Marvell-98DX3255 | ARM64 16-core 2000MHz | 16 GB | 12x 10/100/1000M Ethernet 4x 10G SFP+ | | 512 | up to 32K | 9570 | | **CCR2216-1G-12XS-2XQ** | Marvell-98DX8525 | ARM64 16-core 2000MHz | 16 GB | 12x 25G SFP28 2x 100G QSFP28 | | 1024 | up to 128K | 9570 | | **RDS2216-2XG-4S+4XS-2XQ** | Marvell-98DX4310 | ARM64 16-core 2000MHz | 32 GB | 2x 1/2.5/5/10G Ethernet 4x 10G SFP+ 4x 25G SFP28 2x 100G QSFP28 | | 1024 | up to 128K | 9570 | ### Abbreviations - FDB - Forwarding Database. - MDB - Multicast Database. - SVL - Shared VLAN Learning. - IVL - Independent VLAN Learning. - PVID - Port VLAN ID. - ACL - Access Control List. - CVID - Customer VLAN ID. - SVID - Service VLAN ID. ## Port switching --- In order to set up port switching, check the [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) page. :::danger Currently, it is possible to create only one bridge with hardware offloading. Use the `hw=yes/no` parameter to select which bridge will use hardware offloading. ::: :::warning Bridge STP/RSTP/MSTP, IGMP Snooping, and VLAN filtering settings don't affect hardware offloading. Since RouterOS v6.42, Bonding interfaces are also hardware offloaded. ::: ## VLAN --- Since RouterOS version 6.41, a bridge provides VLAN aware Layer2 forwarding and VLAN tag modifications within the bridge. This set of features makes bridge operation more like a traditional Ethernet switch and allows overcoming Spanning Tree compatibility issues compared to the configuration when tunnel-like VLAN interfaces are bridged. Bridge VLAN Filtering configuration is highly recommended to comply with STP (802.1D), RSTP (802.1w) standards, and it is mandatory to enable MSTP (802.1s) support in RouterOS. ### VLAN Filtering Detailed architectural concepts and configuration steps are covered in the main [Bridge VLAN Filtering](index.md#bridge-vlan-filtering) section. #### Supported VLAN Implementations Depending on your network design, you can implement several hardware-offloaded VLAN topologies: - **Port-Based VLAN:** See the step-by-step configuration guide in the [Bridge VLAN Filtering](index.md#bridge-vlan-filtering) section. - **Protocol-Based VLAN:** Configured via the switch rule table to map specific network protocols. - **MAC-Based VLAN:** Maps specific source MAC addresses to a designated VLAN ID. --- ### MAC-Based VLAN Configuration :::warning Hardware & Forwarding Restrictions - **Rule Capacity:** This functionality utilizes the hardware Switch Rule table. Refer to the [Switch Chip Model Capacity Table](./marvell-prestera-switch-chip-features.md#models) to verify how many rules your specific device supports. - **CPU Forwarding Limitation:** MAC-based VLANs apply strictly to traffic switched between hardware ports. If a packet is routed or forwarded to the CPU, the bridge port's default `pvid` is enforced instead of the `new-vlan-id` action defined in your ACL rules. - **DHCP Conflict:** MAC-based VLAN matching will fail to process DHCP packets if `dhcp-snooping=yes` is enabled on the bridge. ::: #### Configuration Example Enable switching on ports by creating a bridge with enabled hw-offloading: ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether7 hw=yes ``` Add VLANs in the Bridge VLAN table and specify ports: ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether2 untagged=ether7 vlan-ids=200,300,400 ``` Add Switch rules which assign VLAN id based on MAC address: ```ros /interface/ethernet/switch/rule add switch=switch1 ports=ether7 src-mac-address=A4:12:6D:77:94:43/FF:FF:FF:FF:FF:FF new-vlan-id=200 add switch=switch1 ports=ether7 src-mac-address=84:37:62:DF:04:20/FF:FF:FF:FF:FF:FF new-vlan-id=300 add switch=switch1 ports=ether7 src-mac-address=E7:16:34:A1:CD:18/FF:FF:FF:FF:FF:FF new-vlan-id=400 ``` #### Protocol Based VLAN :::warning - The Switch Rule table is used for Protocol Based VLAN functionality, see [this table](./marvell-prestera-switch-chip-features.md#models) on how many rules each device supports. - Protocol-based VLANs will only work properly between switch ports and not between switch ports and CPU. When a packet is being forwarded to the CPU, the `pvid` property for the bridge port will always be used instead of `new-vlan-id` from ACL rules. - Protocol-based VLANs will not work for DHCP packets when DHCP snooping is enabled. ::: Enable switching on ports by creating a bridge with enabled hw-offloading: ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes ``` Add VLANs in the Bridge VLAN table and specify ports: ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether2 untagged=ether6 vlan-ids=200 add bridge=bridge1 tagged=ether2 untagged=ether7 vlan-ids=300 add bridge=bridge1 tagged=ether2 untagged=ether8 vlan-ids=400 ``` Add Switch rules which assign VLAN ID based on MAC protocol: ```ros /interface/ethernet/switch/rule add mac-protocol=ip new-vlan-id=200 ports=ether6 switch=switch1 add mac-protocol=ipx new-vlan-id=300 ports=ether7 switch=switch1 add mac-protocol=0x80F3 new-vlan-id=400 ports=ether8 switch=switch1 ``` #### VLAN Tunneling (Q-in-Q) Since RouterOS v6.43, it is possible to use a provider bridge (IEEE 802.1ad) and Tag Stacking VLAN filtering, and hardware offloading at the same time. The configuration is described in the [Bridge VLAN Tunneling (Q-in-Q)](vlan.md#q-in-q) section. :::danger Devices with the switch chip Marvell-98DX3257 (e.g. CRS354 series) do not support VLAN filtering on 1Gbps Ethernet interfaces for other VLAN types (`0x88a8` and `0x9100`). ::: ### Ingress VLAN translation It is possible to translate a certain VLAN ID to a different VLAN ID using ACL rules on an ingress port. In this example we create two ACL rules, allowing bidirectional communication. This can be done by doing the following. Create a new bridge and add ports to it with hardware offloading: ```ros /interface/bridge add name=bridge1 vlan-filtering=no /interface/bridge/port add interface=ether1 bridge=bridge1 hw=yes add interface=ether2 bridge=bridge1 hw=yes ``` Add ACL rules to translate a VLAN ID in each direction: ```ros /interface/ethernet/switch/rule add new-dst-ports=ether2 new-vlan-id=20 ports=ether1 switch=switch1 vlan-id=10 add new-dst-ports=ether1 new-vlan-id=10 ports=ether2 switch=switch1 vlan-id=20 ``` Add both VLAN IDs to the bridge VLAN table: ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether1 vlan-ids=10 add bridge=bridge1 tagged=ether2 vlan-ids=20 ``` Enable bridge VLAN filtering: ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` :::warning Bidirectional communication is limited only between two switch ports. Translating VLAN ID between more ports can cause traffic flooding or incorrect forwarding between the same VLAN ports. **Caution:** By enabling `vlan-filtering` you will be filtering out traffic destined to the CPU. Before enabling VLAN filtering you should make sure that you set up a [Management port](index.md#management-access-configuration). ::: ## (R/M)STP --- MikroTik devices with a Marvell Prestera switch are capable of running STP, RSTP, and MSTP on a hardware level. For more detailed information, you should check out the [Spanning Tree Protocol](./user-guides/spanning-tree-protocol.md) manual page and for relevant configuration/monitoring options see the [Bridging and Switching](./) page. ## Bonding --- MikroTik devices with Marvell Prestera switch support hardware offloading with bonding interfaces. Only `802.3ad` (LACP), `balance-xor` (static LAG) and `active-backup` bonding modes are hardware offloaded; other bonding modes will use the CPU's resources. You can find more information about the bonding interfaces in the [Bonding Interface](../high-availability-solutions/bonding.md) section. To create a hardware offloaded bonding interface, you must create a bonding interface with a supported bonding mode: ```ros /interface/bonding add mode=802.3ad name=bond1 slaves=ether1,ether2 ``` This interface can be added to a bridge alongside other interfaces: ```ros /interface/bridge add name=bridge /interface/bridge/port add bridge=bridge interface=bond1 hw=yes add bridge=bridge interface=ether3 hw=yes add bridge=bridge interface=ether4 hw=yes ``` :::warning Do not add interfaces to a bridge that are already in a bond, RouterOS will not allow you to add an interface to a bridge that is already a slave port for bonding. ::: Make sure that the bonding interface is hardware offloaded by checking the "H" flag: ```text /interface/bridge/port/print Flags: X - disabled, I - inactive, D - dynamic, H - hw-offload # INTERFACE BRIDGE HW 0 H bond1 bridge yes 1 H ether3 bridge yes 2 H ether4 bridge yes ``` :::warning With HW-offloaded bonding interfaces, the built-in switch chip will always use Layer2+Layer3+Layer4 for a transmit hash policy; changing the transmit hash policy manually will have no effect. ::: ### Configuration example - VLANs with bonds This section will show how to configure multiple switches to use bonding interfaces and port-based VLANs, and it will also show a working example with a DHCP-Server, inter-VLAN routing, management IP, and invalid VLAN filtering configuration. For this network topology, we will be using two CRS326-24G-2S+, one CRS317-1G-16S+, and one CCR1072-1G-8S+. ![CRS3xx VLANs with Bonds](./img/marvell-prestera-switch-chip-features-01.webp) In this setup, SwitchA and SwitchC will tag all traffic from ports ether1-ether8 to VLAN ID 10, ether9-ether16 to VLAN ID 20, and ether17-ether24 to VLAN ID 30. Management will only be possible if a user is connecting with tagged traffic with VLAN ID 99 from ether1 on SwitchA or SwitchB. Connecting to all devices will also be possible from the router using tagged traffic with VLAN ID 99. The SFP+ ports in this setup are going to be used as VLAN trunk ports while being in a bond to create a LAG interface. #### Configure bonding Bonding interfaces are used when a larger amount of bandwidth is required. This is done by creating a link aggregation group, which also provides hardware automatic failover and load balancing for switches. By adding two 10Gbps interfaces to bonding, you can increase the theoretical bandwidth limit to 20Gbps. Make sure that all bonded interfaces are linked to the same speed rates. :::info When using the hardware-offloaded bridge, the switch aggregates traffic using the built-in switch chip without using CPU resources. ::: To create a 20Gbps bonding interface from sfp-sfpplus1 and sfp-sfpplus2 between SwitchA and SwitchB and between SwitchC and SwitchB, use these commands on **SwitchA** and **SwitchC**: ```ros /interface/bonding add mode=802.3ad name=bond_1-2 slaves=sfp-sfpplus1,sfp-sfpplus2 ``` To create a 40Gbps bonding interface between SwitchB and the Router and a 20Gbps bonding interface between SwitchA and SwitchC, use these commands on **SwitchB**: ```ros /interface/bonding add mode=802.3ad name=bond_1-2 slaves=sfp-sfpplus1,sfp-sfpplus2 add mode=802.3ad name=bond_3-4 slaves=sfp-sfpplus3,sfp-sfpplus4 add mode=802.3ad name=bond_5-6-7-8 slaves=sfp-sfpplus5,sfp-sfpplus6,sfp-sfpplus7,sfp-sfpplus8 ``` In our case the Router needs a software-based bonding interface. Use these commands on the **Router**: ```ros /interface/bonding add mode=802.3ad name=bond_1-2-3-4 slaves=sfp-sfpplus1,sfp-sfpplus2,sfp-sfpplus3,sfp-sfpplus4 ``` :::info Interface bonding does not create an interface with a larger link speed. Interface bonding creates a virtual interface that can load balance traffic over multiple interfaces. More details can be found on the [LAG interfaces and load balancing](./user-guides/layer2-misconfiguration.md#lag-interfaces-and-load-balancing) page. ::: #### Configure port switching All switches in this setup require that all used ports are switched together. For bonding, you should add the bonding interface as a bridge port, instead of individual bonding ports. Use these commands on **SwitchA** and **SwitchC**: ```ros /interface/bridge add name=bridge vlan-filtering=no /interface/bridge/port add bridge=bridge interface=ether1 pvid=10 add bridge=bridge interface=ether2 pvid=10 add bridge=bridge interface=ether3 pvid=10 add bridge=bridge interface=ether4 pvid=10 add bridge=bridge interface=ether5 pvid=10 add bridge=bridge interface=ether6 pvid=10 add bridge=bridge interface=ether7 pvid=10 add bridge=bridge interface=ether8 pvid=10 add bridge=bridge interface=ether9 pvid=20 add bridge=bridge interface=ether10 pvid=20 add bridge=bridge interface=ether11 pvid=20 add bridge=bridge interface=ether12 pvid=20 add bridge=bridge interface=ether13 pvid=20 add bridge=bridge interface=ether14 pvid=20 add bridge=bridge interface=ether15 pvid=20 add bridge=bridge interface=ether16 pvid=20 add bridge=bridge interface=ether17 pvid=30 add bridge=bridge interface=ether18 pvid=30 add bridge=bridge interface=ether19 pvid=30 add bridge=bridge interface=ether20 pvid=30 add bridge=bridge interface=ether21 pvid=30 add bridge=bridge interface=ether22 pvid=30 add bridge=bridge interface=ether23 pvid=30 add bridge=bridge interface=ether24 pvid=30 add bridge=bridge interface=bond_1-2 ``` Add all bonding interfaces to a single bridge on SwitchB by using these commands on **SwitchB**: ```ros /interface/bridge add name=bridge vlan-filtering=no /interface/bridge/port add bridge=bridge interface=bond_1-2 add bridge=bridge interface=bond_3-4 add bridge=bridge interface=bond_5-6-7-8 ``` #### Configure management IP It is very useful to create a management interface and assign an IP address to it to preserve access to the switch. This is also very useful when updating your switches since such traffic to the switch will be blocked when enabling invalid VLAN filtering. Create a routable VLAN interface on **SwitchA**, **SwitchB,** and **SwitchC**: ```ros /interface/vlan add interface=bridge name=MGMT vlan-id=99 ``` The Router needs a routable VLAN interface to be created on the bonding interface. Use these commands to create a VLAN interface on the **Router**: ```ros /interface/vlan add interface=bond_1-2-3-4 name=MGMT vlan-id=99 ``` For this guide, we are going to use these addresses for each device: | Device | Address | | :-- | :-- | | Router | 192.168.99.1 | | SwitchA | 192.168.99.2 | | SwitchB | 192.168.99.3 | | SwitchC | 192.168.99.4 | Add an IP address for each switch device on the VLAN interface (change X to the appropriate number): ```ros /ip/address add address=192.168.99.X/24 interface=MGMT ``` Do not forget to add the default gateway and specify a DNS server on the switch devices: ```ros /ip/route add gateway=192.168.99.1 /ip/dns set servers=192.168.99.1 ``` Add the IP address on the **Router**: ```ros /ip/address add address=192.168.99.1/24 interface=MGMT ``` #### Configure invalid VLAN filtering Since most ports on SwitchA and SwitchC are going to be access ports, you can set all ports to accept only certain types of packets, in this case, we will want SwitchA and SwitchC to only accept untagged packets. Use these commands on **SwitchA** and **SwitchC**: ```ros /interface/bridge/port set [ find ] frame-types=admit-only-untagged-and-priority-tagged ``` There is an exception for frame types on SwitchA and SwitchC. In this setup, access to the management is required from ether1 and bonding interfaces. They require that tagged traffic can be forwarded. Use these commands on **SwitchA** and **SwitchC**: ```ros /interface/bridge/port set [find where interface=ether1] frame-types=admit-all set [find where interface=bond_1-2] frame-types=admit-only-vlan-tagged ``` On SwitchB only tagged packets should be forwarded, use these commands on **SwitchB**: ```ros /interface/bridge/port set [ find ] frame-types=admit-only-vlan-tagged ``` An optional step is to set `frame-types=admit-only-vlan-tagged` on the bridge interface to disable the default untagged VLAN 1 (`pvid=1`). We are using the tagged VLAN on the bridge for management access, so there is no need to accept untagged traffic on the bridge. Use these commands on **SwitchA**, **SwitchB** and **SwitchC**: ```ros /interface/bridge/set [find name=bridge] frame-types=admit-only-vlan-tagged ``` It is required to set up a bridge VLAN table. In this network setup, we need to allow VLAN 10 on ether1-ether8, VLAN 20 on ether9-ether16, VLAN 30 on ether17-ether24, VLAN 10,20,30,99 on bond\_1-2, and a special case for ether1 to allow forwarding of VLAN 99 on SwitchA and SwitchC. Use these commands on **SwitchA** and **SwitchC**: ```ros /interface/bridge/vlan add bridge=bridge tagged=bond_1-2 vlan-ids=10 add bridge=bridge tagged=bond_1-2 vlan-ids=20 add bridge=bridge tagged=bond_1-2 vlan-ids=30 add bridge=bridge tagged=bridge,bond_1-2,ether1 vlan-ids=99 ``` :::warning Bridge ports with `frame-types` set to `admit-all` or `admit-only-untagged-and-priority-tagged` will be automatically added as untagged ports for the `pvid` VLAN. ::: Similarly, it is required to set up a bridge VLAN table for SwitchB. Use these commands on **SwitchB**: ```ros /interface/bridge/vlan add bridge=bridge tagged=bond_1-2,bond_3-4,bond_5-6-7-8 vlan-ids=10,20,30 add bridge=bridge tagged=bond_1-2,bond_3-4,bond_5-6-7-8,bridge vlan-ids=99 ``` When everything is configured, VLAN filtering can be enabled. Use these commands on **SwitchA**, **SwitchB,** and **SwitchC**: ```ros /interface/bridge set bridge vlan-filtering=yes ``` :::danger Double-check if port-based VLANs are set up properly. If a mistake is made, you might lose access to the switch, and connectivity can only be regained by resetting the configuration or by using the serial console. ::: :::note VLAN filtering is described in greater detail in the [Bridge VLAN Filtering](index.md#bridge-vlan-filtering) section. ::: #### Configure InterVLAN routing To create InterVLAN routing, the VLAN interface for each customer VLAN ID must be created on the router and must have an IP address assigned to it. The VLAN interface must be created on the bonding interface created previously. Use these commands on the **Router**: ```ros /interface/vlan add interface=bond_1-2-3-4 name=VLAN10 vlan-id=10 add interface=bond_1-2-3-4 name=VLAN20 vlan-id=20 add interface=bond_1-2-3-4 name=VLAN30 vlan-id=30 /ip/address add address=192.168.10.1/24 interface=VLAN10 add address=192.168.20.1/24 interface=VLAN20 add address=192.168.30.1/24 interface=VLAN30 ``` :::info These commands are required for a DHCP Server setup. If inter-VLAN routing is not desired but a DHCP Server on a single router is required, use [Firewall Filter](../firewall-and-quality-of-service/firewall/filter.md) rules to block communication between different subnets. ::: :::note Since RouterOS v7, it is possible to route traffic using L3 HW offloading on supported hardware. See more details in the [L3 Hardware Offloading](./l3-hardware-offloading.md) section. ::: #### Configure DHCP server To get the DHCP-Server working for each VLAN ID, the server must be set up on the previously created VLAN interfaces (one server for each VLAN ID). Preferably, each VLAN ID should have its own subnet and its own IP pool. A DNS Server could be specified as the router's IP address for a particular VLAN ID, or a global DNS Server could be used, but this address must be reachable. To set up the DHCP-Server, use these commands on the **Router**: ```ros /ip/pool add name=VLAN10_POOL ranges=192.168.10.100-192.168.10.200 add name=VLAN20_POOL ranges=192.168.20.100-192.168.20.200 add name=VLAN30_POOL ranges=192.168.30.100-192.168.30.200 /ip/dhcp-server add address-pool=VLAN10_POOL disabled=no interface=VLAN10 name=VLAN10_DHCP add address-pool=VLAN20_POOL disabled=no interface=VLAN20 name=VLAN20_DHCP add address-pool=VLAN30_POOL disabled=no interface=VLAN30 name=VLAN30_DHCP /ip/dhcp-server/network add address=192.168.10.0/24 dns-server=192.168.10.1 gateway=192.168.10.1 add address=192.168.20.0/24 dns-server=192.168.20.1 gateway=192.168.20.1 add address=192.168.30.0/24 dns-server=192.168.30.1 gateway=192.168.30.1 ``` In case the router's DNS Server is being used, don't forget to allow remote requests and make sure DNS Servers are configured on the router. Use these commands on the **Router**: ```ros /ip/dns set allow-remote-requests=yes servers=8.8.8.8 ``` :::danger Make sure to secure your local DNS Server with Firewall from the outside when using `allow-remote-requests` set to `yes` since your DNS Server can be used for DDoS attacks if it is accessible from the Internet by anyone. ::: Don't forget to create NAT, assuming that sfp-sfpplus8 is used as a WAN port, use these commands on the **Router**: ```ros /ip/firewall/nat add action=masquerade chain=srcnat out-interface=sfp-sfpplus8 ``` #### Configure jumbo frames One can increase the total throughput in such a setup by enabling jumbo frames. This reduces the packet overhead by increasing the Maximum Transmission Unit (MTU). If a device in your network does not support jumbo frames, then it will not benefit from a larger MTU. Usually, the whole network does not support jumbo frames, but you can still benefit when sending data between devices that support jumbo frames, including all switches in the path. In this case, if clients behind SwitchA and the client behind SwitchC support jumbo frames, then enabling jumbo frames will be beneficial. Before enabling jumbo frames, determine the MAX-L2MTU by using this command: ```ros [admin@SwitchA] > interface print Flags: R - RUNNING Columns: NAME, TYPE, ACTUAL-MTU, L2MTU, MAX-L2MTU, MAC-ADDRESS # NAME TYPE ACTUAL-MTU L2MTU MAX-L2MTU MAC-ADDRESS 1 R sfp-sfpplus1 ether 1500 1584 10218 64:D1:54:FF:E3:7F ``` :::info More information can be found in the [MTU manual](../hardware/mtu-in-routeros.md) page. ::: When MAX-L2MTU is determined, choose the MTU size depending on the traffic on your network, and use this command on **SwitchA**, **SwitchB,** and **SwitchC**: ```ros /interface/ethernet set [ find ] l2mtu=10218 mtu=10218 ``` :::info Don't forget to change the MTU on your client devices too, otherwise, the above-mentioned settings will not have any effect. ::: ## Multi-chassis Link Aggregation Group --- MLAG (Multi-chassis Link Aggregation Group) implementation in RouterOS allows configuring LACP bonds on two separate devices, while the client device believes it is connected to the same machine. This provides a physical redundancy in case of switch failure. MikroTik devices with a Marvell Prestera switch can be configured with hardware offloaded MLAG. Read [here](../high-availability-solutions/multi-chassis-link-aggregation-group.md) for more information. ## L3 Hardware Offloading --- Layer3 hardware offloading (otherwise known as IP switching or HW routing) will allow offloading some of the router features onto the switch chip. This allows reaching wire speeds when routing packets, which simply would not be possible with the CPU. Offloaded feature set depends on the used chipset. Read [here](./l3-hardware-offloading.md) for more info. ## Port isolation --- Since RouterOS v6.43 it is possible to create a Private VLAN setup, an example can be found in the [Switch chip port isolation](./switch-chip-features.md#port-isolation) manual page. Hardware offloaded bonding interfaces are not included in the switch port-isolation menu, but it is still possible to configure port-isolation individually on each secondary interface of the bonding. :::warning Port isolation can be used with vlan-filtering bridge and it is possible to isolate ports that are members of the same VLAN. The isolation works per-port; it is not possible to isolate ports per-VLAN. ::: ## IGMP/MLD Snooping --- MikroTik devices with Marvell Prestera switch are capable of using IGMP/MLD Snooping on a hardware level. To see more detailed information, you should check out the [IGMP/MLD snooping](./user-guides/bridge-igmp-mld-snooping.md) manual page. ## DHCP Snooping and DHCP Option 82 --- MikroTik devices with a Marvell Prestera switch are capable of using DHCP Snooping with custom Option 82 (Circuit ID, Remote ID) on a hardware level. The switch will create a dynamic ACL rule to capture the DHCP packets and redirect them to the main CPU for further processing. To see more detailed information, please visit the [DHCP Snooping and DHCP Option 82](index.md#dhcp-snooping-and-dhcp-option-82) manual page. :::info Starting from RouterOS v7.17, DHCP snooping is supported with hardware offloading bonding interfaces. ::: ## DHCPv6 Snooping and DHCP Option 18, Option 37 --- MikroTik devices with Marvell Prestera switch are capable of using DHCPv6 Snooping with custom Option 18 (Interface ID) and Option 37 (Remote ID) on a hardware level since RouterOS v7.23. The switch will create a dynamic ACL rule to capture the DHCPv6 packets and redirect them to the main CPU for further processing. To see more detailed information, please visit the [DHCPv6 Snooping / DHCPv6 Shield](./#dhcpv6-snooping--dhcpv6-shield) manual page. ## RA Guard --- MikroTik devices with a Marvell Prestera switch are capable of using RA Guard on a hardware level since RouterOS v7.22. The switch will create a dynamic ACL rule to capture the relevant IPv6 packets and redirect them to the main CPU for further processing. To see more detailed information, please visit the [RA Guard](./#ra-guard) manual page. ## Mirroring --- Mirroring is a function that allows a network switch to duplicate all the data passing through it and send a copy to another specified port, known as the `mirror-target`. This feature is useful for setting up a tap device, which allows for analyzing network traffic using a separate device. You can set up mirroring in a simple way by designating source ports (see `mirror-egress` and `mirror-ingress` in `/interface/ethernet/switch/port`), or you can configure more advanced mirroring based on different criteria (see `mirror` in `/interface/ethernet/switch/rule`). It is important to note that the `mirror-target` port must be on the same switch. You can check the device block diagram or navigate to the `/interface/ethernet` menu to identify which interfaces are connected where. When setting up the configuration, it is not mandatory to add the `mirror-target` interface to the same hardware offloaded bridge where the source ports are set up. The `mirror-target` port can be a standalone interface (not configured as a bridge port), or it can be within a bridge setup. When using the `mirror-target` with a bridge, note that data and mirrored traffic may both travel on the same LAN. In such cases, consider employing RSPAN (Remote Switch Port Analyzer), where mirrored traffic is encapsulated into a separate VLAN before being transmitted over the network. Additionally, you can set the `mirror-target` port to a special value "cpu", which means that the copied packets will be sent to the switch chip's CPU port. ### Configuration examples --- #### Port Based Mirroring Starting from RouterOS version 7.15, it is possible to configure multiple source ports and selectively choose whether to mirror incoming traffic, outgoing traffic, or both. In this example, both incoming and outgoing traffic from the **ether2** interface will be copied and sent to the **ether3** interface for monitoring or analysis. ```ros # Since RouterOS v7.15 /interface/ethernet/switch/port set ether2 mirror-egress=yes mirror-ingress=yes /interface/ethernet/switch set switch1 mirror-target=ether3 # Older RouterOS: /interface/ethernet/switch set switch1 mirror-source=ether2 mirror-target=ether3 ``` #### VLAN Based Mirroring Using ACL rules, it is possible to mirror packets from multiple interfaces using the `ports` setting. Additionally, you can specify more detailed criteria such as VLAN ID, MAC/IP address or TCP/UDP port. Only **ingress** packets are mirrored to the `mirror-target` interface. This example will mirror incoming VLAN 11 traffic from the **ether2** interface, and send copies to the **ether3** interface. To use an ACL rule with a `vlan-id` matcher, you need to have [bridge vlan-filtering](index.md#bridge-vlan-filtering) enabled. ```ros /interface/bridge set bridge1 vlan-filtering=yes /interface/ethernet/switch set switch1 mirror-target=ether3 /interface/ethernet/switch/rule add mirror=yes ports=ether1 switch=switch1 vlan-id=11 ``` #### MAC Based Mirroring This example will mirror incoming traffic with 64:D1:54:D9:27:E6 MAC destination or source address from the **ether1** interface, and send copies to the **ether3** interface. ```ros /interface/ethernet/switch set switch1 mirror-target=ether3 /interface/ethernet/switch/rule add mirror=yes ports=ether1 switch=switch1 dst-mac-address=64:D1:54:D9:27:E6/FF:FF:FF:FF:FF:FF add mirror=yes ports=ether1 switch=switch1 src-mac-address=64:D1:54:D9:27:E6/FF:FF:FF:FF:FF:FF ``` #### IP Based Mirroring This example will mirror incoming traffic with IP destination or source address 192.168.88.0/24 from the **ether1** interface, and send copies to the **ether3** interface. ```ros /interface/ethernet/switch set switch1 mirror-target=ether3 mirror-source=none /interface/ethernet/switch/rule add mirror=yes ports=ether1 switch=switch1 src-address=192.168.88.0/24 add mirror=yes ports=ether1 switch=switch1 dst-address=192.168.88.0/24 ``` There are other options as well, check the [ACL section](./marvell-prestera-switch-chip-features.md#switch-rules-acl) to find out all possible parameters that can be used to match packets. #### Remote Switch Port Analyzer This example will mirror incoming and outgoing traffic from the **ether2** interface, copies will be encapsulated in 802.1Q VLAN using the 999 as VLAN ID, and packets will be sent to the **ether3** interface. If the original traffic is already VLAN tagged, RSPAN will add another layer of VLAN tagging as an outer tag. This results in the mirrored traffic being tagged twice. If the `mirror-target` port is included in a vlan-filtering bridge, it is not required to make the interface a tagged VLAN member under the `/interface/bridge/vlan` menu for the RSPAN. ```ros /interface/ethernet/switch/port set ether2 mirror-egress=yes mirror-ingress=yes /interface/ethernet/switch set switch1 mirror-target=ether3 rspan=yes rspan-egress-vlan-id=999 rspan-ingress-vlan-id=999 ``` ### Property Reference **Sub-menu:** `/interface/ethernet/switch` | Property | Description | | :-- | :-- | | **mirror-target** (*cpu \| name \| none*; Default: **none**) | Selects a single mirroring target port. Packets from `mirror-egress` and `mirror-ingress` (`/interface/ethernet/switch/port`) and mirror (`/interface/ethernet/switch/rule`) will be sent to the selected port. | | **rspan** (*no \| yes*; Default: **no**) | Enables the Remote Switch Port Analyzer (RSPAN) feature on `mirror-target`. Traffic marked for ingress or egress mirroring is carried over a specified remote analyzer VLAN - `rspan-egress-vlan-id` and `rspan-ingress-vlan-id`. | | **rspan-egress-vlan-id** (*integer: 1..4095*; Default: **1**) | Selects the VLAN ID for marked egress traffic. Only applies when `rspan` is enabled. | | **rspan-ingress-vlan-id** (*integer: 1..4095*; Default: **1**) | Selects the VLAN ID for marked ingress traffic. Only applies when `rspan` is enabled. | **Sub-menu:** `/interface/ethernet/switch/port` | Property | Description | | :-- | :-- | | **mirror-egress** (*no \| yes*; Default: **no**) | Whether to send an egress packet copy to the `mirror-target` port. | | **mirror-ingress** (*no \| yes*; Default: **no**) | Whether to send an ingress packet copy to the `mirror-target` port. | **Sub-menu:** `/interface/ethernet/switch/rule` | Property | Description | | :-- | :-- | | **mirror** (*no \| yes*; Default: **no**) | Whether to send a packet copy to `mirror-target` port. | ## Traffic Shaping --- It is possible to limit ingress traffic that matches certain parameters with ACL rules and it is possible to limit ingress/egress traffic per port basis. The policer is used for ingress traffic, the shaper is used for egress traffic. The ingress policer controls the received traffic with packet drops. Everything that exceeds the defined limit will get dropped. This can affect the TCP congestion control mechanism on end hosts and achieved bandwidth can actually be less than defined. The egress shaper tries to queue packets that exceed the limit instead of dropping them. Eventually, it will also drop packets when the output queue gets full; however, it should allow utilizing the defined throughput better. ### Port-based traffic police and shaper ```ros /interface/ethernet/switch/port set ether1 ingress-rate=10M egress-rate=5M ``` ### MAC-based traffic policer ```ros /interface/ethernet/switch/rule add ports=ether1 switch=switch1 src-mac-address=64:D1:54:D9:27:E6/FF:FF:FF:FF:FF:FF rate=10M ``` ### VLAN-based traffic policer ```ros /interface/bridge set bridge1 vlan-filtering=yes /interface/ethernet/switch/rule add ports=ether1 switch=switch1 vlan-id=11 rate=10M ``` :::danger By enabling `vlan-filtering` you will be filtering out traffic destined to the CPU. Before enabling VLAN filtering you should make sure that you set up a [Management port](index.md#management-access-configuration). ::: ### Protocol-based traffic policer ```ros /interface/ethernet/switch/rule add ports=ether1 switch=switch1 mac-protocol=ipx rate=10M ``` There are other options as well, check the [ACL section](./marvell-prestera-switch-chip-features.md#switch-rules-acl) to find out all possible parameters that can be used to match packets. :::warning The Switch Rule table is used for QoS functionality. See [this table](./marvell-prestera-switch-chip-features.md#models) on how many rules each device supports. ::: :::danger Due to hardware limitations, the `egress-rate` and `storm-rate` settings do not work correctly on 10Gbps switch ports when they are linked at 10/100Mbps, 1/2.5/5Gbps. This applies to 98DX224S, 98DX226S, 98DX2528, 98DX3236 switch chips. ::: ## Traffic Storm Control --- Since RouterOS v6.42 it is possible to enable traffic storm control. A traffic storm can emerge when certain frames are continuously flooded on the network. Storm control settings are generally configured on non-uplink ports to restrict incoming storm traffic on those specific ports. This helps safeguard the entire switch and its connected ports by minimizing the impact of traffic storms across the network. For example, if a network loop has been created and no loop avoidance mechanisms are used (e.g. [Spanning Tree Protocol](./user-guides/spanning-tree-protocol.md)), broadcast or multicast frames can quickly overwhelm the network, causing degraded network performance or even complete network breakdown. Using MikroTik devices with a Marvell Prestera switch, it is possible to limit broadcast, unknown multicast and unknown unicast traffic. Unknown unicast traffic is considered when a switch does not contain a host entry for the destined MAC address. Unknown multicast traffic is considered when a switch does not contain a multicast group entry in the `/interface/bridge/mdb` menu. Storm control settings should be applied to ingress ports; the egress traffic will be limited. ![Traffic Storm](./img/marvell-prestera-switch-chip-features-02.webp) :::warning The storm control parameter is specified as a percentage (%) of the link speed. If your link speed is 1Gbps, then specifying `storm-rate` as `10` will allow only 100Mbps of broadcast, unknown multicast and/or unknown unicast traffic to be forwarded. ::: **Sub-menu:** `/interface/ethernet/switch/port` | Property | Description | | :-- | :-- | | **limit-broadcasts** (*yes \| no*; Default: **yes**) | Limit broadcast traffic on a switch port. | | **limit-unknown-multicasts** (*yes \| no*; Default: **no**) | Limit unknown multicast traffic on a switch port. | | **limit-unknown-unicasts** (*yes \| no*; Default: **no**) | Limit unknown unicast traffic on a switch port. | | **storm-rate** (*integer 0..100*; Default: **100**) | Amount of broadcast, unknown multicast and/or unknown unicast traffic is limited to a percentage of the link speed. | :::danger Devices with 98DX224S, 98DX226S, 98DX2528, 98DX3236 switch chip cannot distinguish unknown multicast traffic from all multicast traffic. For example, CRS326-24G-2S+ will limit all multicast traffic when `limit-unknown-multicasts` and `storm-rate` are used. For other devices, for example, CRS317-1G-16S+, the `limit-unknown-multicasts` parameter will limit only unknown multicast traffic (addresses that are not present in `/interface/bridge/mdb).` ::: For example, to limit 1% (10Mbps) of broadcast and unknown unicast traffic on ether1 (1Gbps), use the following commands: ```ros /interface/ethernet/switch/port set ether1 storm-rate=1 limit-broadcasts=yes limit-unknown-unicasts=yes ``` :::warning Due to hardware limitations, the `egress-rate` and `storm-rate` settings do not work correctly on 10Gbps switch ports when they are linked at 10/100Mbps, 1/2.5/5Gbps. This applies to 98DX224S, 98DX226S, 98DX2528, 98DX3236 switch chips. ::: ## MPLS hardware offloading --- Since RouterOS v6.41 it is possible to offload certain MPLS functions to the switch chip. The switch must be a (P)rovider router in a PE-P-PE setup in order to achieve hardware offloading. A setup example can be found in the [LDP example setup](../user-guides/routing-and-networking-protocols/mpls/ldp.md#example-setup). The hardware offloading will only take place when LDP interfaces are configured as physical switch interfaces (e.g. Ethernet, SFP, SFP+). :::warning Currently only `CRS317-1G-16S+` and `CRS309-1G-8S+` using RouterOS v6.41 and newer are capable of hardware offloading certain MPLS functions. `CRS317-1G-16S+` and `CRS309-1G-8S+` built-in switch chips are not capable of popping MPLS labels from packets, in a PE-P-PE setup you either have to use explicit null or disable TTL propagation in the MPLS network to achieve hardware offloading. **Caution:** The MPLS hardware offloading has been removed since RouterOS v7. ::: ## Switch Rules (ACL) --- An Access Control List contains ingress policy engines and egress policy engines. See [this table](./marvell-prestera-switch-chip-features.md#models) on how many rules each device supports. It is an advanced tool for wire-speed packet filtering, forwarding and modifying based on Layer2, Layer3 and Layer4 protocol header field conditions. ACL rules are checked for each received packet until a match has been found. If there are multiple rules that can match, then only the first rule will be triggered. A rule without any action parameters is a rule to accept the packet. Enabling features such as IGMP snooping, DHCP snooping, RoMON, PTP, or loop-protect can automatically create dynamic ACL rules. These rules should be considered when adding new ACL entries. Use the `place-before` property when creating a new rule, or the `move` command to adjust the ACL rule order. :::warning It is not required to set `mac-protocol` to a certain IP version when using L3 or L4 matchers, however, it is recommended to set the `mac-protocol=ip` or `mac-protocol=ipv6` when filtering any IP packets. ::: :::danger Then switch ACL rules are modified (e.g. added, removed, disabled, enabled, or moved), the existing switch rules will be inactive for a short time. This can cause some packet leakage during the ACL rule modifications. ::: **Sub-menu:** `/interface/ethernet/switch/rule` | Property | Description | | :-- | :-- | | **copy-to-cpu** (*no \| yes*; Default: **no**) | Clones the matching packet and sends it to the CPU. | | **disabled** (*yes \| no*; Default: **no**) | Enables or disables the ACL entry. | | **dscp** (*0..63*) | Matching the DSCP field of the packet (only applies to IPv4 packets). | | **dst-address** (*IP address/Mask*) | Matching destination IPv4 address and mask. If `mac-protocol=arp` is specified, matches the destination IP in ARP packets. Without `mac-protocol`, matches only IPv4 packets. | | **dst-address6** (*IPv6 address/Mask*) | Matching destination IPv6 address and mask. | | **dst-mac-address** (*MAC address/Mask*) | Matching destination MAC address and mask. | | **dst-port** (*0..65535*) | Matching destination protocol port number (applies to IPv4 and IPv6 packets if `mac-protocol` is not specified). | | **flow-label** (*0..1048575*) | Matching IPv6 flow label. | | **mac-protocol** (*802.2 \| arp \| capsman \| dot1x \| homeplug-av \| ip \| ipv6 \| ipx \| lacp \| lldp \| loop-protect \| macsec \| mpls-multicast \| mpls-unicast \| mvrp \| packing-compr \| packing-simple \| pppoe \| pppoe-discovery \| rarp \| romon \| service-vlan \| vlan \| or 0..65535 \| or 0x0000-0xffff*) | Matching a particular MAC protocol specified by protocol name or number | | **mirror** (*no \| yes*) | Clones the matching packet and sends it to the mirror-target port. | | **new-dst-ports** (*ports \| bond \| all*) | Changes the destination port to the specified value: If the setting is left empty (e.g. new-dst-ports=""), the packet will be dropped;If a port or hardware-offloaded bonding interface is specified, the packet will be redirected to that port. Only a single port or bond interface is supported;if you use the all argument, packet will be allowed to pass through to the egress processing without being dropped;If this parameter is not used, the packet will be accepted as is. | | **new-vlan-id** (*0..4095*) | Changes the VLAN ID to the specified value. Requires `vlan-filtering=yes`. | | **new-vlan-priority** (*0..7*) | Changes the VLAN priority (priority code point). Requires `vlan-filtering=yes`. | | **ports** (*ports \| bond*) | Matching switch interfaces where the rule will apply to incoming traffic. Multiple ports and [hardware-offloaded bonding](./marvell-prestera-switch-chip-features.md#bonding) interfaces can be selected. Note that the `switch1-cpu` port cannot be selected. If `ports` property is left empty, the rule will apply to all switch interfaces. | | **protocol** (*dccp \| ddp \| egp \| encap \| etherip \| ggp \| gre \| hmp \| icmp \| icmpv6 \| idpr-cmtp \| igmp \| ipencap \| ipip \| ipsec-ah \| ipsec-esp \| ipv6 \| ipv6-frag \| ipv6-nonxt \| ipv6-opts \| ipv6-route \| iso-tp4 \| l2tp \| ospf \| pim \| pup \| rdp \| rspf \| rsvp \| sctp \| st \| tcp \| udp \| udp-lite \| vmtp \| vrrp \| xns-idp \| xtp \| or 0..255*) | Matching a particular IP protocol specified by protocol name or number. Only applies to IPv4 packets if `mac-protocol` is not specified. To match certain IPv6 protocols, use the `mac-protocol=ipv6` setting. | | **rate** (*0..4294967295*) | Sets ingress traffic limitation (bits per second) for matched traffic. | | **redirect-to-cpu** (*no \| yes*) | Changes the destination port of a matching packet to the CPU. | | **src-address** (*IP address/Mask*) | Matching source IPv4 address and mask. If `mac-protocol=arp` is specified, matches the source IP in ARP packets. Without `mac-protocol`, matches only IPv4 packets. | | **src-address6** (*IPv6 address/Mask*) | Matching source IPv6 address and mask. | | **src-mac-address** (*MAC address/Mask*) | Matching source MAC address and mask. | | **src-port** (*0..65535*) | Matching source protocol port number (applies to IPv4 and IPv6 packets if `mac-protocol` is not specified). | | **switch** (*switch group*) | Matching switch group on which the rule will apply. | | **traffic-class** (*0..255*) | Matching IPv6 traffic class. | | **vlan-id** (*0..4095*) | Matching VLAN ID. Requires `vlan-filtering=yes`. | | **vlan-header** (*not-present \| present*) | Matching VLAN header, whether the VLAN header is present or not. Requires `vlan-filtering=yes`. | | **vlan-priority** (*0..7*) | Matching VLAN priority (priority code point). | ### Action parameters - copy-to-cpu - redirect-to-cpu - mirror - new-dst-ports (can be used to drop packets) - new-vlan-id - new-vlan-priority - rate ### Layer2 condition parameters - dst-mac-address - mac-protocol - src-mac-address - vlan-id - vlan-header - vlan-priority ### Layer3 condition parameters - dscp - protocol - IPv4 conditions: - dst-address - src-address - IPv6 conditions: - dst-address6 - flow-label - src-address6 - traffic-class ### Layer4 condition parameters - dst-port - src-port :::warning For VLAN-related matchers or VLAN-related action parameters to work, you need to enable `vlan-filtering` on the bridge interface and make sure that hardware offloading is enabled on those ports, otherwise, these parameters will not have any effect. ::: :::warning When bridge interface `ether-type` is set to `0x8100`, then VLAN-related ACL rules are relevant to frames tagged using regular/customer VLAN (TPID 0x8100); this includes `vlan-id` and `new-vlan-id`. When bridge interface `ether-type` is set to `0x88a8`, then ACL rules are relevant to frames tagged with 802.1ad service tag (TPID 0x88a8). ::: ## Port Security --- It is possible to limit allowed MAC addresses on a single switch port. For example, to allow the 64:D1:54:81:EF:8E MAC address on a switch port, start by switching multiple ports together. In this example, 64:D1:54:81:EF:8E is going to be located behind **ether1**. Create an ACL rule to allow the given MAC address and drop all other traffic on **ether1** (for ingress traffic): ```ros /interface/ethernet/switch/rule add ports=ether1 src-mac-address=64:D1:54:81:EF:8E/FF:FF:FF:FF:FF:FF switch=switch1 add new-dst-ports="" ports=ether1 switch=switch1 ``` Egress traffic can still contain information that should not reach devices with unknown MAC addresses. Assuming the ports are switched, disable MAC learning and disable unknown unicast flooding on **ether1**: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 hw=yes learn=no unknown-unicast-flood=no add bridge=bridge1 interface=ether2 hw=yes ``` With MAC learning disabled, you need to add a static host entry for 64:D1:54:81:EF:8E (for egress traffic): ```ros /interface/bridge/host add bridge=bridge1 interface=ether1 mac-address=64:D1:54:81:EF:8E ``` :::warning Broadcast and multicast traffic will still be sent out from **ether1**. You can use the `broadcast-flood` and `unknown-multicast-flood` parameters to prevent it. Note that some solutions might depend on these settings, such as streaming protocols and DHCP. ::: ## Dual Boot --- The “dual boot” feature allows you to choose which operating system you prefer to use on CRS3xx series switches, RouterOS or SwOS. The Device operating system could be changed using: - Command-line (`/system/routerboard/settings/set boot-os=swos`) - Winbox - Webfig - Serial Console More details about SwOS are described here: [SwOS manual](https://help.mikrotik.com/docs/display/SWOS/SwOS). :::warning To check if a model supports booting into SwOS, refer to the [SwOS Model table](https://help.mikrotik.com/docs/spaces/SWOS/pages/76415036/CRS3xx+and+CSS3xx+series+Manual#CRS3xxandCSS3xxseriesManual-Models) and the product page under Specifications "Operating System". ::: ## Configuring SwOS using RouterOS --- Since RouterOS 6.43 it is possible to load, save and reset SwOS configuration, as well as upgrade SwOS and set an IP address for the CRS3xx series switches by using RouterOS: - Save configuration with `/system/swos/save-config`. :::warning The configuration will be saved on the same device with `swos.config` as a filename. Make sure you download the file from your device since the configuration file will be removed after a reboot. ::: - Load configuration with `/system/swos/load-config`. - Change password with `/system/swos/password`. - Reset configuration with `/system/swos/reset-config`. - Upgrade SwOS from RouterOS using `/system/swos/upgrade`. :::warning The upgrade command will automatically install the latest available SwOS primary backup version, make sure that your device has access to the Internet in order for the upgrade process to work properly. When the device is booted into SwOS, the version number will include the letter "p", indicating a primary backup version. You can then install the latest available SwOS secondary main version from the SwOS "Upgrade" menu. ::: :::warning Starting from RouterOS version 7.17, device-mode restricts SwOS/RouterOS transition for dual-boot; in order to enable: `/system/device-mode/update` routerboard=yes ::: | Property | Description | | :-- | :-- | | **address-acquisition-mode** (*dhcp-only \| dhcp-with-fallback \| static*; Default: **dhcp-with-fallback**) | Changes address acquisition method: dhcp-only - uses only a DHCP client to acquire an address dhcp-with-fallback - for the first 10 seconds, it will try to acquire an address using a DHCP client. If the request is unsuccessful, then the address falls back to static as defined by the static-ip-address property static - the address is set as defined by the static-ip-address property | | **allow-from** (*IP/Mask*; Default: **0.0.0.0/0**) | IP address or a network from which the switch is accessible. By default, the switch is accessible by any IP address. | | **allow-from-ports** (*name*; Default: ) | List of switch ports from which the device is accessible. By default, all ports are allowed to access the switch | | **allow-from-vlan** (*integer: 0..4094*; Default: **0**) | VLAN ID from which the device is accessible. By default, all VLANs are allowed | | **identity** (*name*; Default: **Mikrotik**) | Name of the switch (used for the Mikrotik Neighbor Discovery protocol) | | **static-ip-address** (*IP*; Default: **192.168.88.1**) | IP address of the switch in case the address-acquisition-mode is either set to dhcp-with-fallback or static. By setting a static IP address, the address acquisition process does not change, which is DHCP with fallback by default. This means that the configured static IP address will become active only when there are going to be no DHCP servers in the same broadcast domain | ## See also [Basic VLAN switching](./user-guides/basic-vlan-switching.md) [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) [L3HW Route Hardware Offloading](./l3-hardware-offloading.md) [Quality of Service](./quality-of-service.md) [Spanning Tree Protocol](./user-guides/spanning-tree-protocol.md) [MTU on RouterBOARD](../hardware/mtu-in-routeros.md) [Layer2 misconfiguration](./user-guides/layer2-misconfiguration.md) [Bridge VLAN Table](./user-guides/bridge-vlan-table.md) [Bridge IGMP/MLD snooping](./user-guides/bridge-igmp-mld-snooping.md) [Multi-chassis Link Aggregation Group](../high-availability-solutions/multi-chassis-link-aggregation-group.md) --- ## Quality of Service import WideTable from '@site/src/components/WideTable'; # Quality of Service This document describes **Quality of Service (QoS)** implementation in RouterOS for devices equipped with **[Marvell Prestera switch chips](./marvell-prestera-switch-chip-features.md)**. QoS is a collection of features in network switches that allows network administrators to prioritize traffic and allocate network resources to ensure that critical data flows smoothly with low latency. The primary function of QoS in a network switch is to manage traffic in a way that meets the specific requirements of different types of network applications. For example, voice and video data require low latency and minimal packet loss to ensure high-quality communication, while file transfers and other data applications can tolerate higher levels of latency and packet loss. QoS works by identifying the type of traffic flowing through the switch and assigning it a priority level based on its requirements. The switch then uses this information to modify packet headers and prioritize traffic flow, ensuring that higher-priority traffic receives preferential treatment over lower-priority traffic. RouterOS v7.15 or later is required to support all QoS features: 1. **QoS Marking.** QoS profile matching by ingress packet header, then egress header modification according to the assigned QoS profile. 2. **QoS Enforcement.** Avoid or resolve congestion based on the assigned QoS profile and traffic shaping. 3. **QoS Policy.** Assign QoS profiles via ACL rules. 4. Active Queue Management: **WRED** (Weighted Random Early Detection), **ECN** notification and processing, **PFC** (Priority-based Flow Control). 5. Traffic shaping. ### QoS Changes in RouterOS v7.23 RouterOS v7.23 introduces significant changes to Quality of Service (QoS) offloading. These changes simplify the configuration process and add support for "lossless" traffic classes. Although hardware resources are finite, active queue management using ECN and/or PFC can prevent packet loss when all connected devices support these features and are properly configured. Previous RouterOS versions already supported ECN and PFC, but v7.23 streamlines how you set them up. :::info Not all devices support lossless traffic. Check the QoS Device Support table. ::: #### Configuration Change Summary - QoS Settings: most changes were set to "auto" by default, allowing RouterOS to pick the best known settings for the setup. - QoS Settings: added `lossless-traffic-class` and `lossless-buffers`, allowing explicit specification of lossless traffic and the reservation of queue resources for it. The user can leave those fields as "auto" as well. - QoS Monitor: displays the shared pool usage for lossy and lossless separately. - Tx Queue: removed shared pool index. RouterOS automatically selects the shared pool based on the traffic type (lossy or lossless). - QoS Profile: added automapping to the specified PCP and DSCP values (enabled by default). For example, adding a QoS profile with DSCP=46 automatically applies the profile to traffic received from trusted ports. ## QoS Terminology This section defines the key terms and abbreviations used throughout this documentation: - **QoS** - Quality of Service, a collection of features that allows network administrators to prioritize traffic and allocate network resources. - **ACL** - Access Control List, a set of switch rules used to filter network traffic based on specified criteria. - **AQM** - Active Queue Management, a congestion control mechanism that manages traffic flow by dropping or marking packets before queue overflow occurs. - **DSCP** - Differentiated Services Code Point, a 6-bit field in the IP header used to prioritize network traffic. - **ECN** - Explicit Congestion Notification, a mechanism that allows routers to signal congestion to endpoints devices without dropping packets. - **ETS** - Enhanced Transmission Selection, a traffic scheduling method that uses weighted round-robin to allocate bandwidth among multiple queues groups. - **PCP** - Priority Code Point, a 3-bit field in the VLAN header used to prioritize traffic within a VLAN. - **PFC** - Priority-based Flow Control (IEEE 802.1Qbb), a flow control mechanism that pauses traffic on specific priority queues to prevent packet loss. - **RoCE** - RDMA over Converged Ethernet, a protocol that enables remote direct memory access over Ethernet networks. - **WRED** - Weighted Random Early Detection, a congestion avoidance mechanism that randomly drops packets as a queue approaches capacity. - **/in/eth/sw/** - A CLI shortcut for `/interface/ethernet/switch/`. ## QoS Enhancements in new generation Marvell Prestera Switch Chips MikroTik devices with new generation Marvell Prestera switch chips (e.g. CRS8xx series running the [switch-marvell package](../getting-started/installation-and-upgrade/packages.md#extra-packages) offer a new approach in QoS enforcement. Previous models required making a tradeoff between guaranteed and shared Tx queue buffers. By increasing the shared buffer percentage, the device can absorb larger traffic bursts, but at the same time, one congested port can occupy all shared buffers, limiting the QoS capabilities of other ports. Using the new generation switch chips enables the best of both worlds by introducing **Dynamic Buffers**. A switch chip dynamically adjusts port and queue buffer limits based on the current congestion level. If there is no congestion within the device, a single port can absorb a large burst of traffic, preventing packet loss. When the Tx queue size increases across multiple ports, the device reduces per-port and per-queue limits, enforcing fair use of shared resources while ensuring enough buffers for non-congested queues to continue forwarding traffic. The entire process is automated, requiring zero configuration from the user. Another improvement in the new generation Marvell Prestera switch chips is eliminating the shortage of enqueued packet descriptors for storing control data. The previous generation devices had Packet Cap and Use stats. When a device received a burst of small packets, it could start tail-dropping packets due to hitting Packet Cap, even though it had enough queue buffers to store the payload. The new generation devices ensure there is always enough memory to store control data, leaving the Dynamic Buffer size as the only limiting factor. That's why there are no Packet Cap/Use stats in the new generation devices. New generation devices require QoS HW Offloading to be enabled at all times (**qos-hw-offloading=yes**). RouterOS ignores user requests to disable it while keeping the field for backward compatibility. ## QoS Device Support | Switch Chip | Models | QoS Profiles | QoS Maps | Tx Managers | WRED | ECN | PFC | Lossless Buffers | Dynamic Buffers | Port/Queue Usage Stats | | :-- | :-- | --: | --: | --: | :-- | :-- | :-- | :-- | :-- | :-- | | **98DX3236** | CRS305-1G-4S+IN CRS326-24G-2S+ (RM/IN) CRS328-24P-4S+RM CRS328-4C-20S-4S+RM | 128 | 1 | 8 | | | | | | Current values | | **98DX226S** | CRS305-1G-4S+OUT (FiberBox Plus) CRS310-1G-5S-4S+ (netFiber 9/IN) CRS310-8G+2S+IN CRS318-16P-2S+OUT (netPower 16P) CRS320-8P-8B-4S+RM CRS418-8P-8G-2S+RM CRS418-8P-8G-2S+5axQ2axQ-RM | 128 | 1 | 8 | | | | | | Current values | | **98DX224S** | CRS318-1Fi-15Fr-2S-OUT (netPower 15FR) | 128 | 1 | 8 | | | | | | Current values | | **98DX2528** | CRS304-4XG-IN | 128 | 1 | 8 | | | | | | Current values | | **98DX8525** | CCR2216-1G-12XS-2XQ CRS518-16XS-2XQ-RM | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | | Max fill 1 | | **98DX4310** | CRS504-4XQ (IN/OUT) CRS510-8XS-2XQ-IN RDS2216-2XG-4S+4XS-2XQ | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | | Max fill 1 | | **98DX8208** | CRS309-1G-8S+IN | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | | Current values 2 | | **98DX8212** | CRS312-4C+8XG-RM | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | | Current values 2 | | **98DX8216** | CRS317-1G-16S+RM | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | | Current values 2 | | **98DX8332** | CRS326-24S+2Q+RM CRS326-4C+20G+2Q+RM | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | | Current values 2 | | **98DX3257** | CRS354-48G-4S+2Q+RM CRS354-48P-4S+2Q+RM | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | | Current values 2 | | **98DX3255** | CCR2116-12G-4S+ | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | | Current values 2 | | **98CX8410** | CRS520-4XS-16XQ-RM | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | | Unavailable 3 | | **98DX7335** | CRS812-8DS-2DQ-2DDQ-RM CRS804-4DDQ-hRM | 1024 | 12 | 15 | ✔ | ✔ | ✔ | ✔ | ✔ | Current values + Max fill | **1** The device gathers max queue fill statistics instead of displaying the current usage values. Use the `reset-counters` command to clear those stats. **2** Due to hardware limitations, some switch chip models may experience temporary traffic flow disruption while reading or polling QoS port/queue usage data. **3** Usage data for individual queues on a port is unavailable; only the aggregate total usage for the entire physical port can be accessed. ## Applications and Usage Examples --- ### Basic Configuration Example This example demonstrates how to configure a single QoS level for VoIP (IP Telephony) on top of the standard Best Effort class. The configuration uses a CRS326-24G-2S+ device with the following setup: - All ports are bridged and use **[vlan-filtering](index.md#bridge-vlan-filtering)**; - sfp-sfpplus1 serves as a VLAN trunk connected to another switch; - ether1 through ether9 are dedicated ports for IP phones; - ether10 through ether24 are standard ports for host connection. First, define a QoS profile. This profile specifies the DSCP and PCP values that will be applied to forwarded packets on egress: ```ros /interface/ethernet/switch/qos/profile add dscp=46 name=voip pcp=5 traffic-class=5 ``` Next, assign the VoIP QoS profile to the dedicated ports for IP phones. This applies the profile to ingress traffic on these ports. All other Ethernet ports will use the default profile (where dscp=0 and pcp=0): ```ros /interface/ethernet/switch/qos/port set ether1 profile=voip set ether2 profile=voip set ether3 profile=voip set ether4 profile=voip set ether5 profile=voip set ether6 profile=voip set ether7 profile=voip set ether8 profile=voip set ether9 profile=voip ``` The trunk port receives both types of QoS traffic. To differentiate between them, enable trust-l3 and trust-l2: ```ros /interface/ethernet/switch/qos/port set sfp-sfpplus1 trust-l3=trust trust-l2=trust ``` > **Note:** If you are running RouterOS version 7.23 or later, the VLAN priority and IP DSCP mapping is created automatically, so this step is not required. If you are using an earlier RouterOS version, you must manually create the VLAN priority and IP DSCP mapping with the QoS profile: ```routeros /interface/ethernet/switch/qos/map/ip add dscp=46 profile=voip /interface/ethernet/switch/qos/map/vlan add pcp=5 profile=voip ``` Finally, enable QoS hardware offloading for the above settings to take effect: ```ros /interface/ethernet/switch set switch1 qos-hw-offloading=yes ``` You can verify the port QoS settings using the `print` command: ```ros [admin@MikroTik] /interface/ethernet/switch/qos/port/print Column: NAME, SWITCH, PROFILE, MAP, TRUST-L2, TRUST-L3 # NAME SWITCH PROFILE MAP TRUST-L2 TRUST-L3 TX-MANAGER 0 ether1 switch1 voip default ignore ignore default 1 ether2 switch1 voip default ignore ignore default 2 ether3 switch1 voip default ignore ignore default 3 ether4 switch1 voip default ignore ignore default 4 ether5 switch1 voip default ignore ignore default 5 ether6 switch1 voip default ignore ignore default 6 ether7 switch1 voip default ignore ignore default 7 ether8 switch1 voip default ignore ignore default 8 ether9 switch1 voip default ignore ignore default 9 ether10 switch1 default default ignore ignore default 10 ether11 switch1 default default ignore ignore default 11 ether12 switch1 default default ignore ignore default 12 ether13 switch1 default default ignore ignore default 13 ether14 switch1 default default ignore ignore default 14 ether15 switch1 default default ignore ignore default 15 ether16 switch1 default default ignore ignore default 16 ether17 switch1 default default ignore ignore default 17 ether18 switch1 default default ignore ignore default 18 ether19 switch1 default default ignore ignore default 19 ether20 switch1 default default ignore ignore default 20 ether21 switch1 default default ignore ignore default 21 ether22 switch1 default default ignore ignore default 22 ether23 switch1 default default ignore ignore default 23 ether24 switch1 default default ignore ignore default 24 sfp-sfpplus1 switch1 default default trust ignore default 25 sfp-sfpplus2 switch1 default default ignore ignore default 26 switch1-cpu switch1 ``` With this configuration, incoming packets on port ether1 through ether9 are marked with a Priority Code Point (PCP) value of 5 and a Differentiated Services Code Point (DSCP) value of 46. Incoming packets on port ether10 through ether24 are marked with PCP and DSCP value of 0. When packets are received on the sfp-sfpplus1 port, any packets with a PCP value of 5 retain their PCP value of 5 and DSCP value of 46, while all other packets are marked with PCP and DSCP value of 0. ## Dante Starting from RouterOS v7.15, all MikroTik QoS-capable devices are compatible with Dante audio networking. Dante hardware uses the following DSCP/Diffserv priority values for traffic prioritization: | Dante Priority | Usage | DSCP Label | DSCP Value | | :-- | :-- | :-- | --: | | High | Time-critical PTP events | CS7 | 56 | | Medium | Audio, PTP | EF | 46 | | None | Other traffic | BE | 0 | This example assumes the switch is using its default configuration, which includes a default bridge interface with all Ethernet interfaces added as bridge ports. Any of these interfaces can be used for Dante. First, create QoS profiles to match Dante traffic classes. There is already a pre-existing "default" profile that corresponds to Dante's None priority. ```ros /interface/ethernet/switch/qos/profile add name=dante-ptp dscp=56 pcp=7 traffic-class=7 add name=dante-audio dscp=46 pcp=5 traffic-class=5 ``` If you are running RouterOS version 7.23 or later, the IP DSCP mapping is created automatically, so this step is not required. If you are using an earlier RouterOS version, create a QoS mapping to match QoS profile based on DSCP values: ```ros /interface/ethernet/switch/qos/map/ip add dscp=56 profile=dante-ptp add dscp=46 profile=dante-audio ``` Configure the hardware queue to enforce QoS on Dante traffic: ```ros /interface/ethernet/switch/qos/tx-manager/queue set [find where traffic-class=7] schedule=strict-priority set [find where traffic-class=5] schedule=strict-priority ``` Dante's High and Medium priority traffic is scheduled in strict priority order. The device transmits time-critical PTP packets until queue7 is empty, then proceeds with audio (queue5). Other traffic is transmitted only when PTP and audio queues are empty. The next step is to enable trust mode for incoming Layer 3 packets (IP DSCP field): ```ros /interface/ethernet/switch/qos/port set [find] trust-l3=keep ``` Finally, enable QoS hardware offloading for the above settings to take effect: ```ros /interface/ethernet/switch set switch1 qos-hw-offloading=yes ``` When using Dante in multicast mode, it is beneficial to enable IGMP snooping on the switch. This feature directs traffic only to ports with subscribed devices, preventing unnecessary flooding. Additionally, enabling an IGMP querier (if not already enabled on another device in the same LAN), adjusting query interval, and activating fast-leave can further optimize multicast performance. ```ros /interface/bridge set [find name=bridge] igmp-snooping=yes multicast-querier=yes query-interval=60s /interface/bridge/port set [find] fast-leave=yes ``` ## RDMA over Converged Ethernet (RoCE) RoCE enables direct memory access to remote storage systems over Ethernet networks without involving the host CPU. This significantly reduces latency and CPU overhead, making RoCE ideal for high-performance computing and data center environments. RoCE also allows a converged network where various services (such as data storage, networking, and multimedia) run over a single Ethernet infrastructure, simplifying network management and reducing the cost and complexity of maintaining separate networks. RoCE achieves this through the use of **ECN** and **PFC** mechanisms. These features help prevent network congestion and packet loss, ensuring reliable, lossless communication. See the [device feature table](quality-of-service.md#qos-device-support) for compatible switches. While the switch can support a RoCE environment, the end hosts must also be compatible with the RoCE protocol and equipped with RDMA-capable network interface cards (NICs). There are two main versions of RoCE. RoCEv1 operates as an Ethernet link layer protocol and uses Ethertype 0x8915. RoCEv2 works over standard IP networks, using UDP destination port number 4791. ECN bits in the IP header are marked to signal network congestion, and a Congestion Notification Packet (CNP) is used to acknowledge congestion to the sender. For traffic prioritization, DSCP 26 is used for RoCEv2 traffic, while DSCP 48 is used for CNPs. The following example can be used for lossless RoCEv2 with PFC and ECN, and it assumes that the switch is using its default configuration, which includes a default bridge interface with all Ethernet interfaces added as bridge ports. The minimal recommended RouterOS version is 7.17. First, configure additional profiles. Non-RoCE traffic will be assigned to the already existing "default" profile with traffic-class 1, RoCEv2 to traffic-class 3, and CNP to traffic-class 6. ```routeros /interface/ethernet/switch/qos/profile add dscp=26 name=roce traffic-class=3 add dscp=48 name=cnp traffic-class=6 ``` If you are running RouterOS version 7.23 or later, the IP DSCP mapping is created automatically, so this step is not required. If you are using an earlier RouterOS version, create a QoS mapping to match QoS profiles based on DSCP values. ```routeros /interface/ethernet/switch/qos/map/ip add dscp=26 profile=roce add dscp=48 profile=cnp ``` Configure hardware queue and scheduler. Use ETS (`schedule=high-priority-group`) for traffic-class 1 and traffic-class 3 with 50% bandwidth assignment each (`weight=1`), and strict priority scheduling for traffic-class 6. Additionally, enable ECN (`ecn=yes`) for traffic-class 3 to mark IP packets in the switch that experience congestion. ```routeros /interface/ethernet/switch/qos/tx-manager/queue set 1 schedule=high-priority-group weight=1 set 3 schedule=high-priority-group weight=1 ecn=yes set 6 schedule=strict-priority ``` :::tip Although using `schedule=low-priority-group` allows you to create separate ETS scheduling and bandwidth allocation for a different set of traffic-classes, it is not recommended to use this setting together with `lldp-dcbx=yes`. The reason is that the ETS Configuration/Recommendation TLVs are designed to handle a single bandwidth allocation across traffic classes, thus `schedule=high-priority-group` should be used instead. ::: Configure a PFC profile for traffic-class 3 to ensure a lossless environment for RoCEv2 traffic. ```routeros /interface/ethernet/switch/qos/priority-flow-control add name=pfc-tc3 rx=yes traffic-class=3 tx=yes ``` Set Layer3 trust mode (`trust-l3=keep`) on switch ports where RoCEv2 traffic is expected. Set PFC (`pfc=pfc-tc3`) and egress rate for queue3 to comply with PFC requirements (`egress-rate-queue3=10.0Gbps`). In this example, 10Gbps SFP+ interfaces is used, and the egress rate can be set to match the physical speed of the interface. Change this property depending on your interface speeds. ```routeros /interface/ethernet/switch/qos/port set sfp-sfpplus1 egress-rate-queue3=10.0Gbps pfc=pfc-tc3 trust-l3=keep set sfp-sfpplus2 egress-rate-queue3=10.0Gbps pfc=pfc-tc3 trust-l3=keep set sfp-sfpplus3 egress-rate-queue3=10.0Gbps pfc=pfc-tc3 trust-l3=keep set sfp-sfpplus4 egress-rate-queue3=10.0Gbps pfc=pfc-tc3 trust-l3=keep ``` Enable QoS hardware offloading for the above settings to start working. ```routeros /interface/ethernet/switch set switch1 qos-hw-offloading=yes ``` Enable the LLDP Data Center Bridging Capability Exchange Protocol (DCBX) to share QoS settings and capabilities with other neighboring devices. ```routeros /ip/neighbor/discovery-settings set lldp-dcbx=yes ``` As an optional step, increase the L2MTU to accommodate larger data packets. ```routeros /interface/ethernet set [find switch=switch1] l2mtu=9500 ``` ## QoS Marking --- ### Understanding Map Ranges To avoid defining every possible PCP and DSCP mapping individually, RouterOS allows you to specify multiple values or ranges for PCP and DSCP when creating QoS profile mappings. In this example, PCP values 0 and 2 use the default QoS profile, values 1 and 3-4 use the streaming profile, value 5 uses the voip profile, and values 6-7 use the control profile: ```ros /interface/ethernet/switch/qos/map/vlan add pcp=1,3-4 profile=streaming add pcp=5 profile=voip add pcp=6-7 profile=control ``` This approach simplifies configuration by grouping related priority values together rather than creating separate mappings rules for each individual value. ### Understanding Port, Profile, and Map relation Each switch port has Layer2 and Layer3 trust settings that will change how ingress packets are classified into QoS profiles and what PCP and DSCP values will be used. Below are tables that describe all possible options: | **qos-trust-l2** | **qos-trust-l3** | Behavior | | :-- | :-- | :-- | | **ignore** | **ignore** | The port is considered untrusted. Both headers are ignored, and the port's **profile** is forced to all ingress packets. This is the default setting. | | **ignore** | **trust** | Trust the Layer 3 header. Use the DSCP field from the IP header of ingress packets for QoS profile lookup (see `/in/eth/sw/qos/map/ip`). If the lookup fails (no QoS profiles are mapped to the given DSCP value), the **default** QoS profile is used (not the switch port's QoS profile). The switch port's **profile** field is used only for non-IP traffic. | | **ignore** | **keep** | Trust the Layer 3 header. Use the DSCP field from the IP header of ingress packets for QoS profile lookup (see `/in/eth/sw/qos/map/ip`). If the lookup fails, the **default** QoS profile is used. The switch port's **profile** field is used only for non-IP traffic. If the forwarded/routed packet is VLAN-tagged, its PCP value is set from the selected QoS profile. However, the original DSCP value of the packet is kept intact. | | **trust** | **ignore** | Trust the Layer 2 header, but ignore L3. If an ingress packet is VLAN-tagged, use the PCP field from the VLAN header for QoS profile lookup (see `/in/eth/sw/qos/map/vlan`). If the lookup fails (no QoS profiles are mapped to the given PCP value), the **default** QoS profile is used. The switch port's **profile** field is used only for untagged traffic. | | **trust** | **trust** | Trust both headers, but Layer 3 has higher precedence. In the case of an IP packet, use the DSCP field for QoS profile lookup (see `/in/eth/sw/qos/map/ip`). If the DSCP-to-QoS lookup fails, use the **default** profile. If the packet is not an IP packet but is VLAN-tagged, use the PCP field from the VLAN header for QoS profile lookup (see `/in/eth/sw/qos/map/vlan`). If the VLAN-to-QoS lookup fails, use the **default** QoS profile. Non-IP untagged packets use the switch port's **profile**. | | **trust** | **keep** | The same as **trust+trust**, but the original DSCP value is preserved in forwarded/routed packets. | | **keep** | **ignore** | Trust the Layer 2 header but ignore L3. If an ingress packet is VLAN-tagged, use the PCP field from the VLAN header for QoS profile lookup (see `/in/eth/sw/qos/map/vlan`). If the lookup fails (no QoS profiles are mapped to the given PCP value), the **default** QoS profile is used. The switch port's **profile** field is used only for untagged traffic. If the packet is VLAN-tagged on both ingress and egress, the original PCP value is kept. | | **keep** | **trust** | Trust both headers, but Layer 3 has higher precedence. In the case of an IP packet, use the DSCP field for QoS profile lookup (see `/in/eth/sw/qos/map/ip`). If the DSCP-to-QoS lookup fails, use the **default** profile. If the packet is not an IP packet but is VLAN-tagged, use the PCP field from the VLAN header for QoS profile lookup (see `/in/eth/sw/qos/map/vlan`). If the VLAN-to-QoS lookup fails, use the **default** QoS profile. Non-IP untagged packets use the switch port's **profile**. If the packet is VLAN-tagged on both ingress and egress, the original PCP value is kept. The DSCP value in forwarded/routed packets is set from the selected QoS profile. | | **keep** | **keep** | Trust both headers, but Layer 3 has higher precedence. In the case of an IP packet, use the DSCP field for QoS profile lookup (see `/in/eth/sw/qos/map/ip`). If the DSCP-to-QoS lookup fails, use the **default** profile. If the packet is not an IP packet but is VLAN-tagged, use the PCP field from the VLAN header for QoS profile lookup (see `/in/eth/sw/qos/map/vlan`). If the VLAN-to-QoS lookup fails, use the **default** QoS profile. Non-IP untagged packets use the switch port's **profile**. Keep both the original PCP and/or DSCP values intact in cases of VLAN-tagged and/or IP packets, respectively. | | **Port settings** | | The selected QoS profile and the source for PCP / DSCP field values in forwarded/routed packets | | | | | | | | | | | | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | **qos-trust-l2** | **qos-trust-l3** | VLAN-Tagged IP | | | Untagged IP | | | VLAN-Tagged Non-IP | | | Untagged Non-IP | | | | | | QoS Profile | PCP | DSCP | QoS Profile | PCP 1 | DSCP | QoS Profile | PCP | DSCP | QoS Profile | PCP 1 | DSCP | | ignore | ignore | profile | profile | profile | profile | profile | profile | profile | profile | - | profile | profile | - | | ignore | trust | map/ip | map/ip | map/ip | map/ip | map/ip | map/ip | profile | profile | - | profile | profile | - | | ignore | keep | `/map/ip` | `/map/ip` | original | `/map/ip` | `/map/ip` | original | profile | profile | - | profile | profile | - | | trust | ignore | map/vlan | map/vlan | map/vlan | profile | profile | profile | map/vlan | map/vlan | - | profile | profile | - | | trust | trust | `/map/ip` | `/map/ip` | `/map/ip` | `/map/ip` | `/map/ip` | `/map/ip` | `/map/vlan` | `/map/vlan` | - | profile | profile | - | | trust | keep | `/map/ip` | `/map/ip` | original | `/map/ip` | `/map/ip` | original | `/map/vlan` | `/map/vlan` | - | profile | profile | - | | keep | ignore | map/vlan | original | map/vlan | profile | profile | profile | map/vlan | original | - | profile | profile | - | | keep | trust | map/ip | original | map/ip | map/ip | profile | map/ip | map/vlan | original | - | profile | profile | - | | keep | keep | map/ip | original | original | map/ip | profile | original | map/vlan | original | - | profile | profile | - | **1** Applies only when ingress traffic is untagged, but the egress interface requires the frames to be VLAN-tagged. ### QoS Marking via Switch Rules (ACL) Starting from **RouterOS v7.15**, you can assign QoS profiles to network traffic using Switch Rules (ACL). This method allows for flexible traffic classification based on various packet attributes. **Sub-menu:** `/interface/ethernet/switch/rule` | New/Changed Properties | Description | | :-- | :-- | | **new-qos-profile** (*name*) | The name of the [QoS profile](#qos-profile) to assign to the matched packets. | | **keep-qos-fields** (*yes \| no*; Default: **no**) | Should the original values of QoS fields (PCP, DSCP) be kept (*yes*), or replaced with the ones from the assigned QoS profile (*no*)? Relevant only if **new-qos-profile** is set. | | **new-vlan-priority** (*0..7*) | Deprecated and should be replaced with the respective **new-qos-profile**. Kept for backward compatibility. Relevant only if qos-hw-offloading=no. | The following example assigns a QoS profile based on the source MAC address: ```ros /interface/ethernet/switch/rule add new-qos-profile=stream port=ether1,ether2 src-mac-address=00:01:02:00:00:00/FF:FF:FF:00:00:00 switch=switch1 add new-qos-profile=voip port=ether1,ether2 src-mac-address=04:05:06:00:00:00/FF:FF:FF:00:00:00 switch=switch1 ``` ## QoS Enforcement ### Hardware Queues Each switch port has eight hardware transmission (Tx) queues (queue0 through queue7). Each queue corresponds to a traffic class (tc0 through tc7) defined by a [QoS profile](#qos-profile). When a packet enters the switch, it receives a QoS profile assignment, which determines the traffic class and consequently selects the appropriate egress queue for transmission. Hardware queues have variable sizes configured by the [Transmission Manager](#transmission-manager). Additionally, multiple ports and queues can share resources with each other through a mechanism called *Shared Buffers*. For example, a device with 25 ports has buffer memory sufficient to queue 1200 packets total. If resources are split equally, each port receives 48 exclusive buffers with a maximum of 6 packets per queue (48 divided by 8), which is typically insufficient to absorb even a short traffic burst. However, allocating 50% of buffers for sharing leaves each port with 24 exclusive buffers (3 per queue), while simultaneously allowing a single queue to grow up to 603 buffers (3 exclusive plus 600 shared). RouterOS enables enabling or disabling the shared pool for each queue individually. This capability helps prevent low-priority traffic from consuming all available hardware memory. Additionally, port buffer limits can restrict a single low-speed port from occupying the entire shared pool. For more details, see [QoS Settings](#qos-settings) and [Transmission Manager](#transmission-manager). :::info The default best-effort traffic class (PCP=0, DSCP=0) is traffic class 1, while the lowest priority traffic (PCP=1) uses traffic class 0. ::: ## Hardware Resources The switch chip has limited hardware resources (memory). Two main hardware resources are relevant to QoS operations: - **Packet descriptor** - Contains packet control information such as the target port, header modifications, and other metadata. - **Data buffer** - Memory chunk that stores the actual packet payload. Buffer size varies depending on the switch chip model; typically 256 bytes. One packet descriptor may use multiple buffers (depending on the payload size), and buffers may be shared by multiple descriptors in cases of multicast or broadcast traffic. If the hardware does not have enough free descriptors or buffers, the packet gets dropped (tail-drop). Hardware resources can be limited per destination type (multicast/unicast), per port, and per TX queue. When any of these limits are reached, no additional packets can be enqueued for transmission, and subsequent packets get dropped. RouterOS abstracts low-level hardware details, allowing resource limits to be configured either in terms of packets or as a percentage of the total amount. RouterOS automatically calculates the required hardware descriptor and buffer count based on the user-specified packet limit and port's MTU. Additionally, RouterOS includes preconfigured hardware resources, eliminating the need for manual configuration in common QoS scenarios. :::danger Modifying any hardware resource allocation parameter at runtime causes a temporary device halt during which no packets can be enqueued or transmitted. Temporary packet loss is expected while the device is forwarding traffic. ::: ## Resource Saving (Previous Generation Devices) :::info This section applies only to devices that do **not** support **Dynamic Buffers**. ::: Because hardware resources cannot be reallocated at runtime, RouterOS cannot automatically release queue buffers reserved for inactive ports. These buffers remain unused. However, if you know that a specific port will never be used (for example, it stays physically disconnected), you can manually free the corresponding queue resources by assigning the built-in "offline" tx-manager with minimum resources: ```ros /interface/ethernet/switch/qos/port set sfp-sfpplus1 tx-manager=offline set sfp-sfpplus2 tx-manager=offline ``` :::danger Do not configure the "offline" tx-manager on the **switch-cpu** port. ::: :::warning When configuring the `tx-manager` setting for a QSFP+ or QSFP28 interface, you must apply the same configuration to all four sub-interfaces of that port. For example, if interface qsfp28-1-1 is active and linked at 100Gbps, while sub-interfaces (qsfp28-1-2, qsfp28-1-3, qsfp28-1-4) show a non-running flag, **do not assign the "offline" tx-manager to those non-running sub-interfaces**. Doing so will affect the 100Gbps link as well. However, if none of the four sub-interfaces are running, it is safe to assign the "offline" tx-manager setting. ::: ## Traffic Prioritization The hardware supports two types of traffic transmission prioritization: - **Strict Priority** - traffic from higher queues is always transmitted first. - **Enhanced Transmission Selection (ETS)** - multiple queues participate in packet transmission scheduling at the same time using weighted round-robin. **Strict Priority** queuing is straightforward. If the highest priority queue (Q7) has packets, those are transmitted first. When Q7 is empty, packets from Q6 get transmitted, and so on. The packets from the lowest priority queue (Q0) are transmitted only if all other queues are empty. The downside of strict prioritization is increased latency in lower queues while "overprioritizing" higher queues. Suppose the acceptable latency of TC5 is 20ms, TC3 - 50ms. Traffic appearing in Q5 gets immediately transmitted due to the strict priority of the queue, adding extra latency to every packet in the lower queues (Q4..Q0). A packet burst in Q5 (e.g., a start of a voice call) may temporarily "paralyze" Q3, increasing TC3 latencies over the acceptable 50ms (or even causing packet drops due to a full queue) while TC5 packets get transmitted at <1ms (way below the 20ms limit). Slightly sacrificing TC5 latency by transmitting TC3 packets in between would make everybody happy. That is what **ETS** is for. **Enhanced Transmission Selection (ETS)** schedules traffic for transmission from multiple queues (group members) in a weighted round-robin manner. A queue's weight sets the number of packets transmitted from the queue in each round. For example, if Q2, Q1, and Q0 are the group members, and their weights are 3, 2, and 1, respectively, the scheduler transmits 3 packets from Q2, 2 from Q1, and 1 from Q0. The actual transmission order in each round of the above example is "Q2, Q1, Q0, Q2, Q1, Q2" - for even fairer scheduling. There are two hardware groups: `low-priority-group` and `high-priority-group`. There is a strict priority ordering between the two groups: the low-priority-group transmits only when *all* queues in the high-priority-group are empty. However, it is possible to use only one group for all queues. The default (built-in) RouterOS queue setup is listed below. Q3-Q5 share the bandwidth within the high-priority group, where packets are transmitted while Q6 and Q7 are empty. Q0-Q2 are the members of the low-priority-group, where packets are transmitted while Q3-Q7 are empty. ```ros [admin@MikroTik] /interface/ethernet/switch/qos/tx-manager/queue> print Columns: TX-MANAGER, TRAFFIC-CLASS, SCHEDULE, WEIGHT, QUEUE-BUFFERS, USE-SHARED-BUFFERS # TX-MANAGER TRAFFIC-CLASS SCHEDULE WEIGHT QUEUE-BUFFERS USE-SHARED-BUFFERS 0 default 0 low-priority-group 1 auto no 1 default 1 low-priority-group 2 auto yes 2 default 2 low-priority-group 3 auto yes 3 default 3 high-priority-group 3 auto yes 4 default 4 high-priority-group 4 auto yes 5 default 5 high-priority-group 5 auto yes 6 default 6 strict-priority auto yes 7 default 7 strict-priority auto yes ``` :::tip It is recommended that all group members are adjacent to each other. ::: ## Active Queue Management (AQM) ### Weighted Random Early Detection (WRED) WRED is a congestion control mechanism that operates on a per-queue basis. It signals congestion events to end-point devices by dropping packets before queue overflow occurs. WRED relies on rate throttling mechanisms in end-points that respond to packet loss, such as TCP/IP. WRED uses a randomized packet drop algorithm to anticipate congestion events and respond to them by throttling traffic rates before congestion actually happens. The randomness property of WRED prevents throughput collapse caused by global synchronization of TCP flows. WRED can be enabled or disabled per queue in each Tx Manager. Disable WRED for lossless traffic classes. There is also no reason to enable WRED on high-speed ports where congestion should not occur in the first place. The behavior is controlled via the WRED threshold. The WRED threshold defines the maximum number of packets or bytes that can exceed the queue's shared buffer limit (cap). Random packet drops begin when queue usage exceeds its respective capacity: - `queueX-packet-use > queueX-shared-packet-cap`, or - `queueX-byte-use > queueX-shared-byte-cap`. The more the usage exceeds the capacity, the higher the packet drop chance becomes, reaching 100% at `queueX-shared-packet-cap + wred-packet-threshold` (or byte equivalent). RouterOS automatically selects the actual WRED threshold values based on queue or shared pool capacities. The user can adjust the thresholds via the QoS Settings. :::danger WRED requires the respective Tx queue to use shared buffers (**use-shared-buffers=yes**). ::: Choosing a WRED threshold value involves a tradeoff between congestion anticipation and burst absorption. Setting a higher WRED threshold may lead to earlier traffic rate throttling and, therefore, resolve congestion. However, a high threshold causes packet drops in limited traffic bursts that could be absorbed by the queue buffers and transmitted losslessly if WRED didn't activate. For example, initiating a remote database connection usually starts with heavier traffic (a "packet burst") during the initialization phase, then the traffic rate drops to a "reasonable" level. Any packet drop during the initialization phase results in a slower database connection due to the need for retransmission. Therefore, lowering the WRED threshold or entirely disabling WRED on such traffic is recommended. The opposite case is video streaming, where early congestion detection helps select a comfortable streaming rate without losing too much bandwidth on retransmission or sacrificing quality level. :::info Use Switch Rules (ACL) or other QoS Marking techniques to differentiate traffic and place packets into queues with the desired WRED settings. ::: The following script applies WRED only to TCP/IP traffic by redirecting it to queue2. UDP and other packets remain in queue1 since their end-points typically cannot respond to early drops. Queue1 and queue2 are scheduled equally without prioritizing one queue over another: ```ros /interface/ethernet/switch/qos/profile add name=tcp-wred traffic-class=2 pcp=0 dscp=0 # move TCP traffic to queue2 /interface/ethernet/switch/rule add new-qos-profile=tcp-wred ports=ether1,ether2,ether3,ether4 protocol=tcp switch=switch1 # set the same scheduling priority (weight) between queue1 and queue2 # apply WRED only to queue2 - TCP traffic /interface/ethernet/switch/qos/tx-manager/queue/ set [find where traffic-class=1] weight=2 schedule=low-priority-group use-shared-buffers=yes wred=no set [find where traffic-class=2] weight=2 schedule=low-priority-group use-shared-buffers=yes wred=yes ``` ## Explicit Congestion Notification (ECN) Certain switch chip models support hardware-level ECN marking for IP packets, compliant with RFC 3168. This mechanism operates similarly to WRED but, instead of dropping packets during congestion, it marks them with the CE (Congestion Experienced, binary 11) flag in the ECN field. Only ECN-capable IP packets can receive this mark—those with the ECN field value set to ECT(1) or ECT(0) (binary 01 or 10). Non-ECN-capable transport packets (ECN=00) are never marked. If a packet already carries the CE mark (ECN=11), it retains this designation regardless of whether the device experiences congestion. Enable ECN marking by setting **ecn=yes** on the desired [Tx Manager Queue](quality-of-service.md#transmission-manager). :::danger The ECN marking mechanism requires the respective Tx queue to use shared buffers (**use-shared-buffers=yes**). ::: A packet receives the CE mark when **all** of the following conditions are met: 1. The packet is IPv4 or IPv6. 2. The ECN field value in the IP header is either ECT(1) or ECT(0). 3. The egress port's Tx Queue has **ecn=yes** enabled and uses shared buffers (**use-shared-buffers=yes**). 4. Queue usage exceeds the shared buffer capacity: `queueX-packet-use > queueX-shared-packet-cap` or `queueX-byte-use > queueX-shared-byte-cap`. :::danger Since enabling ECN (ecn=yes) prevents ECN-capable packet drops, queue usage may exceed WRED thresholds if the traffic sender does not respond to congestion notification in time. ::: ## Priority-based Flow Control (PFC) Priority-based Flow Control (PFC) enables lossless operation for up to eight traffic classes, ensuring that congestion in one traffic class does not pause traffic in other classes. This allows loss-sensitive traffic types to coexist with loss-tolerant traffic types on the same network. PFC-capable switch chips comply with IEEE 802.1Qbb PFC standard, meaning they can generate and respond to PFC frames. When congestion occurs on an egress port, the source port transmits a PFC frame for the affected traffic class. The generated PFC frames use timer value 0xFFFF for pause (XOFF) and 0x0 for resume (XON), with the appropriate bit set in the priority enable vector. On the receiving end, the PFC frame pauses the specific priority queues on the destination port for the duration specified in the PFC frame. In RouterOS, PFC configuration is organized into profiles. Each port can be assigned to a specific PFC profile, which defines the traffic classes to enable PFC on, the pause and resume thresholds for sending XOFF and XON frames respectively, and whether the assigned ports should transmit and/or receive PFC frames. When congestion occurs on an egress port, PFC is triggered on the ingress port. Shared buffers must be used to associate the amount of ingress traffic with the packets waiting in Tx queues. For each PFC-enabled traffic class, set **use-shared-buffers=yes** on the corresponding Tx queue. :::info RouterOS implements a 1:1 mapping between traffic classes and Tx queues. Packets with traffic class 0 are enqueued in queue0, TC1 in queue1, and so on up to TC7 in queue7. Therefore, the terms "traffic class" and "Tx queue" are used interchangeably throughout this documentation. ::: When selecting pause and resume thresholds, account for the delay in transmitting and processing PFC frames. For example, device A experiences congestion at time T, sends a PFC pause frame to device B, and B processes the frame and stops transmitting at time T+D. During the delta time D, device B continues sending traffic. If device A has configured the pause threshold to 100%, it has no free buffers available, and packets may drop, which is unacceptable for lossless traffic classes. Setting a lower pause threshold, such as 80%, sends a PFC pause frame while still retaining free memory to absorb traffic during the delta time D. The same principle applies to the resume threshold. Setting it to 0% keeps the device idle during the delta time, reducing overall throughput. PFC receive requires setting the egress rate for all associated queues to calculate pause time, even if it matches the wire speed. For example, if PFC runs on traffic class 3, the assigned ports require the `egress-rate-queue3` setting. ```routeros /interface/ethernet/switch/qos/priority-flow-control/add name=pfctc3 traffic-class=3 rx=yes /interface/ethernet/switch/qos/port/set sfp-sfpplus1,sfp-sfpplus2 pfc=pfctc3 egress-rate-queue3=10G ``` ## Property Reference ### Switch settings **Sub-menu:** `/interface/ethernet/switch` Switch QoS settings (in addition to the existing ones). | Property | Description | | :-- | :-- | | **qos-hw-offloading** (*yes \| no*; Default: **no**) | Allows enabling QoS for the given switch chip (if it supports QoS). New generation devices force **qos-hw-offloading=yes** at all times. | :::tip When you enable QoS, turning off the **qos-hw-offloading** setting will not completely revert to the previous functionality. It is recommended to reboot the device after disabling it. ::: ### Port Settings **Sub-menu:** `/interface/ethernet/switch/qos/port` This sub-menu configures QoS settings for individual switch ports. It allows you to assign a QoS profile to ingress packets arriving on a specific port. If the port is configured as trusted, the assigned profile can be overridden by match rules based on packet header values. By default, all ports are untrusted and receive the default QoS profile (Best-Effort, PCP=0, DSCP=0). In this default state, priority fields are cleared from egress packets. #### Port Stats **Example** ```ros [admin@Mikrotik] /interface/ethernet/switch/qos/port> print stats where name=ether2 name: ether2 tx-packet: 2 887 tx-byte: 3 938 897 drop-packet: 1 799 drop-byte: 2 526 144 tx-queue0-packet: 50 tx-queue1-packet: 1 871 tx-queue3-packet: 774 tx-queue5-packet: 192 tx-queue0-byte: 3 924 tx-queue1-byte: 2 468 585 tx-queue3-byte: 1 174 932 tx-queue5-byte: 291 456 drop-queue1-packet: 1 799 drop-queue1-byte: 2 526 144 ``` | Property | Description | | :-- | :-- | | **name** | Port name. | | **tx-packet** | The total number of packets transmitted via this port. | | **tx-byte** | The total number of bytes transmitted via this port. | | **drop-packet** | The total number of packets that should have been transmitted via this port but were dropped due to a lack of resources (e.g., queue buffers) or QoS Enforcement. | | **drop-byte** | The total number of bytes that should have been transmitted via this port but were dropped. | | **tx-queue0-packet** .. **tx-queue7-packet** | The number of packets transmitted via this port from the respective queue. | | **tx-queue0-byte** .. **tx-queue7-byte** | The number of bytes transmitted via this port from the respective queue. | | **drop-queue0-packet** .. **drop-queue7-packet** | The number of packets dropped from the respective queue (or not enqueued at all due to lack of resources). | | **drop-queue0-byte** .. **drop-queue7-byte** | The number of bytes dropped from the respective queue. | #### Port Resources/Usage :::danger Due to hardware limitations, some switch chip models may break traffic flow while accessing QoS port `usage` data. Use port `usage` for diagnostics/troubleshooting only. For monitoring, use QoS `monitor` or Port `stats` instead. ::: **Example** ```ros [admin@crs326] /interface/ethernet/switch/qos/port> print usage where name=ether2 name: ether2 packet-cap: 136 packet-use: 5 byte-cap: 35 840 byte-use: 9 472 queue0-packet-cap: 130 queue0-packet-use: 1 queue1-packet-cap: 5 queue1-packet-use: 4 queue3-packet-cap: 65 queue3-packet-use: 2 queue0-byte-cap: 24 576 queue0-byte-use: 256 queue1-byte-cap: 7 680 queue1-byte-use: 6 144 queue3-byte-cap: 14 080 queue3-byte-use: 3 072 ``` | Property | Description | | :-- | :-- | | **name** | Port name. | | **packet-cap** | Port's packet capacity. The maximum number of packets that can be enqueued for transmission via the port. | | **packet-use** 1 | Port's packet usage. The number of packets that are currently enqueued in all port's queues. | | **byte-cap** | Port's byte capacity (buffer size). The maximum number of bytes that can be enqueued for transmission via the port. | | **byte-use** 1 | Port's byte usage. The size of hardware buffers (in bytes) that are currently allocated for the enqueued packets. Since the buffers are allocated by blocks (usually - 256B each), the allocated buffer size can be bigger than the actual payload. | | **queue0-packet-cap** .. **queue7-packet-cap** 2 | Individual queue capacity. The maximum number of packets that can be enqueued in the respective queues (unless the **Shared Buffers** are enabled). | | **queue0-shared-packet-cap** .. **queue7-shared-packet-cap** 2 | Shared queue capacity (individual queue capacity + shared buffers). The maximum number of packets that can be enqueued in the respective queues. | | **queue0-packet-use** .. **queue7-packet-use** 2 | Queue packet usage. The number of enqueued packets in the respective queues. | | **queue0-byte-cap** .. **queue7-byte-cap** 2 | Individual queue capacity. The maximum number of bytes that can be enqueued in the respective queues (unless the **Shared Buffers** are enabled). | | **queue0-shared-byte-cap** .. **queue7-shared-byte-cap** 2 | Shared queue capacity (individual queue capacity + shared buffers). The maximum number of bytes that can be enqueued in the respective queues. | | **queue0-byte-use** .. **queue7-byte-use** 2 | Queue buffer usage (in bytes). The size of hardware buffers (in bytes) that are currently allocated for packets in the respective queues. | | **queue0-byte-max** .. **queue7-byte-max** 2 | Maximum queue buffer fill level (in bytes). Available only on devices that provide the queue statistics service. Use the `reset-counters` command to reset values. | **1** Port's packet/byte usage can exceed the capacity if Shared Buffers are enabled. **2** Only the queues in use are printed. #### Port PFC Stats (Previous Generations) **Example** ```ros [admin@crs317] /interface/ethernet/switch/qos/port> print pfc interval=1 where running name: sfp-sfpplus1 sfp-sfpplus2 ether1 pfc: roce disabled disabled pfc-tx: 46 pfc-paused-tc: 3 pfc3-pause-threshold: 1 048 576 pfc3-resume-threshold: 10 240 pfc3-use: 1 075 200 ``` | Property | Description | | :-- | :-- | | **name** | Port name. | | **pfc** | PFC profile name. | | **pfc-rx** | Received PFC frame count. | | **pfc-tx** | Transmitted PFC frame count. | | **pfc-paused-tc** | The list of traffic classes that should be paused (from the sender's perspective). PFC pause frames (XOFF) are periodically sent with the listed timers set from this port. | | **pfc0-pause-threshold .. pfc7-pause-threshold** | Pause thresholds of the respective traffic classes. Only PFC-enabled traffic classes are displayed. | | **pfc0-resume-threshold .. pfc7-resume-threshold** | Resume thresholds of the respective traffic classes. Only PFC-enabled traffic classes are displayed. | | **pfc0-use .. pfc7-use** | The current buffer usage of the respective traffic classes (in bytes). In other words, it is the total size of all queued packets on all ports that were received from this port. Only PFC-enabled traffic classes are displayed. | #### Port PFC Stats (New Generations) **Example** ```routeros [admin@crs812] /interface/ethernet/switch/qos/port> print pfc interval=1 where pfc=roce name: sfp56-5 pfc: roce rx-pause: 287 tx-pause: 46 pfc3-use: 2 184 200 ``` | Property | Description | | :-- | :-- | | **name** | Port name. | | **pfc** | PFC profile name. | | **pfc0-use .. pfc7-use** | The current buffer usage of the respective traffic classes (in bytes). In other words, it is the total size of all queued packets on all ports that were received from this port. Only PFC-enabled traffic classes are displayed. | | **rx-pause** | Received pause frame count. | | **tx-pause** | Transmitted pause frame count. | ### QoS Menu **Sub-menu:** `/interface/ethernet/switch/qos` The entire QoS hardware configuration is located under `/in/eth/sw/qos`. This centralized approach allows you to store all QoS-related configuration items in one place, making it easy to monitor and export settings using `/in/eth/sw/qos/export`. QoS entries have two major flag indicators: - **H** - Hardware-offloaded entry. - **I** - Inactive entry. ### QoS Settings **Sub-menu:** `/interface/ethernet/switch/qos/settings` | Property | Description | | :-- | :-- | | **mirror-buffers** (*percent**: 1..90*; Default: **auto**) | Maximum number of packet buffers for [mirrored](./marvell-prestera-switch-chip-features.md#mirroring) traffic (% of the total buffer memory). | | **mirror-profile** (*name*; Default: **default**) | The name of the [QoS profile](#qos-profile) to assign to the [mirrored](./marvell-prestera-switch-chip-features.md#mirroring) packets (see **`/in/eth/sw/qos/profile`**). | | **multicast-buffers** (*percent**: 1..90*; Default: **auto**) | Maximum number of packet buffers for multicast/broadcast traffic (% of the total buffer memory). | | **shared-buffers** (*percent**: 0..90*; Default: **auto**) | Maximum number of packet buffers that are shared between ports (% of the total buffer memory). Setting it to 0 disables buffer sharing. The remaining buffer memory is split between the ports. All buffers are treated as shared on new generation switch chips that use **Dynamic Buffers**. The switch chip automatically adjusts port and queue buffer limits based on the current congestion level. Using the auto value allows the device to utilize 100% of the available buffer memory, which is the recommended setting for most scenarios. In specific use cases where latency is more important than avoiding packet drops, the buffer limit can be manually reduced. | | **lossless-buffers**(*percent**: 0..100*; Default: **auto**) | If the device supports multiple shared buffer pools, this setting allows adjusting the size of the lossless pool (% of the *shared* buffer memory, where 100% means all shared buffers allocated by the **shared-buffers** setting). For example, if shared-buffers=50 and lossless-buffers=80, the lossless pool receives 40% of the total buffer memory (80% of 50% or "0.8 \* 0.5 = 0.4"), and the lossy pool receives the remaining 10% of shared buffers. | | **lossless-traffic-class**(*integer array: 0..7*; Default: **auto**) | The list of lossless traffic classes. | | **wred-threshold**(*low \| medium \| high;*Default: **medium**) | A relative number of packets above a shared queue cap (`queueX-shared-packet-cap` or `queueX-shared-byte-cap`) where random drops take place. This threshold is applied only to queues with enabled [Weighted Random Early Detection](quality-of-service.md#weighted-random-early-detection-wred) (**wred=yes**) that use shared buffers (****use-shared-buffers=yes)****. The higher the queue buffer fill level, the higher the packet drop chance. The *low* threshold means the random tail drop starts later; the *high* - sooner. | ### QoS Monitor **Command:**`/interface/ethernet/switch/qos/monitor` #### Example ```ros [admin@crs312] /interface/ethernet/switch/qos> monitor once total-packet-cap: 11 480 total-packet-use: 0 total-byte-cap: 2648.0KiB total-byte-use: 0 multicast-packet-cap: 1 148 multicast-packet-use: 0 multicast-byte-cap: 264.8KiB multicast-byte-use: 0 mirror-ingress-packet-cap: 1 148 mirror-ingress-packet-use: 0 mirror-ingress-byte-cap: 264.8KiB mirror-ingress-byte-use: 0 mirror-egress-packet-cap: 1 148 mirror-egress-packet-use: 0 mirror-egress-byte-cap: 264.8KiB mirror-egress-byte-use: 0 lossy-pool-packet-cap: 2 301 lossy-pool-packet-use: 0 lossless-pool-packet-cap: 2 301 lossless-pool-packet-use: 0 lossy-pool-byte-cap: 530.0KiB lossy-pool-byte-use: 0 lossless-pool-byte-cap: 530.0KiB lossless-pool-byte-use: 0 ``` Monitors hardware QoS resources. | Property | Description | | :-- | :-- | | **total-packet-cap** *(integer)* | Total packet capacity. The maximum number of hardware packet descriptors that the device can store in all queues. | | **total-packet-use** *(integer)* | Total packet usage. The current number of packet descriptors residing in the hardware memory. | | **total-byte-cap** *(byte)* | Total tx memory capacity. | | **total-byte-use** *(byte)* | Total tx memory usage. The current number of bytes occupied by the packets in all tx queues. | | **multicast-packet-cap***(integer)* | Multicast packet capacity. The maximum number of hardware packet descriptors that can be used by multicast/broadcast traffic. Depends on the **multicast-buffers** setting. | | **multicast-packet-use** *(integer)* | Multicast packet usage. The hardware makes a copy of the packet descriptor for each multicast destination. | | **mirror-ingress-packet-cap** *(integer)* | Ingress mirror packet capacity. The maximum number of hardware packet descriptors that can be used by ingress mirrored traffic. Depends on the **mirror-buffers** setting. | | **mirror-ingress-packet-use** *(integer)* | Ingress mirror packet usage. | | **mirror-ingress-byte-cap** *(byte)* | Ingress mirror byte capacity. Depends on the **mirror-buffers** setting. | | **mirror-ingress-byte-use** *(byte)* | Ingress mirror byte usage. | | **mirror-egress-packet-cap** *(integer)* | Egress mirror packet capacity. The maximum number of hardware packet descriptors that can be used by egress mirrored traffic. Depends on the **mirror-buffers** setting. | | **mirror-egress-packet-use** *(integer)* | Egress mirror packet usage. | | **mirror-egress-byte-cap** *(byte)* | Egress mirror byte capacity. Depends on the **mirror-buffers** setting. | | **mirror-egress-byte-use** *(byte)* | Egress mirror byte usage. | | **shared-packet-cap** *(integer)* | Shared packet capacity. The maximum number of hardware packet descriptors that can be shared between ports and tx queues. Depends on the **shared-buffers** setting. | | **shared-packet-use** *(integer)* | Shared packet usage. The current number of shared packet descriptors used by all tx queues. | | **shared-byte-cap** *(byte)* | Shared tx memory capacity. Depends on the **shared-buffers** setting. | | **shared-byte-use** *(byte)* | Shared tx memory usage. The current number of shared buffers occupied by the packets in all tx queues. | | **lossy-pool-packet-cap**(integer) | Shared packet capacity of the lossy pool. The field is omitted if the device does not support multiple shared pools. | | **lossy-pool-packet-use (integer)** | Shared packet usage of the lossy pool. The field is omitted if the device does not support multiple shared pools. | | **lossless-pool-packet-cap (integer)** | Shared packet capacity of the lossless pool. The field is omitted if the device does not support multiple shared pools. | | **lossless-pool-packet-use (integer)** | Shared packet usage of the lossless pool. The field is omitted if the device does not support multiple shared pools. | | **wred-packet-cap** *(integer)* | The maximum packet count that a queue can use above the shared cap (`queueX-shared-packet-cap` in `/in/eth/sw/qos/port/print usage`) to trigger a random tail drop. For example, if `queue1-shared-packet-cap=3072` and `wred-packet-cap=512`, WRED triggers when `queue1-packet-use` exceeds 3072, reaching 100% drop rate at 3072+512=3584 packets. | | **wred-byte-cap** *(integer)* | The maximum byte count that a queue can use above the shared cap (`queueX-shared-byte-cap`) to trigger a random tail drop. For example, if `queue1-shared-byte-cap=768KiB` and `wred-byte-cap=128KiB`, WRED triggers when `queue1-packet-use` exceeds 768KiB, reaching 100% drop rate at 768+128=896KiB. | ### QoS Profile **Sub-menu:** `/interface/ethernet/switch/qos/profile` QoS profiles determine priority field values (PCP, DSCP) for the forwarded/routed packets. Congestion avoidance/resolution is based on QoS profiles. Each packet gets a QoS profile assigned based on the ingress switch port QoS settings (see `/in/eth/sw/port`). | Property | Description | | :-- | :-- | | ****color**** (*green \| yellow \| red*; Default: **green**) | Traffic color for color-aware drop precedence management. Leave the default value (green) for color-blind drop precedence management. | | ****dscp**** (*integer: 0..63*; Default: **0**) | IPv4/IPv6 DSCP field value for the egress packets assigned to the QoS profile. | | **name** (*string*; Default: ) | The user-defined name of the QoS profile. | | **pcp** (*integer: 0..7*; Default: **0**) | VLAN priority value (IEEE 802.1q PCP - Priority Code Point). Used only if the egress packets assigned to the QoS profile are VLAN-tagged (have the 802.1q header). The value can be further altered via the QoS Egress Map. | | **traffic-class** (*integer: 0..7*; Default: **0**) | The traffic class determines the packet priority and the egress queue (see **tx-manager**). The queue number is usually the same as the traffic class (packets with tc0 go into queue0, tc1 - queue1, ... tc7 - queue7). Unlike pcp, where 0 means the default priority but 1 - the lowest one (and further customizable), traffic classes are strictly ordered. TC0 always selects the lowest priority, etc. | | ******automap******(yes*\| no*; Default: **yes**) | Automatically maps packets with matching PCP or DSCP values to this QoS profile. Only applies to **trusted** ports. | ### QoS Mapping **Sub-menu:** `/interface/ethernet/switch/qos/map` Priority-to-profile mapping table(-s) for trusted packets. All switch chips have one built-in map - **default**. In addition, some models allow the user to define custom mapping tables and assign different maps to various switch ports via the **qos-map** property: - Devices based on **Marvell Prestera **98DX224S, 98DX226S****, or ****98DX3236**** switch chip models support only one map - default. - Devices based on **Marvell Prestera 98DX8xxx**, **98DX4xxx** switch chips, or **98DX325x** model devices support up to 12 maps (the default + 11 user-defined). | Property | Description | | :-- | :-- | | **name** (*string*; Default: ) | The user-defined name of the mapping table. | #### `VLAN Map` **Sub-menu:** `/interface/ethernet/switch/qos/map/vlan` Matches VLAN priorities (802.1p PCP/DEI fields) to QoS profiles. By default, all values are matched to the default QoS profile. | Property | Description | | :-- | :-- | | ****dei-only**** (yes *\| no*; Default: **no**) | Maps only packets with DEI (formerly CFI) bit set in the VLAN header. | | **map** (*name*; Default: **default**) | The name of the mapping table. | | **profile** (*name*; Default: ) | The name of the QoS profile to assign to the matched packets. | | **pcp** (*range: 0..7*; Default: **0**) | VLAN priority (PCP) value(-s) for the lookup. | #### DSCP Map **Sub-menu:** `/interface/ethernet/switch/qos/map/ip` Matches DSCP values to QoS profiles. | Property | Description | | :-- | :-- | | **dscp** (*range: 0..63*; Default: **0**) | DSCP value(-s) for the lookup. | | **map** (*name*; Default: **default**) | The name of the mapping table. If not set, the standard (built-in) mapping table gets altered. | | **profile** (*name*; Default: ) | The name of the QoS profile to assign to the matched packets. | ### Transmission Manager **Sub-menu:** `/interface/ethernet/switch/qos/tx-manager` Transmission (Tx) Manager controls packet enqueuing for transmission and packet tx order. Different switch ports can be assigned to different Tx managers. The maximum number of hardware Tx managers depends on the switch chip model. | Property | Description | | :-- | :-- | | **name** (*string*; Default: ) | The user-defined name of the Tx Manager | | **queue-buffers***(percent: 0%..100% \| bytes \| auto;*Default:**auto**) | The total number of hardware Tx buffers allocated to all ports linked to this Tx Manager. Any value but **auto** is NOT scaled by the number of ports. For example, if queue-buffers=30%, and there are 3 ports using this Tx Manager, each respective port receives 10% of the total available resources. Adding two more ports to the Tx Manager drops per-port buffers down to 6% (30/5). | :::info Port status has no effect on the allocated resources. Running ports receive the same amount of queue buffers as disconnected or disabled ones if all of them are assigned to the same Tx Manager. ::: #### Transmission Queue Scheduler **Sub-menu:** `/interface/ethernet/switch/qos/tx-manager/queue` Each port has eight Tx queues. The assigned Tx Manager controls packet enqueuing and schedules transmission orders. Each queue can have either strict priority (where packets with the highest traffic class are always transmitted first) or be grouped together for a weighted round-robin tx schedule. Creating a Tx Manager automatically creates all eight respective queue schedulers. :::danger Changing any properties of Tx manager or queues completely halts traffic enqueueing and transmission during the offload process. Temporary packet loss is expected while the device is forwarding traffic. ::: | Property | Description | | :-- | :-- | | **tx-manager** (*name*; *read-only*) | The linked Tx Manager | | **traffic-class** (*integer: 0..7*; *read-only*) | The traffic class (tc0..tc7) and the respective port queue (queue0..queue7) that the scheduler controls. | | **schedule**(*strict-priority \| high-priority-group \| low-priority-group* ) | strict-priority - packets in the respective queue are always scheduled before moving to lower traffic classes. Packets with lower traffic classes are not transmitted until the current queue is empty.high-priority-group - all queues in the group are scheduled together by using a weighted round-robin principle. For example, if TC5 has weight 4, TC4 - 3, and TC3 - 2, then the scheduler transmits 4 packets from queue5, 3 packets from Q4, and 2 packets from Q3 in a single round. To achieve lower latency, each round is "sliced" between all queues in the group. In other words, the packet order in each round of the above example is "Q5, Q4, Q3, Q5, Q4, Q3, Q5, Q4, Q5".low-priority-group - similar logic to the high-priority-group, but the low-priority-group is scheduled only when all queues in the high-priority-group are empty. | | **weight** *(integer: 0..255;* Default: **1**) | The weight value for the traffic class if it is a member of a schedule group. The field is not used in the case of a strict priority schedule. | | ****queue-buffers*****(percent: 0%..100% \| bytes \| auto;*Default:**auto**) | The number of hardware Tx buffers allocated to this queue. Any value but **auto** is NOT scaled by the number of ports, i.e., the value gets split on ports linked to the Tx Manager. When given in percent, it means percentage of the tx-manager's queue-buffers value. | | ****use-shared-buffers**** *(yes \| no)* | Allow the queue to use the shared buffer pool when **queue-buffers**are full. If the queue is full and the shared buffers are disabled, the packet gets dropped. If the shared buffers are enabled, the queue may use up to **shared-packet-cap** or **shared-poolX-packet-cap** (see [QoS Settings](#qos-settings) for details) packets from the shared pool. | | ****wred****(*yes \| no*; Default: **no)** | Enables/disables [Weighted Random Early Detection](quality-of-service.md#weighted-random-early-detection-wred) for the given queue. | | *****ecn (******yes \| no; Default: **no**)* | Enables/disables [ECN marking](http://help.mikrotik.com#ecn) of the transmitted packets. | | ****wred-actual****(*yes \| no*; read-only) | The actual WRED value. | | ****ecn-actual**** (*yes \| no*; read-only) | The actual ECN value. | :::danger On some device models, due to hardware limitations, enabling ECN on one queue turns on CE marking of ECN-capable packets on all queues. In such cases, `ecn-actual=yes` despite `ecn=no`. ::: ### Priority-based Flow Control (PFC) **Sub-menu:** `/interface/ethernet/switch/qos/priority-flow-control` [PFC](quality-of-service.md#priority-based-flow-control-pfc) configuration is organized in profiles. Different switch ports can be assigned to different PFC profiles. The maximum number of hardware Tx managers depends on the switch chip model. The builtin profile named "**disabled**" cannot be changed. | Property | Description | | :-- | :-- | | **name** (*string*; Default: ) | The user-defined name of the PFC profile | | **pause-threshold** (*percent: 0%..100% \| bytes \| auto;* Default: **auto)** | Transmits a pause frame (XOFF) when the total size of enqueued packets reaches this threshold. Enqueued packets are counted per ingress port. Applies only when **tx=yes**. The value can be given either explicitly in bytes or percent of the respective shared pool size (**shared-poolX-byte-cap**). | | **resume-threshold** (*percent: 0%..100% \| bytes \| auto;* Default: **auto)** | Transmits a resume frame (XON) when the total size of enqueued packets drops down to this threshold. Enqueued packets are counted per ingress port. Applies only when **tx=yes**. The value can be given either explicitly in bytes or percent of the respective shared pool size (**shared-poolX-byte-cap**). | | ****rx**** (*yes \| no*; Default: **no)** | Enables receiving of PFC frames. The received PFC frame pauses the specific priority queues on the port that received the PFC frame for the duration specified by the PFC frame. Disabling rx disables queue pausing. | | **traffic-class** (*integer array: 0..7*) | The list of PFC-enabled traffic classes. | | **tx** (*yes \| no*; Default: **no)** | Enables transmission of PFC frames. | --- ## Switch Chip Features import WideTable from '@site/src/components/WideTable'; # Switch Chip Features --- There are several types of switch chips on Routerboards and they have different sets of features. Most of them (from now on "Other") have only the basic "Port Switching" feature, but there are a few with more features: | Feature | QCA8337 | Atheros8327 | Atheros8316 | Atheros8227 | Atheros7240 | IPQ-PPE | ICPlus175D | MT7621, MT7531 | EN7523 | RTL8367 | 88E6393X | 88E6191X, 88E6190 | 98PX1012 | Other | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | Port Switching | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | yes | | Port Mirroring | yes | yes | yes | yes | yes | no | yes | yes | yes | yes | yes | yes | no | no | | TX limit 1 | yes | yes | yes | yes | yes | no | no | yes | yes | yes | yes | yes | no | no | | RX limit 1 | yes | yes | no | no | no | no | no | yes | yes | yes | yes | yes | no | no | | Host table | 2048 entries | 2048 entries | 2048 entries | 1024 entries | 2048 entries | 2048 entries | 2048 entries 2 | 2048 entries | 1024 entries | 2048 entries | 16k entries | 16k entries | no | no | | Vlan table | 4096 entries | 4096 entries | 4096 entries | 4096 entries | 16 entries | no | no | 4096 entries 3 | 4096 entries 3 | 4096 entries 3 | 4096 entries 3 | 4096 entries 3 | no | no | | Rule table | 92 rules | 92 rules | 32 rules | no | no | no | no | no | no | no | 256 | no | no | no | **1** RouterOS v7 does not support bandwidth limiting features on these switch chips. **2** Independent VLAN Learning (IVL) is not supported; only Shared VLAN Learning (SVL) is available. **3** The Switch menu configuration supports only basic VLAN port forwarding, without complex tag translation options. ## Notes 1. For QCA8337, Atheros8327, Atheros8316, Atheros8227, and Atheros7240 the Tx/Rx rate limits can be changed with the `bandwidth` property on the `"/interface/ethernet"` menu, see more details in the [Ethernet manual](../wired-connections/ethernet.md). For RTL8367, 88E6393X, 88E6191X, 88E6190, MT7621, MT7531 and EN7523 Tx/Rx rate limit can be changed with `egress-rate` and `ingress-rate` properties on `/interface/ethernet/switch/port` menu. 2. MAC addresses are learned up to the specified number, but the content of a switch host table is not available in RouterOS and static host configuration is not supported. 3. [Bridge HW vlan-filtering](index.md#bridge-vlan-filtering) was added in RouterOS 7.1 for RTL8367, MT7621, MT7531, EN7523. The switch does not support other `ether-type` 0x88a8 or 0x9100 (only 0x8100 is supported) and no `tag-stacking`. Using these features will disable HW offload. :::info Cloud Router Switch (CRS) series devices have highly advanced switch chips built-in. They support a wide variety of features. For more details about switch chip capabilities on CRS1xx/CRS2xx series devices, check the [CRS1xx/CRS2xx series switches](./crs1xx-and-2xx-series-switches.md) manual. For MikroTik devices with Marvell Prestera switch (e.g. CRS3xx), see the [Marvell Prestera switch chip features](./marvell-prestera-switch-chip-features.md) manual. ::: | RouterBoard | Switch-chip description | | :-- | :-- | | **C52iG-5HaxD2HaxD-TC (hAP ax[^2]), C53UiG+5HPaxD2HPaxD (hAP ax[^3]), Chateau ax series** | IPQ-PPE (ether1-ether5) | | **cAPGi-5HaxD2HaxD (cAP ax)** | IPQ-PPE (ether1-ether2) | | **L009 series** | 88E6190 (ether2-ether8, sfp1) | | **RB5009 series** | 88E6393X (ether1-ether8, sfp-sfpplus1) | | **CCR2004-16G-2S+** | 88E6191X (ether1-ether8); 88E6191X (ether9-ether16); | | **RB4011iGS+** | RTL8367 (ether1-ether5); RTL8367 (ether6-ether10); | | **RB1100AHx4** | RTL8367 (ether1-ether5); RTL8367 (ether6-ether10); RTL8367 (ether11-ether13) | | **L41G-2axD (hAP ax lite)** | MT7531 (ether1-ether4) | | **RB750Gr3 (hEX), RB760iGS (hEX S)** | MT7621 (ether1-ether5) | | **E50UG (hEX Refresh)** | EN7523 (ether2-ether5) | | **RBM33G** | MT7621 (ether1-ether3) | | **RB3011 series** | QCA8337 (ether1-ether5); QCA8337 (ether6-ether10) | | **RB OmniTik ac series** | QCA8337 (ether1-ether5) | | **RBwsAP-5Hac2nD (wsAP ac lite)** | Atheros8227 (ether1-ether3) | | **RB941-2nD (hAP lite)** | Atheros8227 (ether1-ether4) | | **RB951Ui-2nD (hAP); RB952Ui-5ac2nD (hAP ac lite); RB750r2 (hEX lite); RB750UPr2 (hEX PoE lite); RB750P-PBr2 (PowerBox); RB750P r2; RBOmniTikU-5HnDr2 (OmniTIK 5); RBOmniTikUPA-5HnDr2 (OmniTIK 5 PoE)** | Atheros8227 (ether1-ether5) | | **RB750Gr2 (hEX); RB962UiGS-5HacT2HnT (hAP ac); RB960PGS (hEX PoE); RB960PGS-PB (PowerBox Pro)** | QCA8337 (ether1-ether5) | | **RB953GS** | Atheros8327 (ether1-ether3+sfp1) | | **RB850Gx2** | Atheros8327 (ether1-ether5) with ether1 optional | | **RB2011 series** | Atheros8327 (ether1-ether5+sfp1); Atheros8227 (ether6-ether10) | | **RB750GL; RB751G-2HnD; RB951G-2HnD; RBD52G-5HacD2HnD (hAP ac²), RBD53iG-5HacD2HnD (hAP ac³), RBD53GR-5HacD2HnD&R11e-LTE6 (hAP ac³ LTE6 kit), RBD53G-5HacD2HnD-TC&EG12-EA (Chateau LTE12)** | Atheros8327 (ether1-ether5) | | **RBcAPGi-5acD2nD (cAP ac), RBwAPGR-5HacD2HnD (wAP R ac and wAP ac LTE series), RBwAPG-5HacD2HnD (wAP ac), RBD25G-5HPacQD2HPnD (Audience), RBD25GR-5HPacQD2HPnD&R11e-LTE6 (Audience LTE6 kit),** | Atheros8327 (ether1-ether2) | | **RBD22UGS-5HPacD2HnD (mANTBox 52 15s)** | Atheros8327 (ether1-sfp1) | | **RB1100AH** | Atheros8327 (ether1-ether5); Atheros8327 (ether6-ether10) | | **RB1100AHx2** | Atheros8327 (ether1-ether5); Atheros8327 (ether6-ether10) | | **CCR1009-8G-1S-1S+; CCR1009-8G-1S** | Atheros8327 (ether1-ether4) | | **RB493G** | Atheros8316 (ether1+ether6-ether9); Atheros8316 (ether2-ether5) | | **RB435G** | Atheros8316 (ether1-ether3) with ether1 optional | | **RB450G** | Atheros8316 (ether1-ether5) with ether1 optional | | **RB450Gx4** | Atheros8327 (ether1-ether5) | | **RB433GL** | Atheros8327 (ether1-ether3) | | **RB750G** | Atheros8316 (ether1-ether5) | | **RB1200** | Atheros8316 (ether1-ether5) | | **RB1100** | Atheros8316 (ether1-ether5); Atheros8316 (ether6-ether10) | | **DISC Lite5** | Atheros8227 (ether1) | | **RBmAP2nD** | Atheros8227 (ether1-ether2) | | **RBmAP2n** | Atheros7240 (ether1-ether2) | | **RB750** | Atheros7240 (ether2-ether5) | | **RB750UP** | Atheros7240 (ether2-ether5) | | **RB751U-2HnD** | Atheros7240 (ether2-ether5) | | **RB951-2n** | Atheros7240 (ether2-ether5) | | **RB951Ui-2HnD** | Atheros8227 (ether1-ether5) | | **RB433 series** | ICPlus175D (ether2-ether3); older models had ICPlus175C | | **RB450** | ICPlus175D (ether2-ether5); older models had ICPlus175C | | **RB493 series** | ICPlus178C (ether2-ether9) | | **RB816** | ICPlus178C (ether1-ether16) | The command-line configuration is under the switch menu. This menu contains a list of all switch chips present in the system and some sub-menus as well. ```ros [admin@MikroTik] > /interface/ethernet/switch/print Flags: I - invalid # NAME TYPE MIRROR-SOURCE MIRROR-TARGET SWITCH-ALL-PORTS 0 switch1 Atheros-8327 none none 1 switch2 Atheros-8227 none none ``` Depending on the switch type there can be different configuration capabilities available. ## Features --- ### Port Switching To set up port switching on non-CRS series devices, check the [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) page. :::warning Port switching in RouterOS v6.41 and newer is done using the bridge configuration. Before RouterOS v6.41 port switching was done using the master-port property. ::: #### Switch All Ports Feature Ether1 port on RB450G/RB435G/RB850Gx2 devices has a feature that allows it to be removed/added to the default switch group. This setting is available on the `/interface/ethernet/switch` menu. By default ether1 port will be included in the switch group. ![Switch 4](./img/switch-chip-features-01.webp) | Property | Description | | :-- | :-- | | **switch-all-ports** (no*\| yes*; Default: **yes**) | Changes the ether1 switch group only on RB450G/RB435G/RB850Gx2 devices. yes - ether1 is part of the switch and supports switch grouping and all other advanced Atheros8316/Atheros8327 features including extended statistics (`/interface/ethernet/print` stats).no - ether1 is not part of the switch, effectively making it a stand-alone ethernet port, this way increasing its throughput to other ports in bridged and routed mode, but removing the switching possibility on this port. | ### Port Mirroring Port mirroring lets the switch copy all traffic that is going in and out of one port (`mirror-source`) and send out these copied frames to some other port (`mirror-target`). This feature can be used to easily set up a 'tap' device that receives all traffic that goes in/out of some specific port. Note that `mirror-source` and `mirror-target` ports have to belong to the same switch (see which port belongs to which switch in the `/interface/ethernet` menu). Also, mirror-target can have a special `cpu` value, which means that mirrored packets should be sent out to the switch chips CPU port. Port mirroring happens independently of switching groups that have or have not been set up. **Sub-menu:** `/interface/ethernet/switch` | Property | Description | | :-- | :-- | | **mirror-source** (*name \| none*; Default: **none**) | Selects a single mirroring source port. Ingress and egress traffic will be sent to the `mirror-target` port. Note that the `mirror-target` port has to belong to the same switch (see which port belongs to which switch in the `/interface/ethernet` menu). | | **mirror-target** (*name \| none \| cpu*; Default: **none**) | Selects a single mirroring target port. Mirrored packets from `mirror-source` and `mirror` (see the property in the rule and host table) will be sent to the selected port. | | **mirror-egress-target** (*name \| none*; Default: **none**) | Selects a single mirroring egress target port, only available on **88E6393X**, **88E6191X** and **88E6190** switch chips. Mirrored packets from `mirror-egress` (see the property in the port menu) will be sent to the selected port. | **Sub-menu:** `/interface/ethernet/switch/rule` | Property | Description | | :-- | :-- | | **mirror** (*no \| yes*; Default: **no**) | Whether to send a packet copy to the `mirror-target` port. | | **mirror-ports** (*name*; Default: ) | Selects multiple mirroring target ports, only available on the **88E6393X** switch chip. Matched packets in the ACL rule will be copied and sent to selected ports. | **Sub-menu:** `/interface/ethernet/switch/host` | Property | Description | | :-- | :-- | | **mirror** (*no \| yes*; Default: **no**) | Whether to send a frame copy to the `mirror-target` port from a frame with a matching MAC destination address (matching destination or source address for CRS3xx series switches) | **Sub-menu:** `/interface/ethernet/switch/port` | Property | Description | | :-- | :-- | | **mirror-egress** (*no \| yes*; Default: **no**) | Whether to send egress packet copy to the `mirror-egress-target` port, only available on **88E6393X**, **88E6191X** and **88E6190** switch chips. | | **mirror-ingress** (*no \| yes*; Default: **no**) | Whether to send ingress packet copy to the `mirror-ingress-target` port, only available on **88E6393X**, **88E6191X** and **88E6190** switch chips. | | **mirror-ingress-target** (*name \| none*; Default: **none**) | Selects a single mirroring ingress target port, only available on **88E6393X**, **88E6191X** and **88E6190** switch chips. Mirrored packets from `mirror-ingress` will be sent to the selected port. | Port mirroring configuration example: ```ros /interface/ethernet/switch set switch1 mirror-source=ether2 mirror-target=ether3 ``` :::danger If you set mirror-source as an Ethernet port for a device with at least two switch chips and these mirror-source ports are in a single bridge while mirror-target for both switch chips is set to send the packets to the CPU, then this will result in a loop, which can make your device inaccessible. ::: ### Port Settings Properties under this menu are used to configure VLAN switching and filtering options for switch chips that support a VLAN Table. These properties are only available to switch chips that have VLAN Table support. Check the [Switch Chip Features](./switch-chip-features.md) table to make sure your device supports such a feature. :::danger Ingress traffic is considered as traffic that is being sent **IN** a certain port; this port is sometimes called **ingress port**. Egress traffic is considered as traffic that is being sent **OUT** of a certain port; this port is sometimes called **egress port**. Distinguishing them is very important to properly set up VLAN filtering since some properties apply only to either ingress or egress traffic. ::: | Property | Description | | :-- | :-- | | **vlan-mode** (*check \| disabled \| fallback \| secure*; Default: **disabled**) | Changes the VLAN lookup mechanism against the [VLAN Table](./switch-chip-features.md#vlan-table) for ingress traffic.disabled - disables checking against the VLAN Table completely for ingress traffic. No traffic is dropped when set on the ingress port.fallback - checks tagged traffic against the VLAN Table for ingress traffic and forwards all untagged traffic. If ingress traffic is tagged and the egress port is not found in the VLAN table for the appropriate VLAN ID, then traffic is dropped. If a VLAN ID is not found in the VLAN Table, then traffic is forwarded. Used to allow known VLANs only in specific ports.check - checks tagged traffic against the VLAN Table for ingress traffic and drops all untagged traffic. If ingress traffic is tagged and the egress port is not found in the VLAN table for the appropriate VLAN ID, then traffic is dropped.secure - checks tagged traffic against the VLAN Table for ingress traffic and drops all untagged traffic. Both ingress and egress ports must be found in the VLAN Table for the appropriate VLAN ID, otherwise, traffic is dropped. | | **vlan-header** (*add-if-missing \| always-strip \| leave-as-is*; Default: **leave-as-is**) | Sets the action which is performed on the port for egress traffic.add-if-missing - adds a VLAN tag on egress traffic and uses default-vlan-id from the ingress port. Should be used for trunk ports.always-strip - removes a VLAN tag on egress traffic. Should be used for access ports.leave-as-is - does not add or remove a VLAN tag on egress traffic. Should be used for hybrid ports. | | **default-vlan-id** (*auto \| integer: 0..4095*; Default: **auto**) | Adds a VLAN tag with the specified VLAN ID on all untagged ingress traffic on a port. It should be used with vlan-header set to `always-strip` on a port to configure the port to be the access port. For hybrid ports default-vlan-id is used to tag untagged traffic. If two ports have the same default-vlan-id, then the VLAN tag is not added since the switch chip assumes that traffic is being forwarded between access ports. | :::warning On **QCA8337** and **Atheros8327** switch chips, a default `vlan-header=leave-as-is` property should be used. The switch chip will determine which ports are access ports by using the `default-vlan-id` property. The `default-vlan-id` should only be used on access/hybrid ports to specify which VLAN the untagged ingress traffic is assigned to. ::: ### VLAN Table The VLAN table specifies certain forwarding rules for packets that have a specific 802.1Q tag. Those rules are of higher priority than switch groups configured using the [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) feature. Basically, the table contains entries that map specific VLAN tag IDs to a group of one or more ports. Packets with VLAN tags leave the switch chip through one or more ports that are set in the corresponding table entry. The exact logic that controls how packets with VLAN tags are treated is controlled by a `vlan-mode` parameter that is changeable per switch port. VLAN ID based forwarding takes into account the MAC addresses dynamically learned or manually added in the host table. QCA8337 and Atheros8327 switch-chips also support Independent VLAN Learning (IVL) which does the learning based on both - MAC addresses and VLAN IDs, thus allowing the same MAC to be used in multiple VLANs. Packets without a VLAN tag are treated just as if they had a VLAN tag with port`default-vlan-id`. If `vlan-mode=check` or `vlan=mode=secure` is configured, to forward packets without VLAN tags you have to add an entry to the VLAN table with the same VLAN ID according to the `default-vlan-id`. | Property | Description | | :-- | :-- | | **disabled** (*no \| yes*; Default: **no**) | Enables or disables switch VLAN entry. | | **independent-learning** (no*\| yes*; Default: **yes**) | Whether to use shared-VLAN-learning (SVL) or independent-VLAN-learning (IVL). | | **ports** (*name*; Default: **none**) | Interface member list for the respective VLAN. This setting accepts comma-separated values. e.g. `ports=ether1,ether2`. | | **switch** (*name*; Default: **none**) | Name of the switch for which the respective VLAN entry is intended. | | **vlan-id** (*integer: 0..4095*; Default:) | The VLAN ID for certain switch port configurations. | :::warning Devices with **MT7621**, **MT7531**, **EN7523, RTL8367**, **88E6393X**, **88E6191X**, **88E6190** switch chips support [HW offloaded vlan-filtering](index.md#bridge-vlan-filtering) in RouterOS v7. VLAN-related configuration on the `/interface/ethernet/switch` menu is not available. ::: #### VLAN Forwarding Both `vlan-mode` and `vlan-header` along with the VLAN Table can be used to configure VLAN tagging, untagging and filtering. Multiple combinations are possible, each achieving a different result. Below you can find a table of what kind of traffic is going to be sent out through an egress port when certain traffic is received on an ingress port for each VLAN Mode. **NOTES:** - **L** - `vlan-header` is set to `leave-as-is` - **S** - `vlan-header` is set to `always-strip` - **A** - `vlan-header` is set to `add-if-missing` - **U** - Untagged traffic is sent out - **T** - Tagged traffic is sent out, a tag is already present on the ingress port - **TA** - Tagged traffic is sent out, a tag was added on the ingress port - **DI** - Traffic is dropped on ingress port because of the mode selected in vlan-mode - **DE** - Traffic is dropped on egress port because the egress port was not found in the VLAN Table - **VID match** - VLAN ID from the VLAN tag for ingress traffic is present in the VLAN Table - **Port match** - Ingress port is present in the VLAN Table for the appropriate VLAN ID | | | | | | | | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | *VLAN Mode = disabled* | Egress port is not present in VLAN Table | | | Egress port is present in VLAN Table | | | | | L | S | A | L | S | A | | Untagged traffic | U | U | TA | U | U | TA | | Tagged traffic; no VID match | T | U | T | | | | | Tagged traffic; VID match; no Port match | T | U | T | T | U | T | | Tagged traffic; VID match; Port match | T | U | T | T | U | T | | | | | | | | | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | *VLAN Mode = fallback* | Egress port is not present in VLAN Table | | | Egress port is present in VLAN Table | | | | | L | S | A | L | S | A | | Untagged traffic | U | U | TA | U | U | TA | | Tagged traffic; no VID match | T | U | T | | | | | Tagged traffic; VID match; no Port match | DE | DE | DE | T | U | T | | Tagged traffic; VID match; Port match | DE | DE | DE | T | U | T | | | | | | | | | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | *VLAN Mode = check* | Egress port is not present in VLAN Table | | | Egress port is present in VLAN Table | | | | | L | S | A | L | S | A | | Untagged traffic | | | | | | | | Tagged traffic; no VID match | DI | DI | DI | | | | | Tagged traffic; VID match; no Port match | DE | DE | DE | T | U | T | | Tagged traffic; VID match; Port match | DE | DE | DE | T | U | T | | | | | | | | | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | *VLAN Mode = secure* | Egress port is not present in VLAN Table | | | Egress port is present in VLAN Table | | | | | L | S | A | L | S | A | | Untagged traffic | | | | | | | | Tagged traffic; no VID match | DI | DI | DI | | | | | Tagged traffic; VID match; no Port match | DI | DI | DI | DI | DI | DI | | Tagged traffic; VID match; Port match | DE | DE | DE | T | U | T | :::warning The tables above are meant for more advanced configurations and to double-check your understanding of how packets will be processed with each VLAN related property. ::: ### Host Table The host table represents switch chip's internal MAC address to port mapping. It can contain two kinds of entries: dynamic and static. Dynamic entries get added automatically. This is also called a learning process: when the switch chip receives a packet from a certain port, it adds the packet's source MAC address and the port it received the packet from to the host table, so when a packet comes in with the same destination MAC address, it knows to which port it should forward the packet. If the destination MAC address is not present in the host table (so-called unknown-unicast traffic), then it forwards the packet to all ports in the group. Dynamic entries take about 5 minutes to time out. Learning is enabled only on ports that are configured as part of the switch group, so you won't see dynamic entries if you have not set up port switching. Also, you can add static entries that take over dynamic entries if a dynamic entry with the same MAC address already exists. Since port switching is configured using a bridge with hardware offloading, any static entries created on one table (either bridge host or switch host) will appear on the opposite table as a dynamic entry. Adding a static entry on the switch host table will provide access to some more functionality that is controlled via the following params: | Property | Description | | :-- | :-- | | **copy-to-cpu** (*no \| yes*; Default: **no**) | Whether to send a frame copy to the switch CPU port from a frame with a matching MAC destination address (matching destination or source address for CRS3xx series switches) | | **drop** (*no \| yes*; Default: **no**) | Whether to drop a frame with a matching MAC source address received on a certain port (matching destination or source address for CRS3xx series switches) | | **mac-address** (*MAC;* Default: **00:00:00:00:00:00**) | Host's MAC address | | **mirror** (*no \| yes*; Default: **no**) | Whether to send a frame copy to the `mirror-target` port from a frame with a matching MAC destination address (matching destination or source address for CRS3xx series switches) | | **ports** (*name*; Default: **none**) | Name of the interface, a static MAC address can be mapped to more than one port, including the switch CPU port | | **redirect-to-cpu** (*no \| yes*; Default: **no**) | Whether to redirect a frame to the switch CPU port from a frame with a matching MAC destination address (matching destination or source address for CRS3xx series switches) | | **share-vlan-learned**(*no \| yes*; Default: **no**) | Whether the static host MAC address lookup is used with shared-VLAN-learning (SVL) or independent-VLAN-learning (IVL). The SVL mode is used for those VLAN entries that do not support IVL or IVL is disabled (independent-learning=no) | | **switch** (*name*; Default: **none**) | Name of the switch to which the MAC address is going to be assigned | | **vlan-id** (*integer: 0..4095*; Default:) | VLAN ID for the statically added MAC address entry | :::warning Every switch chip has a finite number of MAC addresses it can store on the chip, see the Introduction table for a specific host table size. Once a host table is full, different techniques can be utilized to cope with the situation, for example, the switch can remove older entries to free space for more recent MAC addresses (used on QCA-8337 and Atheros-8327 switch chips), another option is to simply ignore the new MAC addresses and only remove entries after a timeout has passed (used on Atheros8316, Atheros8227, Atheros-7240, ICPlus175D and Realtek-RTL8367 switch chips), the last option is a combination of the previous two - only allow a certain number of entries to be renewed and keep the other host portion intact till the timeout (used on MediaTek-MT7621, MT7531, EN7523 switch chips). These techniques cannot be changed with configuration. ::: :::warning For Atheros8316, Atheros8227 and Atheros-7240 switch chips, the switch-cpu port will always participate in the host learning process when at least one hardware offloaded bridge port is active on the switching group. It will cause the switch-cpu port to learn MAC addresses from non-HW offloaded interfaces. This might cause packet loss when a single bridge contains HW and non-HW offloaded interfaces. Also, packet loss might appear when a duplicate MAC address is used on the same switching group regardless of whether hosts are located on different logical networks. It is recommended to use HW offloading only when all bridge ports can use HW offloading or keep it disabled on all switch ports when one or more bridge ports cannot be configured with HW offloading. ::: :::note The switch chips **QCA-8337** and **Atheros-8327** automatically add reserved multicast MAC addresses (01:80:C2:00:00:0x) to the host table when a hardware-offloaded bridge is created with `forward-reserved-addresses=no` and `protocol-mode=stp/rstp`. These MACs should not be forwarded by 802.1Q compatible bridges and they are essential for correct operation with R/STP. Since the switch has a limited number of host table entries, these MAC addresses are only assigned to VLAN 1. ::: :::info To ensure packets with these destination MAC addresses are processed correctly: - Switch ports should be set to default VLAN 1 (`default-vlan-id=auto` or `default-vlan-id=1`). - If VLAN 1 is explicitly configured, it must use independent VLAN learning (`independent-learning=yes`). ::: ### Rule Table Rule table is a very powerful tool allowing wire-speed packet filtering, forwarding and VLAN tagging based on L2, L3 and L4 protocol header field conditions. The menu contains an ordered list of rules just like in `/ip/firewall/filter`, so ACL rules are checked for each packet until a match has been found. If multiple rules can match, then only the first rule will be triggered. A rule without any action parameters is a rule to accept the packet. Each rule contains a condition part and an action part. The action part is controlled by the following parameters: | Property | Description | | :-- | :-- | | **copy-to-cpu** (*no \| yes*; Default: **no**) | Whether to send a packet copy to switch CPU port | | **mirror** (*no \| yes*; Default: **no**) | Whether to send a packet copy to `mirror-target` port | | **new-dst-ports** (*name*; Default: **none**) | Changes the destination port as specified, multiple ports allowed, including a switch CPU port. An empty setting will drop the packet. When the parameter is not used, the packet will be accepted | | **new-vlan-id** (*integer: 0..4095*) | Changes the VLAN ID to the specified value or adds a new VLAN tag if one was not already present (the property only applies to the **Atheros8316** and **88E6393X** switch chips (**NOTE**: in case of 88E6393X switch chip, vlan-filtering=yes is also required)) | | **new-vlan-priority** (*integer: 0..7*) | Changes the VLAN priority field (priority code point; the property only applies to **Atheros8327**, **QCA8337** and **Atheros8316** switch chips) | | **rate** (*integer: 0..4294967295*) | Sets ingress traffic limitation (bits per second) for matched traffic and can only be applied to the first 32 rule slots (the property only applies to **Atheros8327/QCA8337** switch chips) | | **redirect-to-cpu** (*no \| yes*; Default: **no**) | Changes the destination port of a matching packet to the switch CPU | The conditions part is controlled by the rest of the parameters: | Property | Description | | :-- | :-- | | **disabled** (*no \| yes*; Default: **no**) | Enables or disables the switch rule | | **dscp** (*integer: 0..63*) | Matching DSCP field of the packet | | **dst-address** (*IP address/Mask*) | Matching destination IP address and mask | | **dst-address6** (*IPv6 address/Mask*) | Matching destination IPv6 address and mask | | **dst-mac-address** (*MAC address/Mask*) | Matching destination MAC address and mask | | **dst-port** (*integer:* *0..65535*) | Matching destination protocol port number or range | | **flow-label** (*integer:* *0..1048575*) | Matching IPv6 flow label | | **mac-protocol** (*802.2 \| arp \| capsman \| dot1x \| homeplug-av \| ip \| ipv6 \| ipx \| lacp \| lldp \| loop-protect \| macsec \| mpls-multicast \| mpls-unicast \| mvrp \| packing-compr \| packing-simple \| pppoe \| pppoe-discovery \| rarp \| romon \| service-vlan \| vlan \| or 0..65535 \| or 0x0000-0xffff*) | Matching a particular MAC protocol specified by protocol name or number (skips VLAN tags if any) | | **ports** (*name*) | The Name of the interface on which the rule will apply to the received traffic, multiple ports are allowed. If the ports property is left empty, the rule will apply to all switch interfaces | | **protocol** (*dccp \| ddp \| egp \| encap \| etherip \| ggp \| gre \| hmp \| icmp \| icmpv6 \| idpr-cmtp \| igmp \| ipencap \| ipip \| ipsec-ah \| ipsec-esp \| ipv6 \| ipv6-frag \| ipv6-nonxt \| ipv6-opts \| ipv6-route \| iso-tp4 \| l2tp \| ospf \| pim \| pup \| rdp \| rspf \| rsvp \| sctp \| st \| tcp \| udp \| udp-lite \| vmtp \| vrrp \| xns-idp \| xtp \| or 0..255*) | Matching a particular IP protocol specified by protocol name or number | | **src-address** (*IP address/Mask*) | Matching source IP address and mask | | **src-address6** (*IPv6 address/Mask*) | Matching source IPv6 address and mask | | **src-mac-address** (*MAC address/Mask*) | Matching source MAC address and mask | | **src-port** (*0..65535*) | Matching source protocol port number or range | | **switch** (*switch group*) | Matching the switch group on which the rule will apply | | **traffic-class** (*0..255*) | Matching IPv6 traffic class | | **vlan-id** (*0..4095*) | Matching VLAN ID (the property only applies to the Atheros8316, Atheros8327, QCA8337, 88E6393X switch chips) | | **vlan-header** (*not-present \| present*) | Matching VLAN header, whether the VLAN header is present or not (the property only applies to the Atheros8316, Atheros8327, QCA8337, 88E6393X switch chips. In case of **88E6393X** switch chip, vlan-filtering=yes is also required) | | **vlan-priority** (*0..7*) | Matching VLAN priority (priority code point) | :::warning IPv4 and IPv6 specific conditions cannot be present in the same rule. ::: :::warning Because the rule table is processed entirely in switch chip hardware, there is a limitation on how many rules you may have. Depending on the number of conditions (MAC layer, IP layer, IPv6, L4 layer) you use in your rules, the number of active rules may vary from 8 to 32 for Atheros8316 switch chip, from 8 to 16 for Atheros8327/QCA8337 switch chip and from 42 to 256 for 88E6393X switch chip. You can always do `/interface/ethernet/switch/rule/print` after modifying your rule set to see that no rules at the end of the list are 'invalid', which means those rules did not fit into the switch chip. ::: ### Port isolation Port isolation provides the possibility to divide (isolate) certain parts of your network. This might be useful when you need to make sure that certain devices cannot access other devices. This can be done by isolating switch ports. Port isolation only works between ports that are members of the same switch. Switch port isolation is available on all switch chips since RouterOS v6.43. | Property | Description | | :-- | :-- | | **forwarding-override** (*interface*; Default: ) | Forces ingress traffic to be forwarded to a specific interface. Multiple interfaces can be specified by separating them with a comma. | :::info (R/M)STP will only work properly in PVLAN setups. (R/M)STP will not work properly in setups where there are multiple isolated switch groups, because switch groups might not properly receive BPDUs and therefore fail to detect network loops. ::: :::warning The `forwarding-override` property affects ingress traffic only. Switch ports that do not have the `forwarding-override` specified can send packets through all switch ports. ::: :::warning Switch chips with VLAN table support (**QCA8337**, **Atheros8327**, **Atheros8316**, **Atheros8227** and **Atheros7240**) can override the port isolation configuration when enabling a VLAN lookup on the switch port (the `vlan-mode` is set to `fallback`, `check` or `secure`). If additional port isolation is needed between ports on the same VLAN, a switch rule with a new-dst-ports property can be implemented. Other devices without switch rule support cannot overcome this limitation. ::: #### Private VLAN In some scenarios, you might need to forward all traffic to an uplink port while all other ports are isolated from each other. This kind of setup is called **Private VLAN** configuration. The **Switch** will forward all Ethernet frames directly to the uplink port allowing the **Router** to filter unwanted packets and limit access between devices that are behind switch ports. ![Port Isolation](./img/switch-chip-features-02.webp) To configure switch port isolation, you need to switch all required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add interface=sfp1 bridge=bridge1 hw=yes add interface=ether1 bridge=bridge1 hw=yes add interface=ether2 bridge=bridge1 hw=yes add interface=ether3 bridge=bridge1 hw=yes ``` :::warning By default, the bridge interface is configured with `protocol-mode` set to `rstp`. For some devices, this can disable hardware offloading because specific switch chips do not support this feature. See the [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) section with supported features. ::: Override the egress port for each switch port that needs to be isolated (excluding the uplink port): ```ros /interface/ethernet/switch/port-isolation set ether1 forwarding-override=sfp1 set ether2 forwarding-override=sfp1 set ether3 forwarding-override=sfp1 ``` :::warning It is possible to set multiple uplink ports for a single switch chip, this can be done by specifying multiple interfaces and separating them with a comma. ::: #### Isolated switch groups In some scenarios you might need to isolate a group of devices from other groups. This can be done using the switch port isolation feature. This is useful when you have multiple networks but you want to use a single switch. With port isolation you can allow certain switch ports to be able to communicate through only a set of switch ports. In this example, devices on **ether1-3** will only be able to communicate with devices that are on **ether1-3**, while devices on **ether4-5** will only be able to communicate with devices on **ether4-5** (**ether1-3** is not able to communicate with **ether4-5**). :::warning Port isolation is only available between ports that are members of the same switch. ::: ![Port Isolation 2](./img/switch-chip-features-03.webp) To configure isolated switch groups you must first switch all ports: ```ros /interface/bridge add name=bridge /interface/bridge/port add bridge=bridge1 interface=ether1 hw=yes add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether3 hw=yes add bridge=bridge1 interface=ether4 hw=yes add bridge=bridge1 interface=ether5 hw=yes ``` :::warning By default, the bridge interface is configured with `protocol-mode` set to `rstp`. For some devices, this can disable hardware offloading because specific switch chips do not support this feature. See the [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) section with supported features. ::: Then specify in the `forwarding-override` property all ports that you want to be in the same isolated switch group (except the port on which you are applying the property), for example, to create an isolated switch group for **A** devices: ```ros /interface/ethernet/switch/port-isolation set ether1 forwarding-override=ether2,ether3 set ether2 forwarding-override=ether1,ether3 set ether3 forwarding-override=ether1,ether2 ``` To create an isolated switch group for **B** devices: ```ros /interface/ethernet/switch/port-isolation set ether4 forwarding-override=ether5 set ether5 forwarding-override=ether4 ``` ### CPU Flow Control All switch chips have a special port that is called **switchX-cpu**. This is the CPU port for a switch chip. It is meant to forward traffic from a switch chip to the CPU. Such a port is required for management traffic and routing features. By default, the switch chip ensures that this special CPU port is not congested and sends out Pause Frames when link capacity is exceeded to make sure the port is not oversaturated. This feature is called **CPU Flow Control**. Without this feature, packets that might be crucial for routing or management purposes might get dropped. Since RouterOS v6.43, it is possible to disable the CPU Flow Control feature on some devices that are using one of the following switch chips: QCA8337, Atheros8227, Atheros8327, Atheros7240, Atheros8316, 88E6191X and 88E6393X. Other switch chips have this feature enabled by default and cannot be changed. To disable CPU Flow Control, use the following command: ```ros /interface/ethernet/switch/set switch1 cpu-flow-control=no ``` ### Statistics Some switch chips are capable of reporting statistics, this can be useful to monitor how many packets are sent to the CPU from the built-in switch chip. These statistics can also be used to monitor CPU Flow Control. You can find an example of the switch chip's statistics below: ```ros [admin@MikroTik] > /interface/ethernet/switch/print stats name: switch1 driver-rx-byte: 221 369 701 driver-rx-packet: 1 802 975 driver-tx-byte: 42 621 969 driver-tx-packet: 310 485 rx-bytes: 414 588 529 rx-packet: 2 851 236 rx-too-short: 0 rx-too-long: 0 rx-broadcast: 1 040 309 rx-pause: 0 rx-multicast: 486 321 rx-fcs-error: 0 rx-align-error: 0 rx-fragment: 0 rx-control: 0 rx-unknown-op: 0 rx-length-error: 0 rx-code-error: 0 rx-carrier-error: 0 rx-jabber: 0 rx-drop: 0 tx-bytes: 44 071 621 tx-packet: 312 597 tx-too-short: 0 tx-too-long: 8 397 tx-broadcast: 2 518 tx-pause: 2 112 tx-multicast: 7 142 tx-excessive-collision: 0 tx-multiple-collision: 0 tx-single-collision: 0 tx-excessive-deferred: 0 tx-deferred: 0 tx-late-collision: 0 tx-total-collision: 0 tx-drop: 0 tx-jabber: 0 tx-fcs-error: 0 tx-control: 2 112 tx-fragment: 0 tx-rx-64: 6 646 tx-rx-65-127: 1 509 891 tx-rx-128-255: 1 458 299 tx-rx-256-511: 178 975 tx-rx-512-1023: 953 tx-rx-1024-1518: 672 tx-rx-1519-max: 0 ``` Some devices have multiple CPU cores that are directly connected to a built-in switch chip using separate data lanes. These devices can report which data lane was used to forward the packet from or to the CPU port from the switch chip. For such devices, an extra line is added for each row, the first line represents data that was sent using the first data lane, the second line represents data that was sent using the second data line, and so on. You can find an example of the switch chip's statistics for a device with multiple data lanes connecting the CPU and the built-in switch chip: ```ros [admin@MikroTik] > /interface/ethernet/switch/print stats name: switch1 driver-rx-byte: 226 411 248 0 driver-rx-packet: 1 854 971 0 driver-tx-byte: 45 988 067 0 driver-tx-packet: 345 282 0 rx-bytes: 233 636 763 0 rx-packet: 1 855 018 0 rx-too-short: 0 0 rx-too-long: 0 0 rx-pause: 0 0 rx-fcs-error: 0 0 rx-overflow: 0 0 tx-bytes: 47 433 203 0 tx-packet: 345 282 0 tx-total-collision: 0 0 ``` ## Setup Examples --- :::info Make sure you have added all needed interfaces to the VLAN table when using secure `vlan-mode`. For routing functions to work properly on the same device through ports that use secure `vlan-mode`, you will need to allow access to the CPU from those ports; this can be done by adding the switchX-cpu interface itself to the VLAN table. Examples can be found in the [Management port](./switch-chip-features.md#management-access-configuration) section. ::: :::note It is possible to use the built-in switch chip and the CPU at the same time to create a Switch-Router setup, where a device acts as a switch and as a router at the same time. You can find a configuration example in the [Switch-Router](./switch-chip-features.md#inter-vlan-routing) section. ::: :::warning When allowing access to the CPU, you are allowing access from a certain port to the actual router/switch. This is not always desirable. Make sure you implement proper firewall filter rules to secure your device when access to the CPU is allowed from a certain VLAN ID and port. Use firewall filter rules to allow access to only certain services. ::: :::warning Devices with **MT7621**, **MT7531**, **EN7523, RTL8367**, **88E6393X**, **88E6191X,** **88E6190** switch chips support [HW offloaded vlan-filtering](index.md#bridge-vlan-filtering) in RouterOS v7. VLAN-related configuration on the `/interface/ethernet/switch` menu is not available. ::: :::warning For VLAN related matchers or VLAN related action parameters to work on the **88E6393X** switch chip, you need to enable vlan-filtering on the bridge interface and make sure that hardware offloading is enabled on those ports, otherwise, these parameters will not have any effect. ::: ### VLAN Example 1 (Trunk and Access Ports) RouterBOARDs with Atheros switch chips can be used for 802.1Q Trunking. This feature in RouterOS v6 is supported by **QCA8337, Atheros8316, Atheros8327, Atheros8227** and **Atheros7240** switch chips. In this example, **ether3**, **ether4,** and **ether5** interfaces are access ports, while **ether2** is a trunk port. VLAN IDs for each access port: ether3 - 200, ether4 - 300, ether5 - 400. ![Access Ports](./img/switch-chip-features-04.webp) Switch together the required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether3 hw=yes add bridge=bridge1 interface=ether4 hw=yes add bridge=bridge1 interface=ether5 hw=yes ``` :::warning By default, the bridge interface is configured with `protocol-mode` set to `rstp`. For some devices, this can disable hardware offloading because specific switch chips do not support this feature. See the [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) section with supported features. ::: Add VLAN table entries to allow frames with specific VLAN IDs between ports: ```ros /interface/ethernet/switch/vlan add ports=ether2,ether3 switch=switch1 vlan-id=200 add ports=ether2,ether4 switch=switch1 vlan-id=300 add ports=ether2,ether5 switch=switch1 vlan-id=400 ``` Assign `vlan-mode` and `vlan-header` mode for each port and also `default-vlan-id` on ingress for each access port: ```ros /interface/ethernet/switch/port set ether2 vlan-mode=secure vlan-header=add-if-missing set ether3 vlan-mode=secure vlan-header=always-strip default-vlan-id=200 set ether4 vlan-mode=secure vlan-header=always-strip default-vlan-id=300 set ether5 vlan-mode=secure vlan-header=always-strip default-vlan-id=400 ``` - Setting `vlan-mode=secure` ensures strict use of the VLAN table. - Setting `vlan-header=always-strip` for access ports removes the VLAN header from the frame when it leaves the switch chip. - Setting `vlan-header=add-if-missing` for trunk port adds VLAN header to untagged frames. - `default-vlan-id` specifies what VLAN ID is added for untagged ingress traffic of the access port. :::warning On **QCA8337** and **Atheros8327** switch chips, a default `vlan-header=leave-as-is` property should be used. The switch chip will determine which ports are access ports by using the `default-vlan-id` property. The `default-vlan-id` should only be used on access/hybrid ports to specify which VLAN the untagged ingress traffic is assigned to. ::: ### VLAN Example 2 (Trunk and Hybrid Ports) VLAN Hybrid ports can forward both tagged and untagged traffic. This configuration is supported only by some Gigabit switch chips (**QCA8337, Atheros8327**). ![Hybrid Ports](./img/switch-chip-features-05.webp) Switch together the required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether3 hw=yes add bridge=bridge1 interface=ether4 hw=yes add bridge=bridge1 interface=ether5 hw=yes ``` :::warning By default, the bridge interface is configured with `protocol-mode` set to `rstp`. For some devices, this can disable hardware offloading because specific switch chips do not support this feature. See the [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) section with supported features. ::: Add VLAN table entries to allow frames with specific VLAN IDs between ports. ```ros /interface/ethernet/switch/vlan add ports=ether2,ether3,ether4,ether5 switch=switch1 vlan-id=200 add ports=ether2,ether3,ether4,ether5 switch=switch1 vlan-id=300 add ports=ether2,ether3,ether4,ether5 switch=switch1 vlan-id=400 ``` In the switch port menu set `vlan-mode` on all ports and also `default-vlan-id` on planned hybrid ports: ```ros /interface/ethernet/switch/port set ether2 vlan-mode=secure vlan-header=leave-as-is set ether3 vlan-mode=secure vlan-header=leave-as-is default-vlan-id=200 set ether4 vlan-mode=secure vlan-header=leave-as-is default-vlan-id=300 set ether5 vlan-mode=secure vlan-header=leave-as-is default-vlan-id=400 ``` - `vlan-mode=secure` will ensure strict use of the VLAN table. - `default-vlan-id` will define VLAN for untagged ingress traffic on the port. - In QCA8337 and Atheros8327 chips when `vlan-mode=secure` is used, it ignores switch port `vlan-header` options. VLAN table entries handle all the egress tagging/untagging and work as `vlan-header=leave-as-is` on all ports. It means what comes in tagged, goes out tagged as well, only `default-vlan-id` frames are untagged at the egress port. ### Management access configuration In these examples, there will be shown examples for multiple scenarios, but each of these scenarios requires you to have switched ports. Below you can find how to switch multiple ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add interface=ether1 bridge=bridge1 hw=yes add interface=ether2 bridge=bridge1 hw=yes ``` :::warning By default, the bridge interface is configured with `protocol-mode` set to `rstp`. For some devices, this can disable hardware offloading because specific switch chips do not support this feature. See the [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) section with supported features. ::: In these examples, it will be assumed that **ether1** is the trunk port and **ether2** is the access port, for configuration as follows: ```ros /interface/ethernet/switch/port set ether1 vlan-header=add-if-missing set ether2 default-vlan-id=100 vlan-header=always-strip /interface/ethernet/switch/vlan add ports=ether1,ether2,switch1-cpu switch=switch1 vlan-id=100 ``` #### Tagged To make the device accessible only from a certain VLAN, you need to create a new VLAN interface on the bridge interface and assign an IP address to it: ```ros /interface/vlan add name=MGMT vlan-id=99 interface=bridge1 /ip/address add address=192.168.99.1/24 interface=MGMT ``` Specify from which interfaces it is allowed to access the device: ```ros /interface/ethernet/switch/vlan add ports=ether1,switch1-cpu switch=switch1 vlan-id=99 ``` :::warning Only specify trunk ports in this VLAN table entry. It is not possible to allow access to the CPU with tagged traffic through an access port since the access port will tag all ingress traffic with the specified `default-vlan-id` value. ::: When the VLAN table is configured, you can enable `vlan-mode=secure` to limit access to the CPU: ```ros /interface/ethernet/switch/port set ether1 vlan-header=add-if-missing vlan-mode=secure set ether2 default-vlan-id=100 vlan-header=always-strip vlan-mode=secure set switch1-cpu vlan-header=leave-as-is vlan-mode=secure ``` #### Untagged To make the device accessible from the access port, create a VLAN interface with the same VLAN ID as set in `default-vlan-id`, for example, VLAN 100, and add an IP address to it: ```ros /interface/vlan add name=VLAN100 vlan-id=100 interface=bridge1 /ip/address add address=192.168.100.1/24 interface=VLAN100 ``` Specify which access (untagged) ports are allowed to access the CPU: ```ros /interface/ethernet/switch/vlan add ports=ether1,ether2,switch1-cpu switch=switch1 vlan-id=100 ``` :::danger Most commonly an access (untagged) port is accompanied by a trunk (tagged) port. In case of untagged access to the CPU, you are forced to specify both the access port and the trunk port. This gives access to the CPU from the trunk port as well. This is not always desired and a Firewall might be required on top of VLAN filtering. ::: When the VLAN table is configured, you can enable `vlan-mode=secure` to limit access to the CPU: ```ros /interface/ethernet/switch/port set ether1 vlan-header=add-if-missing vlan-mode=secure set ether2 default-vlan-id=100 vlan-header=always-strip vlan-mode=secure set switch1-cpu vlan-header=leave-as-is vlan-mode=secure ``` :::warning To set up the management port using untagged traffic on a device with the **Atheros7240** switch chip, you will need to set `vlan-header=add-if-missing` for the CPU port. ::: #### Untagged from tagged port It is possible to allow access to the device from the trunk (tagged) port with untagged traffic. To do so, assign an IP address to the bridge interface: ```ros /ip/address add address=10.0.0.1/24 interface=bridge1 ``` Specify which ports are allowed to access the CPU. Use the `vlan-id` that is used in `default-vlan-id` for switch-cpu and trunk ports, by default it is set to 0 or 1. ```ros /interface/ethernet/switch/vlan add ports=ether1,switch1-cpu switch=switch1 vlan-id=1 ``` When the VLAN table is configured, you can enable `vlan-mode=secure` to limit access to the CPU: ```ros /interface/ethernet/switch/port set ether1 default-vlan-id=1 vlan-header=add-if-missing vlan-mode=secure set switch1-cpu default-vlan-id=1 vlan-header=leave-as-is vlan-mode=secure ``` :::warning This configuration example is not possible for devices with the **Atheros8316** and **Atheros7240** switch chips. For devices with **QCA8337** and **Atheros8327** switch chips, it is possible to use any other `default-vlan-id` as long as it stays the same on switch-cpu and trunk ports. For devices with **Atheros8227** switch chip, only `default-vlan-id=0` can be used and the trunk port must use `vlan-header=leave-as-is`. ::: ### Inter-VLAN routing Many MikroTik devices come with a built-in switch chip that can be used to greatly improve overall throughput when configured properly. Devices with a switch chip can be used as a router and a switch at the same time. This gives you the possibility to use a single device instead of multiple devices for your network. ![Switch Router](./img/switch-chip-features-06.webp) For this type of setup to work, you must switch all required ports together ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether3 hw=yes ``` Create a VLAN interface for each VLAN ID and assign an IP address to it: ```ros /interface/vlan add interface=bridge1 name=VLAN10 vlan-id=10 add interface=bridge1 name=VLAN20 vlan-id=20 /ip/address add address=192.168.10.1/24 interface=VLAN10 add address=192.168.20.1/24 interface=VLAN20 ``` Setup a DHCP Server for each VLAN: ```ros /ip/pool add name=POOL10 ranges=192.168.10.100-192.168.10.200 add name=POOL20 ranges=192.168.20.100-192.168.20.200 /ip/dhcp-server add address-pool=POOL10 disabled=no interface=VLAN10 name=DHCP10 add address-pool=POOL20 disabled=no interface=VLAN20 name=DHCP20 /ip/dhcp-server/network add address=192.168.10.0/24 dns-server=8.8.8.8 gateway=192.168.10.1 add address=192.168.20.0/24 dns-server=8.8.8.8 gateway=192.168.20.1 ``` Enable NAT on the device: ```ros /ip/firewall/nat add action=masquerade chain=srcnat out-interface=ether1 ``` Add each port to the VLAN table and allow these ports to access the CPU to make DHCP and routing work: ```ros /interface/ethernet/switch/vlan add independent-learning=yes ports=ether2,switch1-cpu switch=switch1 vlan-id=10 add independent-learning=yes ports=ether3,switch1-cpu switch=switch1 vlan-id=20 ``` Specify each port to be an access port, and enable secure VLAN mode on each port and on the switch1-cpu port: ```ros /interface/ethernet/switch/port set ether2 default-vlan-id=10 vlan-header=always-strip vlan-mode=secure set ether3 default-vlan-id=20 vlan-header=always-strip vlan-mode=secure set switch1-cpu vlan-mode=secure ``` :::warning On **QCA8337** and **Atheros8327** switch chips, a default `vlan-header=leave-as-is` property should be used. The switch chip will determine which ports are access ports by using the `default-vlan-id` property. The `default-vlan-id` should only be used on access/hybrid ports to specify which VLAN the untagged ingress traffic is assigned to. ::: If your device has a switch rule table, then you can limit access between VLANs on a hardware level. As soon as you add an IP address on the VLAN interface, you enable inter-VLAN routing, but this can be limited on a hardware level while preserving DHCP Server and other router-related services. To do so, use these ACL rules. With this type of configuration, you can achieve isolated port groups using VLANs. ```ros /interface/ethernet/switch/rule add dst-address=192.168.20.0/24 new-dst-ports="" ports=ether2 switch=switch1 add dst-address=192.168.10.0/24 new-dst-ports="" ports=ether3 switch=switch1 ``` ## See also - [Switch Router](./switch-chip-features.md#inter-vlan-routing) - [Basic VLAN Switching](./user-guides/basic-vlan-switching.md) - [Bridge Hardware Offloading](index.md#bridge-hardware-offloading) - [Spanning Tree Protocol](./user-guides/spanning-tree-protocol.md) - [DHCP Snooping and Option 82](index.md#dhcp-snooping-and-dhcp-option-82) - [MTU on RouterBOARD](../hardware/mtu-in-routeros.md) - [Layer2 misconfiguration](./user-guides/layer2-misconfiguration.md) --- ## CRS3xx and CSS3xx Series Manual ## Summary SwOS is an operating system designed specifically for the administration of MikroTik switch products. It provides fundamental managed switch functionalities alongside advanced features such as port-to-port forwarding, broadcast storm control, MAC/IP/port filtering via ACL rules, VLAN configuration, traffic mirroring, and bandwidth limitation. SwOS is managed exclusively through a web browser (HTTP) over IPv4. Console access, SSH, API, or other management interfaces are not supported. --- ## Connecting to the Switch Open a web browser and enter the default management IP address. ![Swos login css326](./img/crs3-01.webp) * **Default IP Address**: `192.168.88.1` * **Default Username**: `admin` * **Default Password**: *(blank)* --- ## System Tab The System tab manages general configuration parameters, device discovery options, and administrative security. ![Swos system css326](./img/crs3-02.webp) ### System Management Settings | Property | Description | | :--- | :--- | | **Address Acquisition** | Defines IP assignment via static settings, DHCP with fallback, or DHCP only. | | **Static IP Address** | Specifies the static IPv4 address for management access. | | **Identity** | Sets a customizable name for the switch identifier. | | **Allow From** | Restricts management web access to specified IP ranges or subnets. | | **Allow From Ports** | Limits web access to designated physical switch interfaces. | | **Allow From VLAN** | Restricts access to a specific incoming VLAN ID profile. | ![SwOS Management](./img/crs3-03.webp) ### DHCP & PPPoE Snooping SwOS features built-in security mechanics to block unauthorized or rogue DHCP servers and PPPoE discovery sequences on specified untrusted interfaces. ![CSS326 DHCP Snooping](./img/crs3-04.webp) ### Configuration Security and Maintenance The lower section handles backups and administrative passwords. ![Swos system3 css326](./img/crs3-05.webp) * **Change Password**: Updates the device access keys. * **Backup Configuration**: Saves current settings to a local file. * **Restore Configuration**: Uploads and applies existing configuration states. --- ## Link Tab The Link tab configures physical link parameters and monitors active connection properties for each interface. ![Swos link css326](./img/crs3-06.webp) * **Link Profiles**: Manage interface states, toggle speed/duplex auto-negotiation, and control flow control pause frames. --- ## PoE Tab *(Available on devices supporting Power over Ethernet distribution features)* ![SwOS PoE](./img/crs3-07.webp) * Supports configuring power delivery settings (`auto`, `on`, `off`) and establishing port prioritization during power constraint events. --- ## SFP Tab Provides visual diagnostics for connected SFP/SFP+ optical transceivers. ![Swos sfp1 css326](./img/crs3-08.webp) * Monitors internal diagnostics such as operating temperatures, laser supply voltages, TX/RX power levels, and hardware serialization strings. --- ## Forwarding and Port Isolation Manages Layer 2 packet-forwarding tables across the switching architecture. ![Swos forw css326](./img/crs3-09.webp) ![Swos ivl system](./img/crs3-10.webp) ### Port Isolation and Isolated Groups Port isolation splits broadcast domains internally, controlling client communications without adding subnet layers. ![SwOS Isolated Groups](./img/crs3-11.webp) ![SwO isolation example3](./img/crs3-12.webp) --- ## LAG (Link Aggregation) Bundles physical interfaces into single high-throughput channels using either dynamic LACP links or static arrays. ![Swos lag css326](./img/crs3-13.webp) --- ## RSTP (Rapid Spanning Tree Protocol) Provides loop avoidance architectures and structural redundancy parameters. ![Swos rstp css326](./img/crs3-14.webp) * Supports configuring custom bridge path costs utilizing classic short or modern long path evaluation structures. --- ## VLAN & VLANs Matrix Configuration VLAN routing rules split ingress packet sorting behavior from egress formatting tables. ### VLAN Tab (Ingress Control) Handles port behaviors for incoming traffic streams. ![Swos vlan css326](./img/crs3-15.webp) * **VLAN Modes**: Configures entry constraints across `disabled`, `optional`, `enabled`, and `strict` modes. ![Swos strict vlans](./img/crs3-16.webp) * **Default VLAN ID**: Sets the Port VLAN ID (PVID) assigned to incoming untagged traffic. ![Default vlan id](./img/crs3-17.webp) ### VLANs Tab (Egress Mapping) Defines broadcast memberships and handling across target trunk ports. ![Swos vlans css326](./img/crs3-18.webp) ![Swos vlans menu](./img/crs3-19.webp) #### Traditional Mode Templates * **Access Interfaces**: Pairs standard untagged endpoints to specific target VLAN tags. ![Access ports](./img/crs3-20.webp) * **Trunk and Hybrid Options**: Blends multiple tagged streams with optional untagged native routing paths across primary core uplinks. ![Hybrid ports](./img/crs3-21.webp) ![Swos hybrid](./img/crs3-22.webp) ![Swos hybrid vlan](./img/crs3-23.webp) --- ## Private VLANs Enforces secure structural port communication profiles across shared infrastructure spaces. ![SwOS Private VLAN](./img/crs3-24.webp) --- ## Hosts Tab Exposes the active hardware Forwarding Database (FDB) dynamic entries discovered via incoming source addresses. ![Swos shost css326](./img/crs3-25.webp) --- ## IGMP Snooping Filters multicast distributions, tracking active group subscriptions to block multicast flooding. ![IGMP snooping](./img/crs3-26.webp) ![CSSxx IGMP](./img/crs3-27.webp) ![IGMP vlantab](./img/crs3-28.webp) --- ## SNMP Tab Enables monitoring via standard SNMP structures. ![Swos snmp2 1](./img/crs3-29.webp) --- ## ACL Tab (Access Control Lists) Executes hardware-offloaded filtering rules matching patterns across L2/L3/L4 frame headers to drop or redirect packets. ![CRS326 ACL table](./img/crs3-30.webp) --- ## Diagnostics: Stats, Errors, and Histograms Tracks interface counters, dropped frames, error patterns, and detailed structural link history diagnostics. ![Swos stat1 css326](./img/crs3-31.webp) ![Swos stat2 css326](./img/crs3-32.webp) ![Swos stat3 css326](./img/crs3-33.webp) --- ## Health Tab Monitors hardware operating environments, tracking system core temperatures and operating input voltages. ![SwOS CRS328 health](./img/crs3-34.webp) --- ## Dual Boot Operation Many CRS hardware units support a dual-boot design, allowing toggle operations between running RouterOS or SwOS. ![Router board settings](./img/crs3-35.webp) ![Router board settings webfig](./img/crs3-36.webp) ![Dual boot option](./img/crs3-37.webp) Swapping operating systems toward SwOS using the RouterOS CLI interface utilizes the following system command structure: ```bash /system routerboard settings set boot-os=swos ``` ## Reset and Reinstall It is possible to reset SwOS configuration using the "Reset Configuration" button in the System menu. In case SwOS web management is not available, the configuration can still be reset using other options. The CSS326-24G-2S+ and CSS318-16G-2S+IN devices have built-in backup SwOS firmware which can be loaded in case standard firmware breaks or upgrade fails: * Holding Reset button for few seconds while CSS326-24G-2S+ and CSS318-16G-2S+IN is booting resets configuration and loads backup firmware. * After loading backup firmware, it is possible to connect to 192.168.88.1 (or leased address from a DHCP server) using web browser and install new SwOS firmware. The Dual Boot devices can boot RouterOS using a reset button. Power the device while holding the reset button and wait till user LED starts flashing (around 5 seconds). This will reset the RouterOS configuration and the device will now boot into RouterOS. After device is accessible by RouterOS, it is possible to upgrade and reset SwOS configuration. See the article - Configuring SwOS using RouterOS. CRS3xx devices with a serial console have additional options. To change between RouterOS and SwOS follow these steps: 1. Connect to the device using a serial console 2. Enter RouterBOOT setup 3. Choose "j - boot os" 4. Choose either RouterOS or SwOS It is possible to load a SwOS backup firmware in case standard firmware breaks or upgrade fails: 1. Connect to the device using a serial console 2. Boot SwOS 3. Choose "p - boot primary SwOS" 4. After loading backup firmware, it is possible to connect to 192.168.88.1 (or leased address from a DHCP server) using a web browser and install new SwOS firmware. To reset SwOS configuration: 1. Connect to the device using a serial console 2. Boot SwOS 3. Choose "r - reset configuration" ![Swos reset](./img/crs3-38.webp) --- ## CSS106 (RB260) series Manual ## Features | Features | Description | | --- | --- | | **Forwarding** | Full non-blocking wirespeed switchingUp to 2k MAC entries in the Host tableForwarding Database works based on SVL or IVLPort IsolationPort LockJumbo frame support - 9198 bytes | | **Spanning Tree Protocol** | RSTP support | | **Multicast Forwarding** | IGMP Snooping support | | **Mirroring** | Port-based mirroring | | **VLAN** | Fully compatible with IEEE802.Port-based VLANVLAN filtering | | **Quality of Service (QoS)** | Ingress traffic limiting (by ACL)Egress traffic limiting | | **Access Control List** | Ingress ACL tablesUp to 32 ACL rules (limited by SwOS)Classification based on ports, L2, L3, L4 protocol header fieldsACL actions include filtering, forwarding, and modifying the protocol header fields | --- ## Connecting to the switch Open your web browser and enter the IP address of your switch (192.168.88.1 by default) and a login screen will appear. The switch can also run a DHCP client, see if a different IP address has been assigned by the DHCP server. ![Swos login css106](./img/css106-01.webp) SwOS default IP address: **192.168.88.1**, user name: **admin** and there is no password. [MikroTik Neighbor Discovery](../../system-information-and-utilities/neighbor-discovery) can be used to discover the IP address of the Mikrotik switch. LLDP is not supported. --- ## Interface Overview SwOS interface menu consists of several tabs: Link, SFP, Forwarding, RST, Statistics, Errors, VLAN, VLANs, Hosts, IGMP Groups, SNMP, ACL, System and Upgrade. Description of buttons in SwOS configuration tool: - **Append** - add a new item to the end of the list - **Apply All** - applies current configuration changes - **Cut** - removes an item from the list - **Clear** - reset properties of the item - **Discard Changes** - removes unsaved configuration - **Insert** - add a new item to the list (places it before current item) - **Sort** - sort VLAN table by VLAN-IDs; sort host table by MAC addresses - **Change Password** - changes the password of the switch - **Logout** - logout from the current switch - **Reboot** - reboot the switch - **Reset Configuration** - reset configuration back to factory defaults - **Choose File** - browse for upgrade or backup file - **Upgrade** - upgrade the firmware of the switch using the selected file - **Download & Upgrade** - automatically try to download and upgrade the firmware, the PC which is running a web browser should be able to access the Internet - **Restore Backup** - restore switch using a selected backup file - **Save Backup** - generate and download backup file from the switch > **Note:** Each RouterBOARD switch series have their own firmware which cannot be installed on other series models! CSS106-5G-1S (RB260GS) and CSS106-1G-4P-1S (RB260GSP) supports SwOS v2.0 and newer. When upgrading the device, it will first load primary firmware and then make an upgrade. In case a wrong firmware file is chosen, the device will continue to operate with primary firmware and you will be able to choose the correct file. --- ## System System Tab performs the following functions: - General information about switch - Switch management - Configuration reset - Backup and restore configuration > **Note:** SwOS uses a simple algorithm to ensure TCP/IP communication - it just replies to the same IP and MAC address packet came from. This way there is no need for Default Gateway on the device itself. ![Swos system1](./img/css106-02.webp) | Property | Description | | --- | --- | | **Address Acquisition** | Specify which address acquisition method to use:`DHCP with fallback` - switch is trying to request an IPv4 address from a DHCP server. If the requests are unsuccessful, then the switch can be accessed using a **Static IP Address** value`static` - address is set as a **Static IP Address** value (IPv4 only)`DHCP only` - switch uses DHCPv4 client to acquire address | | **Static IP Address** | IP address of the switch in case of **Address Acquisition** is set as `DHCP with fallback` or `static` | | **Identity** | Name of the switch (for Mikrotik neighbor discovery protocol) | | **Allow From** | IP address or network from which the switch is accessible. Default value is `0.0.0.0/0` - any address. | | **Allow From Ports** | List of switch ports from which the service is accessible | | **Allow From VLAN** | VLAN ID from which the service is accessible. Make sure to first configure VLANs and VLAN pages | | **Watchdog** | Enable or disable system watchdog. It will reset CPU of the switch in case of fault condition | | **Independent VLAN Lookup** | Enable or disable independent VLAN lookup in the Host table for packet forwarding | | **IGMP Snooping** | Enable or disable IGMP Snooping | | **IGMP Fast Leave** | Enables or disables IGMP fast leave feature on the switch port. This property only has an effect when IGMP Snooping is enabled | | **Mikrotik Discovery Protocol** | Enable or disable Mikrotik neighbor discovery protocol | | **Port1 PoE In Long Cable** | If enabled, it will turn off short detection on all PoE out ports to allow the use of longer ethernet cables. This is potentially dangerous setting and should be used with caution. (CSS106-1G-4P-1S model) | | **MAC Address** | MAC address of the switch (read-only) | | **Serial Number** | Serial number of the switch (read-only) | | **Board Name** | MikroTik model name (read-only) | | **Voltage** | Shows the input voltage measured in volts (read-only, CSS106-1G-4P-1S model) | | **Temperature** | Shows PCB temperature in celsius temperature scale (read-only, CSS106-1G-4P-1S model) | ### Password and Backup ![Swos password css106](./img/css106-03.webp) --- ## Link Link Tab allows you to: - Configure Ethernet and SFP ports - Monitor status of Ethernet and SFP ports ![Swos link css106](./img/css106-04.webp) | Property | Description | | --- | --- | | **Enabled** | Enable or disable port | | **Name** | Editable port name | | **Link Status** | Current link status (read-only) | | **Auto Negotiation** | Enable or disable auto-negotiation (some SFP modules may require it disabled in order to work) | | **Speed** | Specify speed setting of the port (requires auto-negotiation to be disabled) | | **Full Duplex** | Specify the duplex mode of the port (requires auto-negotiation to be disabled) | | **Flow control** | Enable or disable 802.3x Flow control | > **Note:** Using SFP+ 1m/3m DAC cable or S-RJ01 module, the device always shows that the link is established even if nothing is connected on another end. The switch supports Jumbo frames up to 9198 bytes. Manually decreasing the MTU settings is not supported for SwOS devices. ### PoE PoE settings change Power over Ethernet output on CSS106-1G-4P-1S port2-port5 and show PoE status and measurements. ![740px Swospoe2](./img/css106-05.webp) | Property | Description | | --- | --- | | **PoE Out** | Sets PoE out mode of the port:`off` - all detection and PoE out is turned off`auto` - detection is done regarding resistance on the spare pairs to check if the port has PoE capability. For a port to be turned on measured value should be within a range from 3kΩ to 26.5kΩ`on` - PoE out is enabled regardless of the resistance on the port. ***Use this with caution as that can damage connected equipment!***`calibr` - manual port PoE out recalibration. It may be necessary if there are occasional problems with powering connected devices. | | **PoE Priority** | Port priority for PoE out supply. If the installation is going over available power budget, the port with the lowest priority is going to be turned off first. `1` - the highest priority port; `4` - the lowest priority port | | **PoE Status** | Current PoE out status of the port:`disabled` - PoE out is turned off`waiting for load` - `auto` mode detects out of range resistance to turn on PoE out`powered on` - PoE out is turned on`short circuit` - if it is detected, PoE out is turned off to ensure that there is no additional damage on the powered device and no damage on powering device`voltage too low` - not enough voltage supplied to turn on the device with PoE out`current too low` - not enough current supplied to turn on the device with PoE out`waiting for cable disconnect` - manual recalibration with `calibr` has detected connected device and waits for disconnection to complete the recalibration process | | **PoE Current** | Shows current usage on the port measured in milliamperes | | **PoE Power** | Shows PoE out power on the port measured in watts | --- ## SFP The SFP tab allows you to monitor the status of SFP modules. ![Swos sfp css106](./img/css106-06.webp) --- ## Forwarding Forwarding Tab provides advanced forwarding options among switch ports, port isolation, port locking, port mirroring and egress bandwidth limit features. Ingress rate per port and rate for broadcast traffic can be configured with [Access Control List](#acl) by setting `Rate`. ACL must have one port per entry to provide bandwidth limiting properly. ![740px Swos forwarding2](./img/css106-07.webp) | Property | Description | | --- | --- | | **Forwarding** | Forwarding table - allows or restricts traffic flow between specific ports | | **Port Lock** | `Port Lock` - Enables or disables MAC address learning on this port. When the option is enabled, it will restrict MAC address learning and static MAC addresses should be configured`Lock On First` - enable or disable MAC address learning on this port (MAC address from the first received packet will still be learned) | | **Port Mirroring** | `Mirror Ingress` - whether traffic entering this port must be copied and forwarded to the mirroring target port`Mirror Egress` - whether traffic leaving this port must be copied and forwarded to the mirroring target port`Mirror To` - mirroring target port | | **Bandwidth Limit** | `Egress Rate` - limit traffic leaving this port (bps) | --- ## RSTP Per-port and global RSTP configuration and monitoring are available in the RSTP menu. ![Swos RSTP css106](./img/css106-08.webp) | Property | Description | | --- | --- | | **RSTP** | Enable or disable STP/RSTP functionality on this port | | **Mode** | Shows STP/RSTP functionality mode on a specific port (read-only):`RSTP``STP` | | **Role** | Shows specific port role (read-only):`root` - port that is facing towards the root bridge and will be used to forward traffic from/to the root bridge`alternate` - port that is facing towards root bridge, but is not going to forward traffic (a backup for root port)`backup` - port that is facing away from the root bridge, but is not going to forward traffic (a backup for non-root port)`designated` - port that is facing away from the root bridge and is going to forward traffic`disabled` - port that is not strictly part of STP (RSTP functionality is disabled) | | **Root Path Cost** | Shows root path cost for ports that are facing root bridge (read-only) | | **Type** | `edge` - ports that are not supposed to receive any BPDUs, should be connected to end station (read-only)`point-to-point` - ports that operate in full-duplex links, can be part of STP and operate in forwarding state (read-only) | | **State** | Shows each port state (read-only):`forwarding` - port participates in traffic forwarding and is learning MAC addresses, is receiving BPDUs`discarding` - port does not participate in traffic forwarding and is not learning MAC addresses, is receiving BPDU`learning` - port does not participate in traffic forwarding, but is learning MAC addresses | | **Bridge Priority (hex)** | RSTP bridge priority for Root Bridge selection | | **Port Cost Mode** | There are two methods for automatically detecting RSTP port cost depending on link speed.`short`: 10G - 2; 1G - 4; 100M - 10; 10M - 100`long`: 10G - 2000; 1G - 20000; 100M - 200000; 10M - 2000000 | | **Forward Reserved Multicast** | Whether to forward IEEE reserved multicast MAC address that are in the **01:80:C2:00:00:0x** range. Switches compliant with R/M/STP standards should refrain from forwarding these packets.If you enable this setting, SwOS will forward reserved multicast MAC packets and disable RSTP:- the switch will not process incoming BPDUs (Bridge Protocol Data Units)- it will also not send its own BPDUs- Bridge Priority and per-port RSTP configuration settings will no longer have any effect.Enabling forwarding of reserved MAC addresses may affect certain protocols relying on these addresses. It is advisable to enable forwarding only when absolutely necessary, such as in transparent bridging setups (e.g., extending long links, using bridge as media converters, or conducting network analysis).Notable MAC addresses and protocol examples (used by RouterOS):`01:80:C2:00:00:00` - Spanning Tree Protocol (STP)`01:80:C2:00:00:01` - Ethernet Flow Control`01:80:C2:00:00:02` - Link Aggregation Control Protocol (LACP)`01:80:C2:00:00:03` - Dot1x client and server`01:80:C2:00:00:08` - Spanning Tree Protocol (for 802.1ad bridges, using `ether-type=0x88a8`)`01:80:C2:00:00:0D` - Multiple VLAN Registration Protocol (for 802.1ad bridges, using `ether-type=0x88a8`)`01:80:C2:00:00:0E` - Link Layer Discovery Protocol, Multi-chassis Link Aggregation Group and Precision Time ProtocolThe Flow Control MAC address `01:80:C2:00:00:01` is an exception — it does not get forwarded by SwOS. | | **Root Bridge** | The priority and MAC address of the selected Root Bridge in the network (read-only) | --- ## Statistics, Errors Provides detailed information about received and transmitted packets. ![Swos stats css106](./img/css106-09.webp) ![Swos error css106](./img/css106-10.webp) --- ## VLAN and VLANs VLAN configuration for switch ports. ![740px Swos vlan2](./img/css106-11.webp) | Property | Description | | --- | --- | | **VLAN Mode** | VLAN mode for ingress port:`disabled` - VLAN table is not used; switch ignores VLAN tag part of tagged packets`optional` - Handle packets with VLAN tag ID that is not present in VLAN table just like packets without VLAN tag`enabled` - Drop packets with VLAN tag ID that is not present in VLAN table. Packets without VLAN tag are treated as tagged packets with `Default VLAN ID``strict` - Same as `enabled`, but also checks VLAN support for inbound interface (drop packets with VLAN tag ID and ingress port that are not present in VLAN table) | | **VLAN Receive** | Defines the type of allowed packets on ingress port:`any` - allows tagged and untagged packets on a certain port`only tagged` - allows only packets with a VLAN tag`only untagged` - allows only packets without a VLAN tag | | **Default VLAN ID** | The switch will treat both untagged and "Default VLAN ID" tagged ingress packets as they are tagged with this VLAN ID. It is also used to untag egress traffic if the packet's VLAN ID matches "Default VLAN ID". The VLAN tag itself will only be added if there is `VLAN Header = add if missing` specified on the egress port | | **Force VLAN ID** | Whether to apply `Default VLAN ID` to incoming packets with VLAN tag | | **VLAN Header** | `leave as is` - if VLAN header is present it remains unchanged`always strip` - if VLAN header is present it is removed from the packet`add if missing` - if VLAN header is not present it is added to the packet (VLAN ID will be `Default VLAN ID` of ingress port) | > **Note:** CSS106 devices running SwOS version 2.12 can filter RSTP BPDU packets when enabling VLAN filtering on ports (VLAN Mode **enabled** or **strict**). With SwOS version 2.13, it is recommended to set VLAN Receive to **any** on trunk ports. > **Note:** VLAN modes `enabled` and `strict` require VLAN ID 1 in the VLANs table to allow access of untagged traffic to the switch itself. VLAN table specifies forwarding rules for packets that have an IEEE 802.1Q tag. Basically, the table contains entries that map specific VLAN tag IDs to a group of one or more ports. Packets with VLAN tags leave the switch through one or more ports that are set in the corresponding table entry. VLAN table works together with destination MAC lookup to determine egress ports. VLAN table supports up to 250 entries. ![Swos vlan css106](./img/css106-12.webp) | Property | Description | | --- | --- | | **VLAN ID** | VLAN ID of the packet | | **IVL** | Enables or disables independent VLAN learning (IVL) | | **IGMP Snooping** | Enables or disables IGMP Snooping on the defined VLAN. When enabled, the switch will listen to IGMP Join and Leave requests from the defined VLAN and only forward traffic to ports which have sent IGMP membership requests from the defined VLAN. When disabled, the switch will flood all VLAN member ports with Multicast traffic. | | **Ports** | Each port has individual *VLAN header* options for each VLAN ID. Depending on *VLAN mode*, if lookup is done in this table, the egress action of packets is processed by this option. The egress option from the **VLAN tab** is ignored. | ### VLAN Configuration Examples #### Trunk and Access Ports ![Access ports small](./img/css106-13.webp) 1. In the System menu enable independent VLAN learning (IVL). ![Css106 ivl](./img/css106-14.webp) 1. In the VLANs menu add VLAN entries, specify port membership, and enable IVL. The default "leave as is" port setting can be used; the tagging and untagging behavior can be changed with the "Default VLAN ID" setting, see the next step. ![Css access trunk vlans](./img/css106-15.webp) 1. In the VLAN menu configure Default VLAN ID on planned access ports (untagged), select the correct VLAN Receive setting (Port2 only tagged, Port3-5 only untagged), and enable strict VLAN filtering to ensure only allowed VLANs can pass through the ports. ![Css106 access vlan](./img/css106-16.webp) > **Note:** CSS106 devices running SwOS version 2.12 can filter RSTP BPDU packets when enabling VLAN filtering on ports (VLAN Mode **enabled** or **strict**). With SwOS version 2.13, it is recommended to set VLAN Receive to **any** on trunk ports. #### Trunk and Hybrid Ports ![Hybrid ports small](./img/css106-17.webp) 1. In the System menu enable independent VLAN learning (IVL). ![Css106 ivl 1](./img/css106-18.webp) 1. In the VLANs menu add VLAN entries, specify port membership, and enable IVL. The default "leave as is" port setting can be used; the tagging and untagging behavior can be changed with the "Default VLAN ID" setting, see the next step. ![Css hybrid vlan](./img/css106-19.webp) 1. In the VLAN menu configure Default VLAN ID on planned hybrid ports (for untagged VLAN), select the correct VLAN Receive setting (Port2 only tagged, Port3-5 any), and enable strict VLAN filtering to ensure only allowed VLANs can pass through the ports. ![Css hybrid vlans](./img/css106-20.webp) > **Note:** CSS106 devices running SwOS version 2.12 can filter RSTP BPDU packets when enabling VLAN filtering on ports (VLAN Mode **enabled** or **strict**). With SwOS version 2.13, it is recommended to set VLAN Receive to **any** on trunk ports. #### Management Access In this example, switch management access on VLAN 200 will be created. The configuration scheme is the same as "**Trunk and Access Ports**" and steps **1., 2., 3.** are identical. The additional **4th** step requires specifying the management VLAN ID in the System menu. After applying the configuration, the switch will only respond to tagged VLAN 200 packets on Port2 and untagged packets on Port3. The DHCP client will also work in the specified VLAN ID. ![Css106 system vlan](./img/css106-21.webp) > **Warning:** Changing management VLAN can completely disable access to the switch management if VLAN settings are not correctly configured. Save a configuration backup before changing this setting and use [Reset](#reset) in case management access is lost. --- ## Hosts This table represents dynamically learned MAC address to port mapping entries. It can contain two kinds of entries: dynamic and static. Dynamic entries get added automatically — this is also called a learning process: when a switch receives a packet from a certain port, it adds the packet's source MAC address X and port it received the packet from to the host table, so when a packet comes in with destination MAC address X it knows to which port it should forward the packet. If the destination MAC address is not present in the host table then it forwards the packet to all ports in the group (flood). Dynamic entries take about 5 minutes to time out. CSS106 series switches support 2048 host table entries. ![Swos hosts css106](./img/css106-22.webp) | Property | Description | | --- | --- | | **Port** | Ports the packet should be forwarded to (read-only) | | **MAC** | Learned MAC address (read-only) | | **VLAN ID** | Learned VLAN ID (read-only) | ### Static Hosts Static entries will take over dynamic entries if a dynamic entry with the same MAC address already exists. Adding a static entry also provides access to additional functionality. ![740px Swos static2](./img/css106-23.webp) | Property | Description | | --- | --- | | **Ports** | Ports the packet should be forwarded to | | **MAC** | MAC address | | **VLAN ID** | VLAN ID | | **Drop** | Packet with certain MAC address coming from certain ports can be dropped | | **Mirror** | Packet can be cloned and sent to mirror-target port | --- ## IGMP Groups IGMP Snooping which controls multicast streams and prevents multicast flooding is implemented in SwOS starting from version 2.5. The feature allows a switch to listen in the IGMP conversation between hosts and routers. First, enable the option under the System tab. ![Swos igmp2 css106](./img/css106-24.webp) Available IGMP snooping data can be found under the IGMP Group tab. ![Swos igmp css106](./img/css106-25.webp) Possibility to enable or disable IGMP Snooping for a specific VLAN ID. ![Swos igmp3 css106](./img/css106-26.webp) --- ## SNMP SwOS supports SNMP v1 and v2c (the Response for GetRequest, GetNextRequest and GetBulkRequest) and uses IF-MIB, SNMPv2-MIB, BRIDGE-MIB and MIKROTIK-MIB (only for health, PoE-out and SFP diagnostics). SNMP traps and writing SwOS configuration are not supported. Available SNMP data: - System information - System uptime - Port status - Interface statistics - Host table information ![Swos snmp2](./img/css106-27.webp) | Property | Description | | --- | --- | | **Enabled** | Enable or disable SNMP service | | **Community** | SNMP community name | | **Contact Info** | Contact information for the NMS | | **Location** | Location information for the NMS | --- ## ACL An access control list (ACL) rule table is a very powerful tool allowing wire-speed packet filtering, forwarding, and VLAN tagging based on L2, L3, and L4 protocol header field conditions. SwOS allows you to implement a limited number of access control list rules (32 simple rules where only L2 conditions are used; 16 rules where both L2 and L3 conditions are used; or 8 advanced rules where all L2, L3, and L4 conditions are used). Each rule contains a conditions part and an action part. ![740px Swos acl2](./img/css106-28.webp) **Conditions parameters** | Property | Description | | --- | --- | | **From** | The port that the packet came in from | | **MAC Src** | Source MAC address and mask | | **MAC Dst** | Destination MAC address and mask | | **Ethertype** | Protocol encapsulated in the payload of an Ethernet Frame | | **VLAN** | VLAN header presence: `any` / `present` / `not present` | | **VLAN ID** | VLAN tag ID | | **Priority** | Priority in VLAN tag | | **IP Src** (IP/netmask:port) | Source IPv4 address, netmask, and L4 port number | | **IP Dst** (IP/netmask:port) | Destination IPv4 address, netmask, and L4 port number | | **Protocol** | IP protocol | | **DSCP** | IP DSCP field | **Action parameters** | Property | Description | | --- | --- | | **Redirect To** | Whether to force new destination ports (if "Redirect To" is enabled and no ports are specified in "Redirect To Ports", a packet will be dropped) | | **Redirect To Ports** | Redirect destination ports | | **Mirror** | Clones packet and sends it to mirror-target port | | **Rate** | Limits bandwidth (bps) | | **Set VLAN ID** | Changes the VLAN tag ID, if VLAN tag is present | | **Priority** | Changes the VLAN tag priority bits, if VLAN tag is present | --- ## Reset The CSS106-5G-1S and CSS106-1G-4P-1S have built-in backup SwOS firmware which can be loaded in case standard firmware breaks or upgrade fails: - Holding the Reset button for a few seconds while the device is booting will reset the configuration and load backup firmware. - After loading backup firmware, it is possible to connect to 192.168.88.1 (or a leased address from a DHCP server) using a web browser and install new SwOS firmware. --- ## CSS610 series Manual ## Summary SwOS Lite is an operating system designed specifically for the administration of MikroTik CSS610 series switch products. CSS610 series switches support only SwOS Lite operating system. The main differences compared to CSS3xx series switches are: - unsupported Independent VLAN Learning - unsupported VLAN mode "enabled" - unsupported ACL Rate limiting - supported Port Egress Rate limiting --- ## CSS610 series Features | Features | Description | | --- | --- | | **Forwarding** | Full non-blocking wirespeed switchingUp to 16k MAC entries in the Host tableForwarding Database works based only on SVLPort IsolationJumbo frame support - 10218 bytes | | **Spanning Tree Protocol** | RSTP support | | **Link Aggregation** | Supports 802.3ad LACP groupsSupports static link aggregation groupsUp to 16 link aggregation groupsUp to 8 member ports per a groupHardware automatic failover and load balancing | | **Multicast Forwarding** | IGMP Snooping supportUnknown Multicast Filtering | | **Mirroring** | Port-based mirroring | | **VLAN** | Fully compatible with IEEE802.1QPort-based VLANUp to 250 VLAN entries (limited by SwOS)VLAN filtering | | **Security** | Port LockBroadcast Storm ControlDHCP & PPPoE Snooping | | **Quality of Service (QoS)** | Ingress traffic limitingEgress traffic limiting | | **Access Control List** | Ingress ACL tablesUp to 32 ACL rules (limited by SwOS)Classification based on ports, L2, L3, L4 protocol header fieldsACL actions include filtering, forwarding, and modifying the protocol header fields | --- ## Connecting to the Switch Open your web browser and enter the IP address of your switch (192.168.88.1 by default) and a login screen will appear. The switch can also run a DHCP client, see if a different IP address has been assigned by the DHCP server. ![Swos login css610](./img/css610-01.webp) SwOS default IP address: **192.168.88.1**, user name: **admin** and there is no password. [MikroTik Neighbor Discovery](../../system-information-and-utilities/neighbor-discovery) can be used to discover the IP address of the Mikrotik switch. LLDP is not supported. --- ## Interface Overview SwOS interface menu consists of multiple tabs depending on the device model. These are all possible SwOS menus: Link, PoE, SFP, Port Isolation, LAG, Forwarding, RSTP, Stats, Errors, Hist, VLAN, VLANs, Hosts, IGMP, SNMP, ACL, System, Health and Upgrade. Description of buttons in SwOS configuration tool: - **Append** - add a new item to the end of the list - **Apply All** - applies current configuration changes - **Cut** - removes an item from the list - **Clear** - reset properties of the item - **Discard Changes** - removes unsaved configuration - **Insert** - add a new item to the list (places it before current item) - **Sort** - sort VLAN table by VLAN-IDs; sort host table by MAC addresses - **Change Password** - changes the password of the switch - **Logout** - logout from the current switch - **Reboot** - reboot the switch - **Reset Configuration** - reset configuration back to factory defaults - **Choose File** - browse for upgrade or backup file - **Upgrade** - upgrade the firmware of the switch using the selected file - **Download & Upgrade** - automatically try to download and upgrade the firmware, the PC which is running a web browser should be able to access the Internet - **Restore Backup** - restore switch using a selected backup file - **Save Backup** - generate and download the backup file from the switch > **Note:** Each RouterBoard switch series device has its own firmware which cannot be installed on other series models! > > - CSS610-1Gi-7R-2S+ supports SwOS Lite v2.12 and newer. > - CSS610-8G-2S+ supports SwOS Lite v2.12 and newer. > - CSS610-8P-2S+IN supports SwOS Lite v2.15 and newer. --- ## System System Tab performs the following functions: - General information about switch - Switch management - Configuration reset - Backup and restore configuration > **Note:** SwOS uses a simple algorithm to ensure TCP/IP communication - it just replies to the same IP and MAC address packet came from. This way there is no need for Default Gateway on the device itself. ![Swos system css610](./img/css610-02.webp) | Property | Description | | --- | --- | | **Address Acquisition** | Specify which address acquisition method to use:`DHCP with fallback` - switch is trying to request an IPv4 address from a DHCP server. If the requests are unsuccessful, then the switch can be accessed using a **Static IP Address** value`static` - address is set as a **Static IP Address** value (IPv4 only)`DHCP only` - switch uses DHCPv4 client to acquire address | | **Static IP Address** | IP address of the switch in case of **Address Acquisition** is set as `DHCP with fallback` or `static` | | **Identity** | Name of the switch (for Mikrotik Neighbor Discovery protocol) | | **Allow From** | IP address from which the switch is accessible. Default value is `0.0.0.0/0` - any address | | **Allow From Ports** | List of switch ports from which it is accessible | | **Allow From VLAN** | VLAN ID from which the service is accessible. Make sure to first configure VLANs and VLAN pages | | **Watchdog** | Enable or disable system Watchdog. It will reset CPU of the switch in case of fault condition | | **IGMP Snooping** | Enable or disable IGMP Snooping | | **IGMP Querier** | Enables or disables IGMP querier on the switch. Only applies when IGMP Snooping is enabled | | **IGMP Fast Leave** | Enables or disables IGMP fast leave feature per switch port | | **IGMP Version** | Changes IGMP version for switch querier. Only applies when IGMP Querier is enabled | | **Mikrotik Discovery Protocol** | Enable or disable Mikrotik Neighbor Discovery protocol | | **MAC Address** | MAC address of the switch (read-only) | | **Serial Number** | Serial number of the switch (read-only) | | **Board Name** | MikroTik model name of the switch (read-only) | | **Uptime** | Current switch uptime (read-only) | | **PoE Out Mode** | Specifies PoE-Out state (CSS610-1Gi-7R-2S+ model only):`auto-on` - the board will attempt to detect if power can be applied to the port. For power-on to happen there should be resistance on spare pairs in the range from 3kΩ to 26.5kΩ`forced-on` - detection range is removed. As a result power over Ethernet will be always on`off` - all detection and power is turned off for this port | | **PoE Out Status** | Shows current PoE-Out status on port (read-only, CSS610-1Gi-7R-2S+ model only) | ### Health ![Swos lite health](./img/css610-03.webp) | Property | Description | | --- | --- | | **Temperature** | Shows CPU temperature in celsius temperature scale (read-only) | | **PSU** | Shows PSU voltage and consumed milliamperes by PoE-out connected devices (read-only, CSS610-8P-2S+IN model only) | | **Power Consumption** | Shows PSU power consumption by PoE-out connected devices (read-only, CSS610-8P-2S+IN model only) | ### DHCP & PPPoE Snooping ![CSS610 DHCP Snooping](./img/css610-04.webp) | Property | Description | | --- | --- | | **Trusted Ports** | Group of ports which allows DHCP or PPPoE servers to provide requested information. When enabled, it allows forwarding DHCP client packets towards the DHCP server through this port. Mainly used to limit unauthorized servers from providing malicious information for users; access ports usually are not configured as trusted. Ports that receive DHCP client packets with already added Option-82 must also be trusted, otherwise these packets are dropped. The setting does not apply to DHCPv6 packets. | | **Add Information Option** | Enables or disables DHCP Option-82 information. When enabled, the Option-82 information (Agent Remote ID and Circuit ID) is added for DHCP packets received from untrusted ports. Can be used together with an Option-82 capable DHCP server to assign IP addresses and implement policies. The setting does not apply to DHCPv6 packets.For Agent Remote ID, SwOS uses the interface name where DHCP client resides. For Agent Circuit ID, SwOS uses the identity of the SwOS device, internally used port ID and VLAN ID. For example:Agent Remote ID - `Port1`Agent Circuit ID - `MikroTik eth 0/1:100` | ### Password and Backup ![Swos system3 css326](./img/css610-05.webp) --- ## Link Link Tab allows you to configure each interface settings and monitor the link status. ![Css610 link](./img/css610-06.webp) | Property | Description | | --- | --- | | **Enabled** | Enable or disable port | | **Name** | Editable port name | | **Link Status** | Current link status (read-only) | | **Auto Negotiation** | Enable or disable auto-negotiation | | **Speed** | Specify speed setting of the port (requires auto-negotiation to be disabled) | | **Full Duplex** | Specify the duplex mode of the port (requires auto-negotiation to be disabled) | | **Flow control Tx/Rx** | Enable or disable 802.3x Flow control | | **Hops** | Shows the number of GPER repeaters in the link | | **Last Hop** | Shows the number of the last GPER repeater if the link is terminated | | **Length** | Shows the length of the cable in meters if the link is terminated | | **Fault At** | Shows the distance in meters to the failure point if the cable is damaged but the link is active | | **Cable Pairs** | Shows four positions of the cable pairs with their status: `O` - open; `S` - short; `P` - reverse polarity | The switch supports Jumbo frames up to 10218 bytes. Manually decreasing the MTU settings is not supported for SwOS Lite devices. --- ## PoE Devices with PoE-out support have some configuration options and certain monitoring features, like PoE-out current, voltage, etc. For a more detailed description, see [PoE-Out manual](https://help.mikrotik.com/docs/display/ROS/PoE-Out). ![SwOS PoE](./img/css610-07.webp) --- ## SFP SFP tab allows you to monitor the status of SFP/SFP+ modules. ![Swos sfp1 css326](./img/css610-08.webp) --- ## Port Isolation The Port Isolation table allows or restricts traffic forwarding between specific ports. By default, all available switch chip ports can communicate with any other port — there is no isolation used. When the checkbox is enabled/ticked you allow traffic to forward from this port towards the ticked port. Below are some port isolation examples. ![SwOS Isolated Groups](./img/css610-09.webp) In some scenarios, you might need to isolate a group of devices from other groups. In this example devices on **Port1-Port5** are not able to communicate with **Port6-Port10** devices, and vice versa. ![SwOS Private VLAN](./img/css610-10.webp) In some scenarios, you might need to forward all traffic to an uplink port while all other ports are isolated from each other. This kind of setup is called a **Private VLAN** configuration. The switch will forward all Ethernet frames only to the uplink **Port1**, while the uplink can reach all other ports. ![SwO isolation example3](./img/css610-11.webp) Individual isolated **Port1** (e.g. for management purpose) — it cannot send or receive traffic from any other port. > **Note:** It is possible to check/uncheck multiple checkboxes by checking one of them and then dragging horizontally (Click & Drag). > **Note:** (R)STP will only work properly in Private VLAN setups. In setups with multiple isolated switch groups, (R)STP might not properly receive BPDUs and therefore fail to detect network loops. --- ## LAG IEEE 802.3ad (LACP) compatible link aggregation is supported, as well as static link aggregation to ensure failover and load balancing based only on Layer2 hashing. Up to 16 link aggregation groups with up to 8 ports per group are supported. Each individual port can be configured as Passive LACP, Active LACP, or a Static LAG port. | Property | Description | | --- | --- | | **Mode** *(default: passive)* | Specify LACP packet exchange mode or Static LAG mode on ports:`Passive` - place port in listening state, use LACP only when its contrary port uses active LACP mode`Active` - prefer to start LACP regardless of contrary port mode`Static` - set port in a Static LAG mode; requires setting the same **Group** setting for all ports that need to be included in the same static LAG | | **Group** | Specify a Static LAG group | | **Trunk** *(read-only)* | Represents group number the port belongs to | | **Partner** *(read-only)* | Represents partner MAC address; only available when ports are included in LACP | --- ## Forwarding Forwarding Tab provides advanced forwarding options among switch ports, port locking, port mirroring, bandwidth limit, and broadcast storm control features. ![Swos forw css610](./img/css610-12.webp) | Property | Description | | --- | --- | | **Port Lock** | `Port Lock` - Enables or disables MAC address learning on this port. When the option is enabled, it will restrict MAC address learning and static MAC addresses should be configured. Any received frames with unknown source MAC address will be dropped`Lock On First` - Allows learning of the source MAC address from the first received frame; this property should be used together with `Port Lock`. Learning of the first MAC address will reset every time an interface status changes | | **Port Mirroring** | `Mirror Ingress` - Whether traffic entering this port must be copied and forwarded to the mirroring target port`Mirror Egress` - Whether traffic leaving this port must be copied and forwarded to the mirroring target port`Mirror To` - Mirroring target port | | **Broadcast Storm Control** | `Storm Rate` - Limit the number of broadcast packets transmitted by an interface. The rate is measured in bits per second (bps)`Include Unknown Unicast` - Include unicast packets without an entry in the host table in `Storm Rate` limitation | | **Multicast Flood Control** | `Flood Unknown Multicast` - Changes the multicast flood option on a switch port; only controls egress traffic. When enabled, the bridge allows flooding multicast packets to the specified switch port; when disabled, it restricts multicast traffic from being flooded. The setting affects all multicast traffic, including non-IP, IPv4, IPv6 and the link-local multicast ranges (e.g. 224.0.0.0/24 and ff02::1) | | **Bandwidth Limit** | `Ingress Rate` - Limit traffic entering this port (bps)`Egress Rate` - Limit traffic leaving this port (bps) | > **Note:** It is possible to limit ingress/egress traffic per port basis. The policer is used for ingress traffic, the shaper is used for egress traffic. The ingress policer controls the received traffic with packet drops — everything that exceeds the defined limit will get dropped. This can affect the TCP congestion control mechanism on end hosts and achieved bandwidth can be actually less than defined. The egress shaper tries to queue packets that exceed the limit instead of dropping them. Eventually, it will also drop packets when the output queue gets full; however, it should allow utilizing the defined throughput better. --- ## RSTP Per-port and global RSTP configuration and monitoring are available in the RSTP menu. ![Swos rstp css326](./img/css610-13.webp) | Property | Description | | --- | --- | | **Bridge Priority (hex)** | RSTP bridge priority for Root Bridge selection | | **Port Cost Mode** | There are two methods for automatically detecting RSTP port cost depending on link speed.`short`: 40G - 1; 10G - 2; 1G - 4; 100M - 10; 10M - 100`long`: 40G - 500; 10G - 2000; 1G - 20000; 100M - 200000; 10M - 2000000 | | **Forward Reserved Multicast** | Whether to forward IEEE reserved multicast MAC address that are in the **01:80:C2:00:00:0x** range. Switches compliant with R/M/STP standards should refrain from forwarding these packets.If you enable this setting, SwOS will forward reserved multicast MAC packets and disable RSTP:- the switch will not process incoming BPDUs (Bridge Protocol Data Units)- it will also not send its own BPDUs- Bridge Priority and per-port RSTP configuration settings will no longer have any effect.Enabling forwarding of reserved MAC addresses may affect certain protocols relying on these addresses. It is advisable to enable forwarding only when absolutely necessary, such as in transparent bridging setups (e.g., extending long links, using bridge as media converters, or conducting network analysis).Notable MAC addresses and protocol examples (used by RouterOS):`01:80:C2:00:00:00` - Spanning Tree Protocol (STP)`01:80:C2:00:00:01` - Ethernet Flow Control`01:80:C2:00:00:02` - Link Aggregation Control Protocol (LACP)`01:80:C2:00:00:03` - Dot1x client and server`01:80:C2:00:00:08` - Spanning Tree Protocol (for 802.1ad bridges, using `ether-type=0x88a8`)`01:80:C2:00:00:0D` - Multiple VLAN Registration Protocol (for 802.1ad bridges, using `ether-type=0x88a8`)`01:80:C2:00:00:0E` - Link Layer Discovery Protocol, Multi-chassis Link Aggregation Group and Precision Time ProtocolThe Flow Control MAC address `01:80:C2:00:00:01` is an exception — it does not get forwarded by SwOS. | | **Root Bridge** | The priority and MAC address of the selected Root Bridge in the network (read-only) | | **RSTP** | Enable or disable STP/RSTP functionality on this port | | **Mode** | Shows STP/RSTP functionality mode on a specific port (read-only):`RSTP``STP` | | **Role** | Shows specific port role (read-only):`root` - port that is facing towards the root bridge and will be used to forward traffic from/to the root bridge`alternate` - port that is facing towards root bridge, but is not going to forward traffic (a backup for root port)`backup` - port that is facing away from the root bridge, but is not going to forward traffic (a backup for non-root port)`designated` - port that is facing away from the root bridge and is going to forward traffic`disabled` - port that is not strictly part of STP (RSTP functionality is disabled) | | **Root Path Cost** | Shows root path cost for ports that are facing root bridge (read-only) | | **Type** | `edge` - ports that are not supposed to receive any BPDUs, should be connected to the end station (read-only)`point-to-point` - ports that operate in full-duplex links, can be part of STP and operate in a forwarding state (read-only) | | **State** | Shows each port state (read-only):`forwarding` - port participates in traffic forwarding and is learning MAC addresses, is receiving BPDUs`discarding` - port does not participate in traffic forwarding and is not learning MAC addresses, is receiving BPDU`learning` - port does not participate in traffic forwarding but is learning MAC addresses | --- ## Stats, Errors and Histogram These menus provide detailed information about received and transmitted packets. ![Swos stat1 css326](./img/css610-14.webp) ![Swos stat2 css326](./img/css610-15.webp) ![Swos stat3 css326](./img/css610-16.webp) > **Note:** Statistics for SFP+ interface are cleared whenever an active SFP+ link is established. --- ## VLAN and VLANs VLAN configuration for switch ports. ![Swos vlan css610](./img/css610-17.webp) | Property | Description | | --- | --- | | **VLAN Mode** (*disabled \| optional \| strict*; Default: **optional**) | VLAN filtering mode; these options are relevant to egress ports (except for strict mode).`disabled` - VLAN table is not used. The switch discards packets with a VLAN tag on egress ports. If the packet has a VLAN tag and the VLAN ID matches `Default VLAN ID` on egress ports, then with `VLAN Receive=any` the switch will remove the VLAN tag and forward the packet.`optional` - Disabled VLAN filtering. Handle packets with VLAN tag ID that is not present in the VLAN table just like packets without VLAN tag.`strict` - Enabled VLAN filtering with additional ingress filtering, which checks if the ingress port is a member of the received VLAN ID in the VLAN table. Received packets on the ingress port with a VLAN ID that does not match the VLAN table will be dropped. Default VLAN ID must be specified for access ports since it will be used to tag ingress traffic and untag egress traffic for a certain port. | | **VLAN Receive** (*any \| only tagged \| only untagged*; Default: **optional**) | Received traffic filtering based on VLAN tag presence.`any` - allows tagged and untagged packets on a certain port`only tagged` - allows only packets with a VLAN tag. The "Default VLAN ID" will not work, because it only applies for untagged traffic`only untagged` - allows only packets without a VLAN tag | | **Default VLAN ID** (*integer: 1..4095*; Default: **1**) | The switch will place received untagged packets in the "Default VLAN ID" VLAN. Only has an effect on untagged traffic, and when **VLAN Receive** is set to "any" or "only untagged". It does not apply for tagged traffic. This parameter is usually used to allocate access ports with a specific VLAN. It is also used to untag egress traffic if the packet's VLAN ID matches Default VLAN ID. | | **Force VLAN ID** (*yes \| no*; Default: **no**) | Assigns the `Default VLAN ID` value to all ingress traffic (tagged and untagged). Has effect in all VLAN Modes. If the port receives tagged traffic and `Default VLAN ID` is set to 1, then with this parameter the egress traffic will be untagged. | VLAN membership configuration for switch ports. ![Swos vlans css610](./img/css610-18.webp) | Property | Description | | --- | --- | | **VLAN ID** (*integer: 1..4095*; Default: **0**) | VLAN ID to which assign ports | | **IGMP Snooping** (*yes \| no*; Default: **no**) | Enables or disables IGMP Snooping on the defined VLAN. When enabled, the switch will listen to IGMP Join and Leave requests from the defined VLAN and only forward traffic to ports which have sent IGMP membership requests from the defined VLAN. When disabled, the switch will flood all VLAN member ports with Multicast traffic. | | **Members** (*ports*; Default: **none**) | Group of ports which are allowed to forward traffic on the defined VLAN | ### VLAN Configuration Examples #### Trunk and Access Ports ![Access ports](./img/css610-19.webp) 1. In the VLANs menu add VLAN entries and specify port membership. ![Css610 vlans](./img/css610-20.webp) 1. In the VLAN menu configure Default VLAN ID on planned access ports (untagged), select the correct VLAN Receive setting (Port2 only tagged, Port6-8 only untagged) and enable strict VLAN filtering to ensure only allowed VLANs can pass through the ports. ![Css610 vlan](./img/css610-21.webp) #### Trunk and Hybrid Ports ![Hybrid ports](./img/css610-22.webp) 1. In the VLANs menu add VLAN entries and specify port membership. ![Css610 vlans hybrid](./img/css610-23.webp) 1. In the VLAN menu configure Default VLAN ID on planned hybrid ports (for untagged VLAN), select the correct VLAN Receive setting (Port2 only tagged, Port6-8 any) and enable strict VLAN filtering to ensure only allowed VLANs can pass through the ports. ![Css610 vlan hybrid](./img/css610-24.webp) #### Management Access In this example, switch management access on VLAN 200 will be created. The configuration scheme is the same as "**Trunk and Access Ports**" and steps **1., 2.** are identical. The additional **3rd** step requires specifying the management VLAN ID in the System menu. After applying the configuration, the switch will only respond to tagged VLAN 200 packets on Port2 and untagged packets on Port6. The DHCP client will also work in the specified VLAN ID. ![Css610 system vlan](./img/css610-25.webp) > **Warning:** Changing management VLAN can completely disable access to the switch management if VLAN settings are not correctly configured. Save a configuration backup before changing this setting and use [Reset and Reinstall](#reset-and-reinstall) in case management access is lost. --- ## Hosts This table represents dynamically learned MAC address to port mapping entries. It can contain two kinds of entries: dynamic and static. Dynamic entries get added automatically — this is also called a learning process: when a switch receives a packet from a certain port, it adds the packet's source MAC address and port it received the packet from to the host table, so when a packet comes in with a certain destination MAC address it knows to which port it should forward the packet. If the destination MAC address is not present in the host table then it forwards the packet to all ports in the group. Dynamic entries take about 5 minutes to time out. Static entries will take over dynamic entries if a dynamic entry with the same MAC address already exists. Adding a static entry also provides access to more functionality. ![Swos shost css610](./img/css610-26.webp) **Static host properties** | Property | Description | | --- | --- | | **Ports** | Ports the packet should be forwarded to | | **MAC** | MAC address | **Dynamic host properties (read-only)** | Property | Description | | --- | --- | | **Port** | Ports the packet should be forwarded to | | **MAC** | Learned MAC address | --- ## IGMP Snooping IGMP Snooping controls multicast streams and prevents multicast flooding. The feature allows a switch to listen in the IGMP conversation between hosts and routers. Enable this option under the System tab. ![Css610 igmp snooping](./img/css610-27.webp) Available IGMP snooping data can be found under the IGMP tab. ![CSSxx IGMP](./img/css610-28.webp) It is possible to enable IGMP Snooping for a specific VLAN ID under the VLANs menu. ![Css610 igmp vlantab](./img/css610-29.webp) --- ## SNMP SwOS supports SNMP v1 and v2c (the Response for GetRequest, GetNextRequest and GetBulkRequest) and uses IF-MIB, SNMPv2-MIB, BRIDGE-MIB and MIKROTIK-MIB (only for health, PoE-out and SFP diagnostics). SNMP traps and writing SwOS configuration are not supported. Available SNMP data: - System information - System uptime - Port status - Interface statistics - Host table information ![Swos snmp2 1](./img/css610-30.webp) | Property | Description | | --- | --- | | **Enabled** | Enable or disable SNMP service | | **Community** | SNMP community name | | **Contact Info** | Contact information for the NMS | | **Location** | Location information for the NMS | --- ## ACL and ACL Stats Tabs An access control list (ACL) rule table is a very powerful tool allowing wire-speed packet filtering, forwarding, and VLAN tagging based on L2, L3, and L4 protocol header field conditions. Each rule contains a conditions part and an action part. ![CSS610 ACL table](./img/css610-31.webp) **Conditions part parameters** | Property | Description | | --- | --- | | **From** | A port that the packet came in from | | **MAC Src** | Source MAC address and mask | | **MAC Dst** | Destination MAC address and mask | | **Ethertype** | Protocol encapsulated in the payload of an Ethernet Frame | | **VLAN** | VLAN header presence: `any` / `present` / `not present` | | **VLAN ID** | VLAN tag ID | | **Priority** | Priority in VLAN tag | | **IP Src** (IP/netmask:port) | Source IPv4 address, netmask, and L4 port number | | **IP Dst** (IP/netmask:port) | Destination IPv4 address, netmask, and L4 port number | | **Protocol** *(integer)* | IP protocol | | **DSCP** | IP DSCP field | **Action part parameters** | Property | Description | | --- | --- | | **Account as** | Select the counter where matched packets will be counted | | **Redirect To** | Force new packets destination port | | **Mirror** | Clones packet and sends it to mirror-target port | | **Drop** | Drop packet | | **Set VLAN ID** | Changes the VLAN tag ID, if VLAN tag is present | | **Priority** | Changes the VLAN tag priority bits, if VLAN tag is present | | **DSCP** | Changes the IP DSCP field | Each ACL rule can be assigned to a specific counter where matched packets will be counted. ![Css610 acl stats](./img/css610-32.webp) --- ## Reset and Reinstall The CSS610 have built-in backup SwOS firmware which can be loaded in case standard firmware breaks or upgrade fails: - Holding the Reset button for a few seconds while the device is booting will reset the configuration and load backup firmware. - After loading backup firmware, it is possible to connect to 192.168.88.1 (or a leased address from a DHCP server) using a web browser and install new SwOS firmware. --- ## GPEN21 series Manual ## Summary The GPEN21 is a smart power injector that serves as an advanced software-controlled repeater. Not only can it power your uplink devices via PoE, but it can also provide a range of useful software features. GPEN21 has an Ethernet and SFP port for fiber connectivity. Customers can choose to use GPEN21 to power an optical module for uplink to the provider, or to provide PoE to power Ethernet uplink to the provider (that uses our GPeR and/or netPower products). The GPEN21 unit can be securely attached to a wall or the communications cabinet. The Ethernet cable can be routed either directly through its bottom cable opening or into the wall, as preferred. SwOS Lite is an operating system designed specifically for the administration of MikroTik GPEN21 products. GPEN21 supports only the SwOS Lite operating system. --- ## GPEN21 Series Features | Features | Description | | --- | --- | | **Forwarding** | Full non-blocking wirespeed switchingUp to 2k MAC entries in the Host table ¹Forwarding Database works based only on SVLJumbo frame support - 10222 bytes | | **Monitoring** | SNMPLink fault detectionSFP diagnosticsInterface statistics | | **VLAN** | Fully compatible with IEEE802.1QPort-based VLANUp to 250 VLAN entries (limited by SwOS)VLAN filtering | | **Security** | Port LockBroadcast Storm Control | | **Quality of Service (QoS)** | Ingress traffic limitingEgress traffic limiting | | **Access Control List** | Ingress ACL tablesUp to 32 ACL rules (limited by SwOS)Classification based on ports, L2, L3, L4 protocol header fieldsACL actions include filtering, forwarding, and modifying the protocol header fields | ¹ The Host table limit does not affect forwarding because packets are sent from upstream to downstream ports and vice versa even when the MAC learning limit is reached. --- ## Connecting to the Device Open your web browser and enter the IP address of your device (192.168.88.1 by default) and a login screen will appear. The device can also run a DHCP client, see if a different IP address has been assigned by the DHCP server. ![Gpen21 login](./img/gpen21-01.webp) SwOS default IP address: **192.168.88.1**, user name: **admin** and there is no password. [MikroTik Neighbor Discovery](../../system-information-and-utilities/neighbor-discovery) can be used to discover the IP address of the Mikrotik switch. LLDP is not supported. --- ## Interface Overview SwOS interface menu consists of multiple tabs depending on the device model. These are all possible SwOS menus: Link, SFP, Forwarding, Stats, Errors, Hist, VLAN, VLANs, Hosts, SNMP, ACL, System, and Upgrade. Description of buttons in SwOS configuration tool: - **Append** - add a new item to the end of the list - **Apply All** - applies current configuration changes - **Cut** - removes an item from the list - **Clear** - reset properties of the item - **Discard Changes** - removes unsaved configuration - **Insert** - add a new item to the list (places it before current item) - **Sort** - sort VLAN table by VLAN-IDs; sort host table by MAC addresses - **Change Password** - changes the password of the device - **Logout** - logout from the current device - **Reboot** - reboot the device - **Reset Configuration** - reset configuration back to factory defaults - **Choose File** - browse for upgrade or backup file - **Upgrade** - upgrade the firmware of the device using the selected file - **Download & Upgrade** - automatically try to download and upgrade the firmware, the PC which is running a web browser should be able to access the Internet - **Restore Backup** - restore device using a selected backup file - **Save Backup** - generate and download the backup file from the device > **Note:** Each device has its own firmware which cannot be installed on other series models! > > - GPEN21 supports SwOS Lite v2.13 and newer. --- ## System System Tab performs the following functions: - General information about the device - Device management - Configuration reset - Backup and restore configuration > **Note:** SwOS uses a simple algorithm to ensure TCP/IP communication - it just replies to the same IP and MAC address packet came from. This way there is no need for Default Gateway on the device itself. ![Gpen21 system](./img/gpen21-02.webp) | Property | Description | | --- | --- | | **Address Acquisition** | Specify which address acquisition method to use:`DHCP with fallback` - device is trying to request an IPv4 address from a DHCP server. If the requests are unsuccessful, then the device can be accessed using a **Static IP Address** value`static` - address is set as a **Static IP Address** value (IPv4 only)`DHCP only` - device uses DHCPv4 client to acquire address | | **Static IP Address** | IP address of the device in case of **Address Acquisition** is set as `DHCP with fallback` or `static` | | **Identity** | Name of the device (for Mikrotik Neighbor Discovery protocol) | | **Allow From** | IP address from which the device is accessible. Default value is `0.0.0.0/0` - any address | | **Allow From Ports** | List of device ports from which it is accessible | | **Allow From VLAN** | VLAN ID from which the service is accessible. Make sure to first configure VLANs and VLAN pages | | **Watchdog** | Enable or disable system Watchdog. It will reset the CPU of the device in case of a fault condition | | **Mikrotik Discovery Protocol** | Enable or disable Mikrotik Neighbor Discovery protocol | | **Dark Mode** | Disable or enable all LEDs on the device | | **MAC Address** | MAC address of the device (read-only) | | **Serial Number** | Serial number of the device (read-only) | | **Board Name** | MikroTik model name of the device (read-only) | | **Uptime** | Current device uptime (read-only) | | **PoE Out Mode** | Specifies PoE-Out state:`auto-on` - the board will attempt to detect if power can be applied to the port. For power-on to happen there should be resistance on spare pairs in the range from 3kΩ to 26.5kΩ`forced-on` - detection range is removed. As a result power over Ethernet will be always on`off` - all detection and power is turned off for this port | | **PoE Out Status** | Shows current PoE-Out status on port (read-only) | ### Password and Backup ![Swos system3 css326](./img/gpen21-03.webp) --- ## Link Link Tab allows you to configure each interface settings and monitor the link status. ![Gpen21 link](./img/gpen21-04.webp) | Property | Description | | --- | --- | | **Enabled** | Enable or disable port | | **Name** | Editable port name | | **Link Status** | Current link status (read-only) | | **Auto Negotiation** | Enable or disable auto-negotiation | | **Speed** | Shows the negotiated speed, or allows manually changing the speed setting of the port (requires auto-negotiation to be disabled) | | **Full Duplex** | Shows the negotiated duplex, or allows manually changing the duplex mode of the port (requires auto-negotiation to be disabled) | | **Hops** | Shows the number of GPER repeaters in the link | | **Last Hop** | Shows the number of the last GPER repeater if the link is terminated | | **Length** | Shows the length of the cable in meters if the link is terminated | | **Fault At** | Shows the distance in meters to the failure point if the cable is damaged but the link is active | | **Cable Pairs** | Shows four positions of the cable pairs with their status: `O` - open; `S` - short; `P` - reverse polarity | The device supports Jumbo frames up to 10222 bytes. Manually decreasing the MTU settings is not supported for SwOS Lite devices. --- ## SFP The SFP tab allows you to monitor the status of SFP modules. ![Gpen21 sfp](./img/gpen21-05.webp) --- ## Forwarding Forwarding Tab provides advanced forwarding options among device ports, port locking, bandwidth limit, and broadcast storm control features. ![Gpen21 forwarding](./img/gpen21-06.webp) | Property | Description | | --- | --- | | **Port Lock** | `Port Lock` - Enables or disables MAC address learning on this port. When the option is enabled, it will restrict MAC address learning and static MAC addresses should be configured. Any received frames with an unknown source MAC address will be dropped.`Lock On First` - Allows learning of the source MAC address from the first received frame; this property should be used together with `Port Lock`. Learning of the first MAC address will reset every time an interface status changes. | | **Uplink Port** | `Set As Uplink Port` - Allows changing the uplink port between PoE-in (Port1), PoE-out (Port2), or SFP interfaces. Packets received on downstream ports are forwarded only to the uplink port; only a single interface can be used as an uplink. | | **Broadcast Storm Control** | `Storm Rate` - Limit the number of broadcast packets transmitted by an interface. The rate is measured in bits per second (bps).`Limit Unknown Unicast` - Include unicast packets without an entry in the host table in `Storm Rate` limitation. | | **Bandwidth Limit** | `Ingress Rate` - Limit traffic entering this port (bps)`Egress Rate` - Limit traffic leaving this port (bps) | > **Note:** It is possible to limit ingress/egress traffic per port basis. The policer is used for ingress traffic, the shaper is used for egress traffic. The ingress policer controls the received traffic with packet drops — everything that exceeds the defined limit will get dropped. This can affect the TCP congestion control mechanism on end hosts and achieved bandwidth can be actually less than defined. The egress shaper tries to queue packets that exceed the limit instead of dropping them. Eventually, it will also drop packets when the output queue gets full; however, it should allow utilizing the defined throughput better. --- ## Stats, Errors and Histogram These menus provide detailed information about received and transmitted packets. ![Gpen21 stats](./img/gpen21-07.webp) ![Gpen21 errors](./img/gpen21-08.webp) ![Gpen21 hist](./img/gpen21-09.webp) --- ## VLAN and VLANs VLAN configuration for device ports. ![Gpen21 vlan](./img/gpen21-10.webp) | Property | Description | | --- | --- | | **VLAN Mode** (*disabled \| optional \| strict*; Default: **optional**) | VLAN filtering mode; these options are relevant to egress ports (except for strict mode).`disabled` - VLAN table is not used. The device discards packets with a VLAN tag on egress ports. If the packet has a VLAN tag and the VLAN ID matches `Default VLAN ID` on egress ports, then with `VLAN Receive=any` the device will remove the VLAN tag and forward the packet.`optional` - Disabled VLAN filtering. Handle packets with VLAN tag ID that is not present in the VLAN table just like packets without VLAN tag.`strict` - Enabled VLAN filtering with additional ingress filtering, which checks if the ingress port is a member of the received VLAN ID in the VLAN table. Received packets on the ingress port with a VLAN ID that does not match with the VLAN table will be dropped. Default VLAN ID must be specified for access ports since it will be used to tag ingress traffic and untag egress traffic for a certain port. | | **VLAN Receive** (*any \| only tagged \| only untagged*; Default: **optional**) | Received traffic filtering based on VLAN tag presence.`any` - allows tagged and untagged packets on a certain port`only tagged` - allows only packets with a VLAN tag. The "Default VLAN ID" will not work, because it only applies for untagged traffic`only untagged` - allows only packets without a VLAN tag | | **Default VLAN ID** (*integer: 1..4095*; Default: **1**) | The device will place received untagged packets in the "Default VLAN ID" VLAN. Only has an effect on untagged traffic, and when **VLAN Receive** is set to "any" or "only untagged". It does not apply for tagged traffic. This parameter is usually used to allocate access ports with a specific VLAN. It is also used to untag egress traffic if the packet's VLAN ID matches Default VLAN ID. | | **Force VLAN ID** (*yes \| no*; Default: **no**) | Assigns the `Default VLAN ID` value to all ingress traffic (tagged and untagged). Has effect in all VLAN Modes. If the port receives tagged traffic and `Default VLAN ID` is set to 1, then with this parameter the egress traffic will be untagged. | VLAN membership configuration for device ports. ![Gpen21 vlans](./img/gpen21-11.webp) | Property | Description | | --- | --- | | **VLAN ID** (*integer: 1..4094*; Default: **0**) | VLAN ID to which assign ports | | **Members** (*ports*; Default: **none**) | Group of ports which are allowed to forward traffic on the defined VLAN | ### VLAN Configuration Examples The VLAN configuration examples are taken from the [CSS610 switch user manual](https://help.mikrotik.com/docs/display/SWOS/CSS610+series+Manual#CSS610seriesManual-VLANConfigurationExample); however, the same principles can be applied to the GPEN21 device. #### Trunk and Access Ports ![Access ports](./img/gpen21-12.webp) 1. In the VLANs menu add VLAN entries and specify port membership. ![Css610 vlans](./img/gpen21-13.webp) 1. In the VLAN menu configure Default VLAN ID on planned access ports (untagged), select the correct VLAN Receive setting (Port2 only tagged, Port6-8 only untagged) and enable strict VLAN filtering to ensure only allowed VLANs can pass through the ports. ![Css610 vlan](./img/gpen21-14.webp) #### Trunk and Hybrid Ports ![Hybrid ports](./img/gpen21-15.webp) 1. In the VLANs menu add VLAN entries and specify port membership. ![Css610 vlans hybrid](./img/gpen21-16.webp) 1. In the VLAN menu configure Default VLAN ID on planned hybrid ports (for untagged VLAN), select the correct VLAN Receive setting (Port2 only tagged, Port6-8 any) and enable strict VLAN filtering to ensure only allowed VLANs can pass through the ports. ![Css610 vlan hybrid](./img/gpen21-17.webp) #### Management Access In this example, device management access on VLAN 200 will be created. The configuration scheme is the same as "**Trunk and Access Ports**" and steps **1., 2.** are identical. The additional **3rd** step requires specifying the management VLAN ID in the System menu. After applying the configuration, the device will only respond to tagged VLAN 200 packets on Port2 and untagged packets on Port6. The DHCP client will also work in the specified VLAN ID. ![Css610 system vlan](./img/gpen21-18.webp) > **Warning:** Changing management VLAN can completely disable access to the device management if VLAN settings are not correctly configured. Save a configuration backup before changing this setting and use [Reset and Reinstall](#reset-and-reinstall) in case management access is lost. --- ## Hosts This table represents dynamically learned MAC address to port mapping entries. It can contain two kinds of entries: dynamic and static. Dynamic entries get added automatically — this is also called a learning process: when a device receives a packet from a certain port, it adds the packet's source MAC address and port it received the packet from to the host table, so when a packet comes in with a certain destination MAC address it knows to which port it should forward the packet. If the destination MAC address is not present in the host table then it forwards the packet to all ports in the group. Dynamic entries take about 5 minutes to time out. Static entries will take over dynamic entries if a dynamic entry with the same MAC address already exists. Adding a static entry also provides access to more functionality. ![Gpen21 hosts](./img/gpen21-19.webp) **Static host properties** | Property | Description | | --- | --- | | **Ports** | Ports the packet should be forwarded to | | **MAC** | MAC address | **Dynamic host properties (read-only)** | Property | Description | | --- | --- | | **Port** | Ports the packet should be forwarded to | | **MAC** | Learned MAC address | --- ## SNMP SwOS supports SNMP v1 and v2c (the Response for GetRequest, GetNextRequest and GetBulkRequest) and uses IF-MIB, SNMPv2-MIB, BRIDGE-MIB and MIKROTIK-MIB (only for health, PoE-out and SFP diagnostics). SNMP traps and writing SwOS configuration are not supported. Available SNMP data: - System information - System uptime - Port status - Interface statistics - Host table information ![Swos snmp2 1](./img/gpen21-20.webp) | Property | Description | | --- | --- | | **Enabled** | Enable or disable SNMP service | | **Community** | SNMP community name | | **Contact Info** | Contact information for the NMS | | **Location** | Location information for the NMS | --- ## ACL An access control list (ACL) rule table is a very powerful tool allowing wire-speed packet filtering, forwarding, and VLAN tagging based on L2, L3, and L4 protocol header field conditions. Each rule contains a conditions part and an action part. ![Gpen21 acl](./img/gpen21-21.webp) **Conditions part parameters** | Property | Description | | --- | --- | | **From** | A port that the packet came in from | | **MAC Src** | Source MAC address and mask | | **MAC Dst** | Destination MAC address and mask | | **Ethertype** | Protocol encapsulated in the payload of an Ethernet Frame | | **VLAN** | VLAN header presence: `any` / `present` / `not present` | | **VLAN ID** | VLAN tag ID | | **Priority** | Priority in VLAN tag | | **IP Src** (IP/netmask:port) | Source IPv4 address, netmask, and L4 port number | | **IP Dst** (IP/netmask:port) | Destination IPv4 address, netmask, and L4 port number | | **Protocol** *(integer)* | IP protocol | | **DSCP** | IP DSCP field | **Action part parameters** | Property | Description | | --- | --- | | **Drop** | Drop packet | | **Set VLAN ID** | Changes the VLAN tag ID, if the VLAN tag is present | | **Priority** | Changes the VLAN tag priority bits, if the VLAN tag is present | --- ## Reset and Reinstall The GPEN21 has built-in backup SwOS firmware which can be loaded in case standard firmware breaks or an upgrade fails: - Holding the Reset button for a few seconds while the device is booting will reset the configuration and load backup firmware. The reset button is located behind the front cover. - After loading backup firmware, it is possible to connect to 192.168.88.1 (or a leased address from a DHCP server) using a web browser and install new SwOS firmware. --- ## SwOS # Introduction to SwOS SwOS is a lightweight operating system built exclusively for the administration of MikroTik switching hardware. It delivers maximum wire-speed Layer 2 forwarding capability across all standard Ethernet frames, handling IPv4, IPv6, and non-IP traffic seamlessly. ### Core & Advanced Features Beyond standard managed switch capabilities, SwOS offers a robust suite of networking features: * **VLAN Management:** Full configuration support for complex VLAN setups, including access and trunking ports. * **Traffic Control:** Advanced broadcast storm control, bandwidth limiting, and port-to-port forwarding settings. * **Monitoring & Mirroring:** Ingress/egress traffic mirroring along with real-time port-level statistics. * **Security & Filtering:** A granular Access Control List (ACL) engine capable of matching traffic by MAC, IP, and port-level rules. * **Hardware Offloading:** Direct hardware-driven manipulation of specific MAC and IP header fields on supported device models. :::note Management Limitation SwOS is configured exclusively through a standard web browser (HTTP) over IPv4. It does not support command-line interface (CLI) access via serial console/SSH, API access, WinBox, or other alternative management protocols. ::: import DocCardList from '@theme/DocCardList'; --- ## Cannot upgrade SwOS --- ## Overview MikroTik switches that support SwOS store two separate firmware images in flash memory: a **primary** (active) image and a **backup** image. Under normal operation, the device boots from the primary image. When a firmware upgrade is initiated — either automatically via the web interface or manually via file upload — the device writes the new image to the primary slot and reboots into it. Upgrade failures typically occur due to one of the following: - Incorrect firmware file selected (wrong model or firmware branch) - Interrupted write operation leaving the primary image corrupted - Network connectivity issue preventing the automatic download from reaching MikroTik servers - On dual-boot devices: device-mode policy restricting OS transitions (RouterOS 7.17+) SwOS-only devices and dual-boot devices require different recovery procedures, described separately below. --- ## Before You Begin > **Warning:** The reset button procedure described in this article will erase the active configuration and load factory defaults. Export a configuration backup from the **System** tab before proceeding. Confirm which firmware file you need before attempting a manual upgrade. Each switch series uses a dedicated firmware binary — cross-series firmware files are not interchangeable and will be rejected or cause a boot failure. The correct file for your device can be found at: [mikrotik.com Software download centre](https://mikrotik.com/download) --- ## Resolution ### SwOS-only Devices (CSS series) These devices do not run RouterOS and have no serial console boot menu. Recovery relies on the hardware backup firmware stored in a protected flash partition. **Step 1 — Attempt manual firmware upload** Navigate to the **Upgrade** tab in the SwOS web interface, select the correct `.swos` firmware file for your device model, and click **Upgrade**. Do not interrupt power during the write process. After the upload completes, the device will reboot automatically. Reload the web interface and verify the firmware version shown in the **System** tab. **Step 2 — Boot into backup firmware via hardware reset** If the manual upload fails or the device becomes unreachable after the upgrade attempt, the backup (primary) firmware can be force-loaded using the reset button: 1. Disconnect power from the device. 2. Hold the **Reset** button and reapply power. 3. Continue holding the button for approximately 5 seconds until the device completes its boot sequence. 4. Release the button. The device will load the backup firmware and apply the factory default configuration. It will be accessible at **192.168.88.1** or at a DHCP-assigned address. **Step 3 — Reattempt manual firmware upload** Once the device is accessible on the backup firmware, repeat the manual upgrade procedure from Step 1. The backup firmware environment provides a clean state from which the upgrade is more likely to succeed. --- ### Dual-Boot Devices (CRS series) Dual-boot devices store both SwOS and RouterOS and can boot into either operating system. This provides additional recovery paths, including upgrade via the RouterOS CLI. **Step 1 — Attempt manual firmware upload** As with SwOS-only devices, first attempt a manual upgrade via the **Upgrade** tab in the SwOS web interface using the correct firmware file for your device. **Step 2 — Boot into backup SwOS via serial console** If the manual upload fails, connect to the device using a serial console cable with the following parameters: | Parameter | Value | | --- | --- | | Baud rate | 115200 | | Data bits | 8 | | Stop bits | 1 | | Parity | None | | Flow control | None | At the boot menu prompt, select: ``` p - boot primary SwOS ``` This loads the factory backup SwOS image. Once the device is accessible, reattempt the manual firmware upload as described in Step 1. **Step 3 — Boot into RouterOS via reset button (no console access)** If no serial console port is available or no cable is at hand, the device can be forced into RouterOS using the reset button: 1. With the device powered on, press and hold the **Reset** button. 2. Hold until the user LED begins to flash (approximately 5 seconds). 3. Release the button. The device will reset the RouterOS configuration to factory defaults and boot into RouterOS. > **Warning:** This procedure resets the RouterOS configuration. Ensure a RouterOS configuration backup exists before proceeding if the device was previously running RouterOS. **Step 4 — Upgrade SwOS from RouterOS CLI** Once booted into RouterOS, SwOS can be upgraded directly without using the web interface. The following command fetches and installs the latest available SwOS firmware for the device: ``` /system swos upgrade ``` Internet access is required for this command to resolve and download the correct firmware package from MikroTik's update servers. Verify connectivity before executing. **Step 5 — Device-mode restriction (RouterOS 7.17 and later)** Starting with RouterOS **v7.17**, the `device-mode` policy restricts OS transitions between SwOS and RouterOS on dual-boot hardware. If the upgrade command fails or OS switching is blocked, explicitly permit the transition with: ``` /system/device-mode/update routerboard=yes ``` This command must be executed in RouterOS before re-attempting the SwOS upgrade or switching back to SwOS. **Step 6 — Return to SwOS** After the SwOS firmware has been successfully updated from RouterOS, set the default boot target back to SwOS and reboot the device: ``` /system routerboard settings set boot-os=swos /system reboot ``` The device will restart and load the newly installed SwOS firmware. --- ## Basic VLAN switching --- Many MikroTik devices come with built-in switch chips that support hardware-level VLAN switching. This enables wire-speed performance when using VLANs, provided the appropriate configuration method is employed. Since the configuration method varies across different models, this guide focuses on setting up a basic trunk/access port with a management port from the trunk port using different devices with the right configuration to achieve the best performance and to fully utilize the available hardware components. ![Basic VLAN Switching](./img/basic-vlan-switching-01.webp) ## MikroTik devices with Marvell Prestera switch and RTL8367, 88E6393X, 88E6191X, 88E6190, MT7621, MT7531 and EN7523 switch chips --- ```ros /interface/bridge add name=bridge1 frame-types=admit-only-vlan-tagged /interface/bridge/port add bridge=bridge1 interface=ether1 frame-types=admit-only-vlan-tagged add bridge=bridge1 interface=ether2 pvid=20 frame-types=admit-only-untagged-and-priority-tagged add bridge=bridge1 interface=ether3 pvid=30 frame-types=admit-only-untagged-and-priority-tagged /interface/bridge/vlan add bridge=bridge1 tagged=ether1 vlan-ids=20 add bridge=bridge1 tagged=ether1 vlan-ids=30 add bridge=bridge1 tagged=ether1,bridge1 vlan-ids=99 /interface/vlan add interface=bridge1 vlan-id=99 name=MGMT /ip/address add address=192.168.99.1/24 interface=MGMT /interface/bridge set bridge1 vlan-filtering=yes ``` More detailed examples can be found [here](../index.md#bridge-vlan-filtering). :::info RTL8367, 88E6393X, 88E6191X, 88E6190, MT7621, MT7531, and EN7523 switch chips can use hardware-offloaded VLAN filtering starting in RouterOS v7. ::: :::warning Bridge ports with `frame-types` set to `admit-all` or `admit-only-untagged-and-priority-tagged` will be automatically added as untagged ports for the `pvid` VLAN. ::: ## CRS1xx/CRS2xx series switches --- ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=ether3 /interface/ethernet/switch/ingress-vlan-translation add ports=ether2 customer-vid=0 new-customer-vid=20 add ports=ether3 customer-vid=0 new-customer-vid=30 /interface/ethernet/switch/egress-vlan-tag add tagged-ports=ether1 vlan-id=20 add tagged-ports=ether1 vlan-id=30 add tagged-ports=ether1,switch1-cpu vlan-id=99 /interface/ethernet/switch/vlan add ports=ether1,ether2 vlan-id=20 add ports=ether1,ether3 vlan-id=30 add ports=ether1,switch1-cpu vlan-id=99 /interface/vlan add interface=bridge1 vlan-id=99 name=MGMT /ip/address add address=192.168.99.1/24 interface=MGMT /interface/ethernet/switch set drop-if-invalid-or-src-port-not-member-of-vlan-on-ports=ether1,ether2,ether3 ``` More detailed examples can be found [here](./crs1xx-2xx-series-switches-examples.md#vlan). ## Other devices with a built-in switch chip --- ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=ether3 /interface/ethernet/switch/vlan add ports=ether1,ether2 switch=switch1 vlan-id=20 add ports=ether1,ether3 switch=switch1 vlan-id=30 add ports=ether1,switch1-cpu switch=switch1 vlan-id=99 /interface/vlan add interface=bridge1 vlan-id=99 name=MGMT /ip/address add address=192.168.99.1/24 interface=MGMT /interface/ethernet/switch/port set ether1 vlan-mode=secure vlan-header=add-if-missing set ether2 vlan-mode=secure vlan-header=always-strip default-vlan-id=20 set ether3 vlan-mode=secure vlan-header=always-strip default-vlan-id=30 set switch1-cpu vlan-header=leave-as-is vlan-mode=secure ``` More detailed examples can be found [here](../switch-chip-features.md#setup-examples). :::info Applicability & Scope This configuration is intended for RouterBOARD series devices (RB4xx, RB9xx, RB2011, RB3011, hAP, hEX, cAP, etc.). Not all devices with a switch chip support hardware-level VLAN switching. If a device has `VLAN table` support, it can use the built-in switch chip. Check your chip's capability using `/interface/ethernet/switch/print` or the [compatibility table](../switch-chip-features.md). ::: :::warning Hardware Limitations & Configuration Rules * **Multiple Switch Chips:** On devices with multiple chips (e.g., RB2011, RB3011, RB1100), VLAN traffic is only hardware-switched between ports on the *same* chip. Bridging ports across different chips means VLANs will not be filtered at the hardware level. To bypass this, either connect a physical cable between the chips, or use Bridge VLAN Filtering (which disables hardware offloading). * **QCA8337 & Atheros8327 Chips:** You must leave the default `vlan-header=leave-as-is` property. The switch chip uses the `default-vlan-id` property (which should only be applied to access/hybrid ports) to assign untagged ingress traffic to a VLAN. * **RSTP Conflict:** By default, bridge interfaces use `protocol-mode=rstp`. On certain devices, this disables hardware offloading. Check the [Bridge Hardware Offloading](../#bridge-hardware-offloading) section for supported features. ::: ## Other devices without a built-in switch chip --- It is possible to do VLAN filtering using the CPU; there are multiple ways to do it, but it is highly recommended to use bridge VLAN filtering. ```ros /interface/bridge add name=bridge1 frame-types=admit-only-vlan-tagged /interface/bridge/port add bridge=bridge1 interface=ether1 frame-types=admit-only-vlan-tagged add bridge=bridge1 interface=ether2 pvid=20 frame-types=admit-only-untagged-and-priority-tagged add bridge=bridge1 interface=ether3 pvid=30 frame-types=admit-only-untagged-and-priority-tagged /interface/bridge/vlan add bridge=bridge1 tagged=ether1 vlan-ids=20 add bridge=bridge1 tagged=ether1 vlan-ids=30 add bridge=bridge1 tagged=ether1,bridge1 vlan-ids=99 /interface/vlan add interface=bridge1 vlan-id=99 name=MGMT /ip/address add address=192.168.99.1/24 interface=MGMT /interface/bridge set bridge1 vlan-filtering=yes ``` More detailed examples can be found [here](../index.md#bridge-vlan-filtering). --- ## Bridge IGMP/MLD snooping --- IGMP (Internet Group Management Protocol) and MLD (Multicast Listener Discovery) snooping are bridge features that enable the bridge to passively listen to IGMP/MLD network communication and use this information to make intelligent forwarding decisions for multicast traffic. By default, bridges flood all multicast traffic to every bridge port, similar to how broadcast traffic is handled. This default behavior may not be ideal for certain applications such as multicast video streaming or SDVoE (Software Defined Video over Ethernet) deployments. IGMP/MLD snooping addresses this issue by forwarding multicast traffic only to ports where interested clients are subscribed. See the IGMP/MLD network concept diagram below. The RouterOS bridge implementation supports IGMP versions 1, 2, and 3, as well as MLD versions 1 and 2. This implementation is based on RFC4541, and the respective protocols specifications are defined in RFC1112 (IGMPv1), RFC2236 (IGMPv2), RFC3376 (IGMPv3), RFC2710 (MLDv1), and RFC3810 (MLDv2). :::warning Source-specific multicast forwarding is not supported for IGMPv3 and MLDv2. ::: ![IGMP Configuration Diagram](./img/bridge-igmp-mld-snooping-01.webp) The bridge processes IGMP/MLD messages only when `igmp-snooping` is enabled. Additionally, the bridge must have an active IPv6 address to process MLD packets. Initially, the bridge does not restrict any multicast traffic and floods all multicast packets. Once an IGMP/MLD querier is detected—by receiving an IGMP/MLD query message (either from an external multicast router or locally from the bridge interface with `multicast-querier` enabled)—the bridge begins restricting unknown IP multicast traffic and forwards only known multicast streams from the Multicast Database (MDB). IGMP and MLD querier detection operate independently; detecting an IGMP querier does not affect IPv6 multicast forwarding, and vice versa. Querier detection also does not restrict the forwarding of non-IP and link-local multicast groups, such as 224.0.0.0/24 and ff02::1. :::danger CRS3xx series devices with Marvell-98DX3236, Marvell-98DX224S, or Marvell-98DX226S switch chips cannot distinguish between non-IP, IPv4, and IPv6 multicast packets once an IGMP or MLD querier is detected. This means the switch will stop forwarding all unknown multicast traffic (regardless of protocol) when a querier is detected. This limitation does not apply to certain link-local multicast address ranges, such as 224.0.0.0/24 or ff02::1. ::: ## Configuration options --- This section describes the IGMP and MLD snooping bridge configuration options. **Sub-menu:** `/interface/bridge` | Property | Description | | :-- | :-- | | **igmp-snooping** (*yes \| no*; Default: **no**) | Enables IGMP and MLD snooping. | | **igmp-version** (*2 \| 3*; Default: **2**) | Selects the IGMP version in which IGMP membership queries will be generated when the bridge interface is acting as an IGMP querier. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | | **last-member-interval** (*time*; Default: **1s**) | When the last client on the bridge port unsubscribes from a multicast group and the bridge is acting as an active querier, the bridge will send a group-specific IGMP/MLD query, to make sure that no other client is still subscribed. The setting changes the response time for these queries. In case no membership reports are received in a certain time period (`last-member-interval` \* `last-member-query-count`), the multicast group is removed from the multicast database (MDB). If the bridge port is configured with fast-leave, the multicast group is removed right away without sending any queries. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | | **last-member-query-count** (*integer: 0..4294967295*; Default: **2**) | How many times should `last-member-interval` pass until the IGMP/MLD snooping bridge stops forwarding a certain multicast stream. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | | **membership-interval** (*time*; Default: **4m20s**) | The amount of time after an entry in the Multicast Database (MDB) is removed if no IGMP/MLD membership reports are received on a bridge port. This property only has an effect when `igmp-snooping` is set to `yes`. | | **mld-version** (*1 \| 2*; Default: **1**) | Selects the MLD version in which MLD membership queries will be generated, when the bridge interface is acting as an MLD querier. This property only has an effect when the bridge has an active IPv6 address, `igmp-snooping` and `multicast-querier` are set to `yes`. | | **multicast-querier** (*yes \| no*; Default: **no**) | Multicast querier generates periodic IGMP/MLD general membership queries to which all IGMP/MLD capable devices respond with an IGMP/MLD membership report, usually a PIM (multicast) router or IGMP proxy generates these queries. By using this property you can make an IGMP/MLD snooping enabled bridge generate IGMP/MLD general membership queries. This property should be used whenever there is no active querier (PIM router or IGMP proxy) in a Layer2 network. Without a multicast querier in a Layer2 network, the Multicast Database (MDB) is not being updated, the learned entries will timeout and IGMP/MLD snooping will not function properly. Only untagged IGMP/MLD general membership queries are generated, IGMP queries are sent with the bridge interface's own IPv4 address as the source address (see `querier-uses-bridge-address`), MLD queries are sent with IPv6 link-local address of the bridge interface. The bridge will not send queries if an external IGMP/MLD querier is detected (see the monitoring values `igmp-querier` and `mld-querier`). This property only has an effect when `igmp-snooping` is set to `yes`. | | **multicast-router** (*disabled \| permanent \| temporary-query*; Default: **temporary-query**) | A multicast router port is a port where a multicast router or querier is connected. On this port, unregistered multicast streams and IGMP/MLD membership reports will be sent. This setting changes the state of the multicast router for a bridge interface itself. This property can be used to send IGMP/MLD membership reports and multicast traffic to the bridge interface for further multicast routing or proxying. This property only has an effect when `igmp-snooping` is set to `yes`.disabled - disabled multicast router state on the bridge interface. Unregistered multicast streams and IGMP/MLD membership reports are not sent to the bridge interface regardless of what is configured on the bridge interface.permanent - enabled multicast router state on the bridge interface. Unregistered multicast streams and IGMP/MLD membership reports are sent to the bridge interface itself regardless of what is configured on the bridge interface.temporary-query - automatically detect multicast router state on the bridge interface using IGMP/MLD queries. | | **querier-interval** (*time*; Default: **4m15s**) | Changes the timeout period for detected querier and multicast-router ports. This property only has an effect when `igmp-snooping` is set to `yes`. | | **querier-uses-bridge-address** (*yes \| no*; Default: **yes**) | When enabled, the bridge IGMP querier uses the bridge interface's own IPv4 address as the source address for IGMP query packets instead of the default 0.0.0.0. Some multicast clients consider queries from 0.0.0.0 invalid and do not respond, which can lead to multicast stream interruptions when snooping table entries time out. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes` and the bridge interface has an IPv4 address assigned. This setting applies only to IPv4 (IGMP). MLD queries always use the IPv6 link-local address of the bridge interface. | | **query-interval** (*time*; Default: **2m5s**) | Changes the interval at which IGMP/MLD general membership queries are sent out when the bridge interface is acting as an IGMP/MLD querier. The interval takes effect when the last startup query is sent. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | | **query-response-interval** (*time*; Default: **10s**) | The setting changes the response time for general IGMP/MLD queries when the bridge is acting as an IGMP/MLD querier. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | | **startup-query-count** (*integer: 0..4294967295*; Default: **2**) | Specifies how many times general IGMP/MLD queries must be sent when the bridge interface is enabled or active querier times out. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | | **startup-query-interval** (*time*; Default: **31s250ms**) | Specifies the interval between startup general IGMP/MLD queries. This property only has an effect when `igmp-snooping` and `multicast-querier` are set to `yes`. | **Sub-menu:** `/interface/bridge/port` | Property | Description | | :-- | :-- | | **fast-leave** (*yes \| no*; Default: **no**) | Enables IGMP/MLD fast leave feature on the bridge port. The bridge will stop forwarding multicast traffic to a bridge port when an IGMP/MLD leave message is received. This property only has an effect when `igmp-snooping` is set to `yes`. | | **multicast-router** (*disabled \| permanent \| temporary-query*; Default: **temporary-query**) | A multicast router port is a port where a multicast router or querier is connected. On this port, unregistered multicast streams and IGMP/MLD membership reports will be sent. This setting changes the state of the multicast router for bridge ports. This property can be used to send IGMP/MLD membership reports and multicast streams to certain bridge ports for further multicast routing or proxying. This property only has an effect when `igmp-snooping` is set to `yes`.disabled - disabled multicast router state on the bridge port. Unregistered multicast streams and IGMP/MLD membership reports are not sent to the bridge port regardless of what is connected to it.permanent - enabled multicast router state on the bridge port. Unregistered multicast and IGMP/MLD membership reports are sent to the bridge port regardless of what is connected to it.temporary-query - automatically detect multicast router state on the bridge port using IGMP/MLD queries. | | **unknown-multicast-flood** (*yes \| no*; Default: **yes**) | Changes the multicast flood option on the bridge port. It only controls the egress traffic. When enabled, the bridge allows flooding multicast packets to the specified bridge port, but when disabled, the bridge restricts multicast traffic from being flooded to the specified bridge port. The setting affects all multicast traffic. This includes non-IP, IPv4, IPv6, and the link-local multicast ranges (e.g. 224.0.0.0/24 and ff02::1). Note that when `igmp-snooping` is enabled and an IGMP/MLD querier is detected, the bridge will automatically restrict unknown IP multicast from being flooded, so the setting is not mandatory for IGMP/MLD snooping setups. When using this setting together with `igmp-snooping`, the only multicast traffic that is allowed on the bridge port is the known multicast from the MDB table. | **Sub-menu:** `/interface/bridge/mdb` | Property | Description | | :-- | :-- | | **bridge** (*name*; Default: ) | The bridge interface to which the MDB entry is going to be assigned. | | **disabled** (*yes \| no*; Default: **no**) | Disables or enables the static MDB entry. | | **group** (*ipv4 \| ipv6 address*; Default: ) | The IPv4 or IPv6 multicast address. Static entries for link-local multicast groups 224.0.0.0/24 and ff02::1 cannot be created, as these packets are always flooded on all ports and VLANs. | | **ports** (*name*; Default: ) | The list of bridge ports to which the multicast group will be forwarded. | | **vid** (*integer: 1..4094*; Default: ) | The VLAN ID on which the MDB entry will be created, only applies when `vlan-filtering` is enabled. When the VLAN ID is not specified, the entry will work in shared-VLAN mode and dynamically apply on all defined VLAN IDs for particular ports. | ## Monitoring and troubleshooting --- This section describes the IGMP/MLD snooping bridge monitoring and troubleshooting options. To monitor learned multicast database (MDB) entries, use the `print` command. **Sub-menu:** `/interface/bridge/mdb` | Property | Description | | :-- | :-- | | **bridge** (*read-only: *name**) | Shows the bridge interface the entry belongs to. | | **group** (*read-only:* *ipv4 \| ipv6 address*) | Shows a multicast group address. | | **on-ports** (*read-only: name*) | Shows the bridge ports that are subscribed to a certain multicast group. | | **vid** (*read-only: integer*) | Shows the VLAN ID for the multicast group, only applies when `vlan-filtering` is enabled. | ```ros [admin@MikroTik] /interface/bridge/mdb/print Flags: D - DYNAMIC Columns: GROUP, VID, ON-PORTS, BRIDGE # GROUP VID ON-PORTS BRIDGE 0 D ff02::2 1 bridge1 bridge1 1 D ff02::6a 1 bridge1 bridge1 2 D ff02::1:ff00:0 1 bridge1 bridge1 3 D ff02::1:ff01:6a43 1 bridge1 bridge1 4 D 229.1.1.1 10 ether2 bridge1 5 D 229.2.2.2 10 ether3 bridge1 ether2 6 D ff02::2 10 ether5 bridge1 ether3 ether2 ether4 ``` To monitor the current status of a bridge interface, use the `monitor` command. **Sub-menu:** `/interface/bridge` | Property | Description | | :-- | :-- | | **igmp-querier** (*none*\| *interface & IPv4 address*) | Shows a bridge port and source IP address from the detected IGMP querier. Only shows the detected external IGMP querier, the local bridge IGMP querier (including IGMP proxy and PIM) will not be displayed. The monitoring value appears only when `igmp-snooping` is enabled. | | **mld-querier** (*none*\| *interface & IPv6 address*) | Shows a bridge port and source IPv6 address from the detected MLD querier. Only shows the detected external MLD querier, the local bridge MLD querier will not be displayed. The monitoring value appears only when `igmp-snooping` is enabled and the bridge has an active IPv6 address. | | **multicast-router** (*yes \| no*) | Shows if a multicast router is detected on the bridge interface. The monitoring value appears only when `igmp-snooping` is enabled. | ```ros [admin@MikroTik] /interface/bridge/monitor bridge1 state: enabled current-mac-address: 64:D1:54:C7:3A:59 root-bridge: yes root-bridge-id: 0x8000.64:D1:54:C7:3A:59 root-path-cost: 0 root-port: none port-count: 3 designated-port-count: 3 fast-forward: no multicast-router: no igmp-querier: ether2 192.168.10.10 mld-querier: ether2 fe80::e68d:8cff:fe39:3824 ``` To monitor the current status of bridge ports, use the `monitor` command. **Sub-menu:** `/interface/bridge/port` | Property | Description | | :-- | :-- | | **multicast-router** (*yes \| no*) | Shows if a multicast router is detected on the port. Monitoring value appears only when `igmp-snooping` is enabled. | ```ros [admin@MikroTik] > /interface/bridge/port/monitor [find] interface: ether2 ether3 ether4 status: in-bridge in-bridge in-bridge port-number: 1 2 3 role: designated-port designated-port designated-port edge-port: no yes yes edge-port-discovery: yes yes yes point-to-point-port: yes yes yes external-fdb: no no no sending-rstp: yes yes yes learning: yes yes yes forwarding: yes yes yes multicast-router: yes no no hw-offload-group: switch1 switch1 switch1 ``` ## Configuration examples --- Below are described the most common configuration examples. Some examples are using a bridge with VLAN filtering, so make sure to understand the filtering principles first - [bridge VLAN filtering](../index.md#bridge-vlan-filtering), [bridge VLAN table](./bridge-vlan-table.md). ### Basic IGMP snooping configuration The first example consists only of a single IGMP snooping bridge, a single multicast source device, and a couple of multicast client devices. See a network scheme below. ![IGMP Basic Setup Diagram](./img/bridge-igmp-mld-snooping-02.webp) First, create a bridge interface with enabled IGMP snooping. In this example, there is no active IGMP querier (no multicast router or proxy), so a local IGMP querier must be enabled on the same bridge. This can be done with a `multicast-querier` setting. If there is no active IGMP querier in the LAN, the unregistered IP multicast will be flooded and multicast entries will always timeout from the multicast database. ```ros /interface/bridge add igmp-snooping=yes multicast-querier=yes name=bridge1 ``` Then add the necessary interfaces as bridge ports. ```ros /interface/bridge/port add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=ether3 add bridge=bridge1 interface=ether4 add bridge=bridge1 interface=ether5 ``` The basic IGMP snooping configuration is finished. Use "`/interface/bridge/mdb/print"` command to monitor the active multicast groups. If necessary, you can configure an IP address and [DHCP server](../../network-management/dhcp.md#configuration-examples) on the same bridge interface. ### IGMP snooping configuration with VLANs The second example adds some complexity. There are two IGMP snooping bridges and we need to isolate the multicast traffic on a different VLAN. See a network scheme below. ![IGMP VLAN Setup Diagram](./img/bridge-igmp-mld-snooping-03.webp) First, create a bridge on both devices and add the needed interfaces as bridge ports. To change the untagged VLAN for a bridge port, use the `pvid` setting. Bridge1 will be acting as an IGMP querier. Below are the configuration commands for Bridge1: ```ros /interface/bridge add igmp-snooping=yes multicast-querier=yes name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 pvid=10 add bridge=bridge1 interface=ether3 pvid=10 add bridge=bridge1 interface=ether4 pvid=10 add bridge=bridge1 interface=ether5 pvid=20 add bridge=bridge1 interface=sfp-sfpplus1 pvid=10 ``` And for the Bridge2: ```ros /interface/bridge add igmp-snooping=yes name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether3 pvid=10 add bridge=bridge1 interface=ether4 pvid=10 add bridge=bridge1 interface=ether5 pvid=20 add bridge=bridge1 interface=sfp-sfpplus1 pvid=10 ``` :::warning Bridge IGMP querier implementation can only send untagged IGMP queries. In case tagged IGMP queries should be sent or IGMP queries should be generated in multiple VLANs, you can configure VLAN interfaces alongside [IGMP Proxy](../../user-guides/routing-and-networking-protocols/multicast/igmp-proxy.md) or [PIM-SM](../../user-guides/routing-and-networking-protocols/multicast/pim-sm.md). The downstream interfaces of the IGMP Proxy, as well as PIM-SM interfaces, can operate as IGMP queriers. ::: Make sure to configure [management access](../#management-access-configuration) for devices. It is essential when configuring a bridge with VLAN filtering. In this example, a VLAN 99 interface with an IP address is added to the bridge. This VLAN will be allowed on the tagged sfp-sfpplus1 port. Below are configuration commands for the Bridge1: ```ros /interface/vlan add interface=bridge1 name=MGMT vlan-id=99 /ip/address add address=192.168.99.1/24 interface=MGMT network=192.168.99.0 /interface/bridge/vlan add bridge=bridge1 tagged=bridge1,sfp-sfpplus1 vlan-ids=99 ``` And for the Bridge2: ```ros /interface/vlan add interface=bridge1 name=MGMT vlan-id=99 /ip/address add address=192.168.99.2/24 interface=MGMT network=192.168.99.0 /interface/bridge/vlan add bridge=bridge1 tagged=bridge1,sfp-sfpplus1 vlan-ids=99 ``` Add bridge VLAN entries and specify tagged and untagged ports. The VLAN 99 entry was already created when configuring management access; only VLAN 10 and VLAN 20 should be added now. Below are the configuration commands for Bridge1: ```ros /interface/bridge/vlan add bridge=bridge1 untagged=ether2,ether3,ether4,sfp-sfpplus1 vlan-ids=10 add bridge=bridge1 tagged=sfp-sfpplus1 untagged=ether5 vlan-ids=20 ``` And for the Bridge2: ```ros /interface/bridge/vlan add bridge=bridge1 untagged=ether3,ether4,sfp-sfpplus1 vlan-ids=10 add bridge=bridge1 tagged=sfp-sfpplus1 untagged=ether5 vlan-ids=20 ``` Last, enable VLAN filtering. Below is the configuration command for Bridge1 and Bridge2: ```ros /interface/bridge/set [find name=bridge1] vlan-filtering=yes ``` At this point, VLANs and IGMP snooping are configured and devices should be able to communicate through ports. However, it is recommended to go even a step further and apply some additional filtering options. Enable `ingress-filtering` and `frame-types` on bridge ports. Below are the configuration commands for Bridge1: ```ros /interface/bridge/port set [find interface=ether2] ingress-filtering=yes frame-types=admit-only-untagged-and-priority-tagged set [find interface=ether3] ingress-filtering=yes frame-types=admit-only-untagged-and-priority-tagged set [find interface=ether4] ingress-filtering=yes frame-types=admit-only-untagged-and-priority-tagged set [find interface=ether5] ingress-filtering=yes frame-types=admit-only-untagged-and-priority-tagged set [find interface=sfp-sfpplus1] ingress-filtering=yes ``` And for the Bridge2: ```ros /interface/bridge/port set [find interface=ether3] ingress-filtering=yes frame-types=admit-only-untagged-and-priority-tagged set [find interface=ether4] ingress-filtering=yes frame-types=admit-only-untagged-and-priority-tagged set [find interface=ether5] ingress-filtering=yes frame-types=admit-only-untagged-and-priority-tagged set [find interface=sfp-sfpplus1] ingress-filtering=yes ``` ### Static MDB entries Since RouterOS version 7.7, it is possible to create static MDB entries for IPv4 and IPv6 multicast groups. For example, to create a static MDB entry for multicast group 229.10.10.10 on ports ether2 and ether3 on VLAN 10, use the command below: ```ros /interface/bridge/mdb add bridge=bridge1 group=229.10.10.10 ports=ether2,ether3 vid=10 ``` Verify the results with the `print` command: ```ros [admin@MikroTik] > /interface/bridge/mdb/print where group=229.10.10.10 Columns: GROUP, VID, ON-PORTS, BRIDGE # GROUP VID ON-PORTS BRIDGE 12 229.10.10.10 10 ether2 bridge1 ether3 ``` In case a certain IPv6 multicast group does not need to be snooped and it is desired to be flooded on all ports and VLANs, it is possible to create a static MDB entry on all VLANs and ports, including the bridge interface itself. Use the command below to create a static MDB entry for multicast group ff02::2 on all VLANs and ports (modify the `ports` setting for your particular setup): ```ros /interface/bridge/mdb add bridge=bridge1 group=ff02::2 ports=bridge1,ether2,ether3,ether4,ether5 [admin@MikroTik] > /interface/bridge/mdb/print where group=ff02::2 Flags: D - DYNAMIC Columns: GROUP, VID, ON-PORTS, BRIDGE # GROUP VID ON-PORTS BRIDGE 0 ff02::2 bridge1 15 D ff02::2 1 bridge1 bridge1 16 D ff02::2 10 bridge1 bridge1 ether2 ether3 ether4 ether5 17 D ff02::2 20 bridge1 bridge1 ether2 ether3 18 D ff02::2 30 bridge1 bridge1 ether2 ether3 ``` --- ## Bridge VLAN Table --- It is possible to use a bridge to filter out VLANs in your network. To achieve this, you should use the [Bridge VLAN Filtering](../index.md#bridge-vlan-filtering) feature. This feature should be used instead of many known VLAN misconfigurations that are most likely causing you either performance issues or connectivity issues. You can read about one of the most popular misconfigurations in the [VLAN in a bridge with a physical interface](layer2-misconfiguration.md#vlan-in-a-bridge-with-a-physical-interface) section. The most important part of the bridge VLAN filtering feature is the bridge VLAN table, which specifies which VLANs are allowed on each port, but configuring it might get quite complex if you are trying to make a more advanced setup, for generic setups you should be able to configure your device using the [Trunk and Access ports](../index.md#vlan-example-trunk-and-access-ports) example, but the purpose of this guide is to provide an in-depth explanation and point out some of the behavior characteristics when using bridge VLAN Filtering. ## Background --- Before explaining bridge VLAN filtering in-depth, you should understand a few basic concepts that are involved in bridge VLAN filtering. - **Tagged/Untagged** - Under the `/interface/bridge/vlan` menu, you can specify an entry that contains tagged and untagged ports. In general, tagged ports should be your trunk port and untagged port should be your access port. By specifying a tagged port, the bridge will always set a VLAN tag for packets that are being sent out through this port (egress). By specifying an untagged port, the bridge will always remove the VLAN tag from egress packets. - **VLAN-ids** - Under the `/interface/bridge/vlan` menu, you can specify an entry in which certain VLANs are allowed on a specific port. The VLAN ID is checked on the egress port. If the packet contains a VLAN ID that does not exist in the bridge VLAN table for the egress port, then the packet is dropped before it gets sent out. - **PVID** - The Port VLAN ID is used for access ports to tag all ingress traffic with a specific VLAN ID. A dynamic entry is added in the bridge VLAN table for every PVID used, and the port is automatically added as an untagged port. - **Ingress filtering** - By default, VLANs that don't exist in the bridge VLAN table are dropped before they are sent out (egress), but this property allows you to drop the packet when they are received (ingress). - **Management access** - The bridge is supposed to simply forward packets between bridge ports, and it would seem to other devices that there is simply a wire between them. With bridge VLAN filtering, you can limit which packets are allowed to access the device that has the bridge configured. The most common practice is to allow access to the device only by using a very specific VLAN ID, but there are other ways you can grant access to the device. Management access is a great way to add another layer of security when accessing the device through a bridge port; this type of access is sometimes called the management port. For devices that support VLAN Filtering with hardware offloading, it is also related to the CPU port of a bridge. - **CPU port** - Every device with a switch chip has a special-purpose port called the CPU port, and it is used to communicate with the device's CPU. For devices that support VLAN filtering with hardware offloading, this port is the bridge interface itself. This port is mostly used to create management access but can be used for other purposes, for example, to route traffic between VLANs, to mark packets, and to apply queue. - **frame-type** - You can filter out packets based on whether they have a VLAN tag or not; this is useful to add an extra layer of security for your bridge ports. - **EtherType** - By default, a VLAN-aware bridge will filter VLANs by checking the C-TAG (0x8100); all other VLAN tags types are considered as untagged packets (without a VLAN tag). The selected EtherType will be used for VLAN filtering and VLAN tagging/untagging. - **VLAN Tunnelling** - If the EtherType of the packet does not match with the EtherType configured for the bridge, then ingress packets are considered as untagged packets; this behavior gives a possibility to encapsulate VLANs into another, different VLAN. This also gives a possibility to divert specific traffic through different devices in your network. - **Tag stacking** - If a packet has a VLAN tag that matches the EtherType, then the packet is considered as a tagged packet, but you can force another VLAN tag regardless of the packet's content. By setting `tag-stacking=yes` on a bridge port, you will add another VLAN tag with the PVID value on top of any other tag for all ingress packets. ## Trunk/Access port setup --- Below you can find a very common diagram for a very typical type of setup that consists of a trunk port and multiple access ports: ![Trunk and Access Setup](./img/bridge-vlan-table-01.webp) This setup is very common since it gives the possibility to divide your network into multiple segments while using a single switch and maybe a single router. Such a requirement is very common for companies that want to separate multiple departments. With VLANs you can use different DHCP Servers, which can give out an IP address from a different subnet based on the VLAN ID, which makes creating Firewall rules and QoS a lot easier. In such a setup you would connect some generic devices like Desktop PCs to **ether2** and **ether3**. These can be considered as workstations and they generally only use untagged traffic (it is possible to force a VLAN tag for all traffic that is sent out a generic workstation, though it is not very common). To isolate some workstations from other workstations you must add a VLAN tag to all packets that enter **ether2** or **ether3**, but to decide what VLAN ID the packet should get, you need to use a concept called **Port-based VLANs**. In this concept, packets get a VLAN tag with a VLAN ID based on the bridge port to which the device is connected. For example, in this setup the device on **ether2** will get a VLAN tag with **VLAN20** and the device on **ether3** will get a VLAN tag with **VLAN30**. This concept is very scalable as long as you have enough bridge ports. This should give you the understanding that traffic between the bridge and devices behind **ether2/ether3** is untagged (since there is no VLAN tag, hence the name). When we have determined our untagged ports, we can now determine our tagged ports. Tagged ports are going to be the trunk ports (the port that carries multiple VLANs) and usually, this port is connected to a router or another switch/bridge. You can have multiple trunk ports as well. Tagged ports are always carrying packets with a VLAN tag (hence the name) and you must **ALWAYS** specify the tagged ports for each VLAN ID you want this port to forward. It is possible that a port is a tagged port for one VLAN ID and the same port is an untagged port for a different VLAN ID, but this is for a different type of setup (Hybrid port setup). A special note must be added for the PVID property. This property should be used on access ports, but it can be used for trunk ports as well (in a Hybrid port setup). By using the PVID property you are adding a new VLAN tag with a VLAN ID that is specified in the PVID to all **UNTAGGED** packets that are received on that specific bridge port. The PVID does not have any effect on tagged packets, this means that, for example, if a packet with a VLAN tag of **VLAN40** is received on **ether2** that has `PVID=20`, then the VLAN tag is **NOT** changed and forwarding will depend on the entries from the bridge VLAN table. To configure the trunk/access port setup, you need to first create a bridge: ```ros /interface/bridge add name=bridge1 ``` :::danger Don't enable VLAN filtering yet as you might get locked out of the device because of the lack of management access, which is configured at the end. ::: Add the bridge ports and specify PVID for each access port: ```ros /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 pvid=20 add bridge=bridge1 interface=ether3 pvid=30 ``` :::warning PVID has no effect until VLAN filtering is enabled. ::: Add appropriate entries in the bridge VLAN table: ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether1 untagged=ether2 vlan-ids=20 add bridge=bridge1 tagged=ether1 untagged=ether3 vlan-ids=30 ``` You might think that you could simplify these entries with a single entry, similar to this: ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether1 untagged=ether2,ether3 vlan-ids=20,30 ``` Do **NOT** use multiple VLAN IDs on access ports. This will unintentionally allow both **VLAN20** and **VLAN30** on both access ports. In the example above, **ether3** is supposed to set a VLAN tag for all ingress packets to use **VLAN30** (since `PVID=30`), but this does not limit the allowed VLANs on this port when VLANs are being sent out through this port. The bridge VLAN table is responsible for deciding whether a VLAN is allowed to be sent through a specific port or not. The entry above specifies that both **VLAN20** and **VLAN30** are allowed to be sent out through **ether2** and **ether3** and on top of that the entry specifies that packets should be sent out without a VLAN tag (packets are sent out as untagged packets). As a result, you may create a packet leak from VLANs to ports that are not even supposed to receive such traffic, see the image below. ![Trunk and Access Setup Bad](./img/bridge-vlan-table-02.webp) A misconfigured VLAN table allows VLAN20 to be sent through ether3; it will also allow VLAN30 through ether2 :::danger Don't use more than one VLAN ID specified in a bridge VLAN table entry for access ports; you should only specify multiple VLAN IDs for trunk ports. ::: It is not necessary to add a bridge port as an untagged port, because each bridge port is added as an untagged port dynamically with a VLAN ID that is specified in the PVID property. This is because of a feature that automatically will add an appropriate entry in the bridge VLAN table for convenience and performance reasons. This feature does have some caveats that you must be aware of. All ports that have the same PVID will be added to a single entry for the appropriate VLAN ID as untagged ports, but note that the **Bridge interface** also has a VLAN ID. For testing purposes, we are going to enable VLAN filtering, but note that it might make you lose access to the device since it does not have management access configured yet (we will configure it later). It is always recommended to configure VLAN filtering while using a serial console, though you can also configure a device through a port that is not added to a bridge. Make sure you are using a serial console or connected through a different port (that is not in a bridge) and enable VLAN filtering: ```ros /interface/bridge/set bridge1 vlan-filtering=yes ``` :::warning You might not lose access to the device as soon as you enable VLAN filtering, but you might get disconnected since the bridge must reset itself in order for VLAN filtering to take any effect, which will force you to reconnect (this is mostly relevant when using MAC-telnet). There is a chance you might be able to access your device using untagged traffic. This scenario is described below. ::: If you have enabled VLAN filtering now and printed out the current VLAN table, you would see such a table: ```text [admin@MikroTik] > /interface/bridge/vlan/print Flags: X - disabled, D - dynamic # BRIDGE VLAN-IDS CURRENT-TAGGED CURRENT-UNTAGGED 0 bridge1 20 ether1 ether2 1 bridge1 30 ether1 ether3 2 D bridge1 1 bridge1 ether1 ``` There is a dynamic entry added for **VLAN1** since `PVID=1` is set by default to all bridge ports (including our trunk port, **ether1**), but you should also notice that the **bridge1** interface (the CPU port) is also added dynamically. You should be aware that **bridge1** is also a bridge port and therefore might get added to the bridge VLAN table dynamically. There is a chance that you might unintentionally allow access to the device because of this feature. For example, if you have followed this guide and left **PVID=1** set for the trunk port (**ether1**) and did not change the PVID for the CPU port (**bridge1**) as well, then access through **ether1** to the device using untagged traffic is allowed. This is also visible when you print out the bridge VLAN table. This scenario is illustrated in the image below: ![Trunk and Access Setup Unintentional Management](./img/bridge-vlan-table-03.webp) Unintentionally allowed management access using untagged traffic through the trunk port :::danger Always check the bridge VLAN table if you have not unintentionally allowed certain VLANs or untagged traffic to specific ports, especially the CPU port (bridge). ::: There is a simple way to prevent the bridge (CPU port) from being added as an untagged port. You can simply set the PVID on the trunk port to be different than the bridge's PVID (or change the bridge's PVID), but there is another option, which is more intuitive and recommended. Since you are expecting that the trunk port is only supposed to receive tagged traffic (in this example, it should only receive **VLAN20/VLAN30**), but no untagged traffic, you can use ingress-filtering along with frame-type to filter out unwanted packets, but to fully understand the behavior of ingress filtering, we must first understand the details of management access. Management access is used to create a way to access a device through a bridge that has VLAN filtering enabled. You could simply allow untagged access and doing that is fairly simple. Let us say you wanted the workstation behind **ether3** to be able to access the device. We assumed before that the workstation is a generic computer that will not use tagged packets and therefore will only send out untagged packets. This means that we should add the CPU port (**bridge1**) as an untagged interface to the bridge VLAN table, to do so, simply use the same PVID value for the **bridge1** and **ether3** ports and set both ports as untagged members for the VLAN ID. In this case, you are going to connect from **ether3** that has `PVID=30`, so you change the configuration accordingly: ```ros /interface/bridge/set [find name=bridge1] pvid=30 /interface/bridge/vlan/set [find vlan-ids=30] untagged=bridge1,ether3 ``` :::warning You can use the feature that dynamically adds untagged ports with the same PVID value, or you can simply change the PVID to match between **ether3** and **bridge1**. ::: Allowing access to the device using untagged traffic is not considered a good security practice. A much better way is to allow access to the device using a very specific VLAN sometimes called the management VLAN. In our case, this is going to be **VLAN99**. This adds a significant layer of security since an attacker must guess the VLAN ID that is being used for management purposes and then guess the login credentials. On top of this, you can even add another layer of security by allowing access to the device using only certain IP addresses. The purpose of this guide is to provide an in-depth explanation. For that reason, we are adding a level of complexity to our setup to understand some possible caveats that you must take into account. We are going to allow access from an access port using tagged traffic (illustrated in the image below). To allow access to the device using **VLAN99** from **ether3**, we must add a proper entry in the bridge VLAN table. Additionally, a network device connected to ether3 must support VLAN tagging. ```ros /interface/bridge/vlan add bridge=bridge1 tagged=bridge1,ether3 vlan-ids=99 ``` ![Trunk and Access Setup Management Access](./img/bridge-vlan-table-04.webp) Management access using tagged traffic through an access port (which makes it a hybrid port) :::warning If PVID for ether1 and bridge1 match (by default, it does match with 1), then access to the device is allowed using untagged traffic from ether1 because of the feature that dynamically adds untagged ports to the bridge VLAN table. ::: But you might notice that access using **VLAN99** does not work at this point. This is because you need a VLAN interface that listens for tagged traffic. You can simply create this interface for the appropriate VLAN ID and you can set an IP address for the interface as well: ```ros /interface/vlan add interface=bridge1 name=VLAN99 vlan-id=99 /ip/address add address=192.168.99.2/24 interface=VLAN99 ``` :::warning Our access port (**ether3**) at this point expects tagged and untagged traffic at the same time; such a port is called a **hybrid port**. ::: At this point, we can benefit from using `ingress-filtering` and `frame-type`. First, we are going to focus on `frame-type`, which limits the allowed packet types (tagged, untagged, both), but for `frame-type` to work properly, `ingress-filtering` must be enabled, otherwise it will not have any effect. In our example, where we wanted to allow access from **ether3** using tagged traffic (**VLAN99**) and at the same time allow a generic workstation to access the network, we can conclude that this port needs to allow tagged and untagged packets, but **ether1** and **ether2** are supposed to receive only specific types of packets, for these reasons we can enhance our network's security. Since **ether1** is our trunk port, it is only supposed to carry tagged packets, but **ether2** is our access port so it should not carry any tagged packets, based on these conclusions we can drop invalid packets: ```ros /interface/bridge/port set [find where interface=ether1] ingress-filtering=yes frame-types=admit-only-vlan-tagged set [find where interface=ether2] ingress-filtering=yes frame-types=admit-only-untagged-and-priority-tagged ``` Let's say that you forgot to enable ingress-filtering and change the frame-type property on **ether1**, this would unintentionally add access to the device through **ether1** using untagged traffic since PVID matches for **bridge1** and **ether1**, but you are expecting only tagged traffic to be able to access the device. It is possible to drop all untagged packets that are destined for the **CPU port**: ```ros /interface/bridge set bridge1 frame-types=admit-only-vlan-tagged ingress-filtering=yes ``` This not only drops untagged packets, but disables the feature that dynamically adds untagged ports to the bridge VLAN table. If you print out the current bridge VLAN table, you will notice that **bridge1** is not dynamically added as an untagged port: ```text [admin@MikroTik] > /interface/bridge/vlan/print Flags: X - disabled, D - dynamic # BRIDGE VLAN-IDS CURRENT-TAGGED CURRENT-UNTAGGED 0 bridge1 20 ether1 1 bridge1 30 ether1 ether3 2 D bridge1 1 ether1 3 bridge1 99 bridge1 ether3 ``` :::warning When `frame-type=admit-only-vlan-tagged` is used on a port, then the port is not dynamically added as an untagged port for the PVID. ::: While `frame-type` can be used to drop a certain type of packet, the `ingress-filtering` can be used to filter out packets before they can be sent out. To fully understand the need for ingress filtering, consider the following scenario: **VLAN99** is allowed on **ether3** and **bridge1**, but you can still send **VLAN99** traffic from **ether1** to **ether3**. This is because the bridge VLAN table checks if a port is allowed to carry a certain VLAN only on egress ports. In our case, **ether3** is allowed to carry **VLAN99** and for this reason, it is forwarded. To prevent this, you **MUST** use ingress-filtering. With ingress filtering, ingress packets are also checked. In our case, the bridge VLAN table does not contain an entry that **VLAN99** is allowed on **ether1**, and therefore the packet will be dropped immediately. Of course, in our scenario without ingress filtering, the connection cannot be established since **VLAN99** can be forwarded only from **ether1** to **ether3**, but not from **ether3** to **ether1**, though there are still possible attacks that can be used in such a misconfiguration (for example, ARP poisoning). The packet dropping behavior is illustrated in the image below: ![Trunk and Access Setup Ingress](./img/bridge-vlan-table-05.webp) Trunk/access port setup with and without ingress filtering. Ingress filtering can prevent unwanted traffic from being forwarded. Note that ether1 is not allowed to carry VLAN99 in the bridge VLAN table. :::danger Always try to use `ingress-filtering` wherever it is possible. It adds a significant layer of security. ::: The ingress-filtering can be used on the **CPU port**(bridge) as well. This can be used to prevent some possible attack vectors and limit the allowed VLANs that can access the CPU. It is better to drop a packet on an ingress port, rather than on an egress port. This reduces the CPU load, which is quite crucial when you are using hardware offloading with bridge VLAN filtering. :::warning The `ingress-filtering` property only affects ingress traffic, but `frame-type` affects both egress and ingress traffic. ::: Even though you can limit the allowed VLANs and packet types on a port, it is never a good security practice to allow access to a device through access ports since an attacker could sniff packets and extract the management VLAN's ID. You should only allow access to the device from the trunk port (**ether1**) since trunk ports usually have better physical security. You should remove the previous entry and allow access to the device through the port that is connected to your router (illustrated in the image below): ```ros /interface/bridge/vlan add bridge=bridge1 tagged=bridge1,ether1 vlan-ids=99 ``` ![Basic VLAN Switching](./img/bridge-vlan-table-06.webp) ## VLAN Tunnelling setup --- In some cases, you might want to forward already tagged traffic through certain switches. This is a quite common setup for backbone infrastructures since it provides a possibility to encapsulate traffic from, for example, your edge routers and seamlessly forward it over your backbone to another edge router. Below you can find an example of a VLAN tunneling topology: ![Provider Bridge](./img/bridge-vlan-table-07.webp) Provider bridge topology SVID stands for Service VID, indicating the tag type along with the VID. :::warning To fully understand how to configure VLAN tunneling properly, you should first read the Trunk/Access port setup section before proceeding any further. ::: There are two possible ways to achieve this, one is the standardized IEEE 802.1ad way, and the other way is using **Tag stacking**. We will first review the standardized way since the same principles apply to both ways and only a couple of parameters must be changed to use the other method. The way VLAN tunneling works is that the bridge checks if the outer VLAN tag is using the same VLAN tag as specified in ether-type. If the VLAN tag matches, the packet is considered as a tagged packet, otherwise, it is considered as an untagged packet. :::warning The bridge checks only the outer tag (closest to the MAC address); any other tag is ignored anywhere in a bridge configuration. The bridge is not aware of the packet contents; even though there might be another VLAN tag, only the first VLAN tag is checked. ::: The ether-type property allows you to select the following EtherTypes for the VLAN tag: - 0x88a8 - IEEE 802.1ad, Service Tag. - 0x8100 - IEEE 802.1Q, Customer VLAN (regular VLAN tag). - 0x9100 - Unofficial tag type (rarely used). To properly configure bridge VLAN filtering, you must understand how the bridge distinguishes between tagged and untagged packets. As mentioned before, the bridge will check if EtherType matches with the outer VLAN tag in the packet. For example, consider the following packet: ```text FFFFFFFFFFFF 6C3B6B7C413E 8100 6063 9999 ---------------------------------------- DST-MAC = FFFFFFFFFFFF SRC-MAC = 6C3B6B7C413E Outer EtherType = 8100 (IEEE 802.1Q VLAN tag) VLAN priority = 3 VLAN ID = 99 (HEX = 63) Inner EtherType = 9999 ``` Let us assume that we have set **`ether-type=0x88a8`**, in this case, the packet above will be considered untagged since the bridge is looking for a different VLAN tag. Let's now consider the following packet: ```text FFFFFFFFFFFF 6C3B6B7C413E 88A8 6063 8100 5062 9999 ---------------------------------------- DST-MAC = FFFFFFFFFFFF SRC-MAC = 6C3B6B7C413E Outer EtherType = 88A8 (IEEE 802.1ad VLAN tag) VLAN priority = 3 VLAN ID = 99 (HEX = 63) Inner EtherType 1 = 8100 (IEEE 802.1Q VLAN tag) VLAN priority = 2 VLAN ID = 98 (HEX = 62) Inner EtherType 2 = 9999 ``` This time let us assume that we have set **`ether-type=0x8100`**. In this case, the packet above is considered as untagged as well since the outer tag is using an IEEE 802.1ad VLAN tag. The same principles apply to other VLAN-related functions, for example, the `PVID` property will add a new VLAN tag on access ports and the VLAN tag will be using the EtherType specified in ether-type. Both **SW1** and **SW2** are using the same configuration: ```ros /interface/bridge add name=bridge1 vlan-filtering=yes ether-type=0x88a8 /interface/bridge/port add interface=ether1 bridge=bridge1 pvid=200 add interface=ether2 bridge=bridge1 pvid=300 add interface=ether3 bridge=bridge1 /interface/bridge/vlan add bridge=bridge1 tagged=ether3 untagged=ether1 vlan-ids=200 add bridge=bridge1 tagged=ether3 untagged=ether2 vlan-ids=300 ``` In this example, we are assuming that all routers are passing traffic that is using a regular/customer VLAN tag. Such traffic on switches will be considered as untagged traffic based on the principle described above. Switches will encapsulate this traffic using a Service VLAN tag (the outer 802.1ad tag) and traffic between **SW1** and **SW2** will be considered as tagged. Before traffic reaches its destination, the switches will decapsulate the outer tag and forward the original 802.1Q tagged frame. See a packet example below: ![Service VLAN 802.1ad](./img/bridge-vlan-table-08.webp)A packet example before and after 802.1ad VLAN encapsulation :::warning All principles that apply to the regular trunk/access port setup using IEEE 802.1Q also apply to VLAN tunneling setups. Make sure you are limiting VLANs and packet type properly using the bridge VLAN table and ingress filtering. ::: In case you want to create management access from, let's say, **ether3** to the device and want to use **VLAN99**, then you would use such commands: ```ros /interface/bridge/vlan add bridge=bridge1 tagged=bridge1,ether3 vlan-ids=99 /interface/vlan add interface=bridge1 name=VLAN99 use-service-tag=yes vlan-id=99 /ip/address add address=192.168.99.2/24 interface=VLAN99 ``` As you may notice, the only difference is that the VLAN interface is using `use-service-tag=yes`; this sets the VLAN interface to listen to IEEE 802.1ad VLAN tags. This will require you to use the IEEE 802.1ad VLAN tag to access the device using the management VLAN - you will not be able to connect to the device using a regular VLAN tag while bridge VLAN filtering is enabled. The ether-type is set globally and will affect all bridge VLAN filtering functions. :::danger Devices with switch chip Marvell-98DX3257 (e.g. CRS354 series) do not support VLAN filtering on 1Gbps Ethernet interfaces for other VLAN types (`0x88a8` and `0x9100`). ::: ### Tag Stacking In the VLAN Tunnelling setup, we were adding a new VLAN tag that was different from the VLAN tag, but it is possible to add a new VLAN tag regardless of the packet contents. The difference from the regular VLAN tunneling setup is that the bridge does not check if the packet is tagged or untagged, it assumes that all packets that are received on a specific port are all untagged packets and will add a new VLAN tag regardless of whether a VLAN tag is present or not. This is called **Tag Stacking** since it "stacks" VLAN tags on top of the previous tag, regardless of the VLAN tag type. This is a very common setup for networks that do not support the IEEE 802.1ad standard, but still want to encapsulate VLAN traffic into a new VLAN. The VLAN tag that is going to be added depends on `ether-type` and `PVID`. For example, if you have `ether-type=0x8100` and `PVID=200` on a port, then the bridge will add a new IEEE 802.1Q VLAN tag right on top of any other tag (if such is present). The same VLAN filtering principles still apply. You have to determine which ports are going to be your trunk ports and mark them as tagged ports, determine your access ports, and add them as untagged ports. To explain how VLAN tagging and untagging works with tag stacking, let us use the same network topology as before: ![Basic VLAN Switching 2](./img/bridge-vlan-table-09.webp) What we want to achieve is that regardless of what is being received on **ether2** and **ether3**, a new VLAN tag will be added to encapsulate the traffic that is coming from those ports. `Tag-stacking` forces a new VLAN tag, so we can use this property to achieve our desired setup. We are going to be using the same configuration as in the Trunk/Access port setup, but with `tag-stacking` enabled on the access ports: ```ros /interface/bridge add name=bridge1 vlan-filtering=yes ether-type=0x8100 /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 tag-stacking=yes pvid=20 add bridge=bridge1 interface=ether3 tag-stacking=yes pvid=30 /interface/bridge/vlan add bridge=bridge1 tagged=ether1 untagged=ether2 vlan-ids=20 add bridge=bridge1 tagged=ether1 untagged=ether3 vlan-ids=30 ``` :::warning The added VLAN tag will use the specified `ether-type`. The selected EtherType will also be used for VLAN filtering. Only the outer tag is checked, but with tag-stacking in place, the tag checking is skipped, and it is assumed that a new tag must be added either way. ::: Let us assume that the devices behind **ether2** and **ether3** are sending tagged **VLAN40** traffic. With this configuration, **ALL** packets will get encapsulated with a new VLAN tag, but you must make sure that you have added the VLAN ID from the outer tag to the bridge VLAN table. **VLAN40** is not added to the bridge VLAN table since it is the inner tag and it is not checked; we are only concerned about the outer tag, which is either **VLAN20** or **VLAN30** depending on the port. Similar to other setups, the bridge VLAN table is going to be used to determine if the VLAN tag needs to be removed or not. For example, when **ether1** receives tagged **VLAN20** packets, the bridge checks that **ether2** is allowed to carry **VLAN20** so it is about to send it out through **ether2**, but it also checks the bridge VLAN table whether the VLAN tag should be removed and since **ether2** is marked as an untagged port, the bridge will forward these packets from **ether1** to **ether2** without the **VLAN20** VLAN tag. From the access port perspective, the same principles as in the Trunk/Access port setup apply. All packets that are received on **ether2** will get a new VLAN tag with the VLAN ID that is specified in PVID, in this case, a new VLAN tag will be added with **VLAN20** and this VLAN will be subjected to VLAN filtering. See a packet example below: ![Tag Stacking](./img/bridge-vlan-table-10.webp) A packet example before and after tag stacking --- ## Controller Bridge and Port Extender :::danger The feature has been removed from RouterOS since v7.18. ::: --- Controller Bridge (CB) and Port Extender (PE) are an IEEE 802.1BR standard implementation in RouterOS for CRS3xx series switches. It allows virtually extending the CB ports with a PE device and managing these extended interfaces from a single controlling device. Such configuration provides a simplified network topology, flexibility, increased port density and ease of manageability. An example of Controller Bridge and Port Extender topology can be seen below. ![CB Summary](./img/controller-bridge-and-port-extender-01.webp) The Controller Bridge establishes communication with the Port Extender through a **cascade port**. Similarly, the Port Extender will communicate with the Controller Bridge only through an **upstream port**. On a PE device, control ports must be configured and only one port (closest to the CB) will act as an upstream port. Other control ports can act as a backup for the upstream port or even a cascade port for switches connected in series (e.g. Port Extender 2 and 3 in the image above). Cascade and upstream ports are used to transmit and receive control and network traffic. **Extended ports** are interfaces that are controlled by the CB device and they are typically connected to the end hosts. Extended ports only transmit and receive network traffic. See supported features for each switch model below. | **Model** | **Controller Bridge** | Port Extender | | :-- | :-- | :-- | | netPower 15FR (CRS318-1Fi-15Fr-2S) | **-** | **+** | | netPower 16P (CRS318-16P-2S+) | **-** | **+** | | CRS310-1G-5S-4S+ (netFiber 9/IN) | **-** | **+** | | CRS326-24G-2S+ (RM/IN) | **-** | **+** | | CRS328-24P-4S+ | **-** | **+** | | CRS328-4C-20S-4S+ | **-** | **+** | | CRS305-1G-4S+ | **-** | **+** | | CRS309-1G-8S+ | **+** | **+** | | CRS317-1G-16S+ | **+** | **+** | | CRS312-4C+8XG | **+** | **+** | | CRS326-24S+2Q+ | **+** | **+** | | CRS354-48G-4S+2Q+ | **+** | **+** | | CRS354-48P-4S+2Q+ | **+** | **+** | ### Limitations Although the controller allows configuring port extender interfaces, some bridging and switching features cannot be used or will not work properly. Below are the most common controller and extender limitations. The list might change with upcoming RouterOS releases. | Feature | Support | | :-- | :-- | | Bonding for cascade and upstream ports | + | | Bridge VLAN filtering | + | | Bonding for extended ports | - | | Dot1x authenticator (server) | - | | Ingress and egress rates | - | | Mirroring | - | | Port ingress VLAN filtering | - | | Port isolation | - | | Storm control | - | | Switch rules (ACL) | - | | L3HW offloading | - | | MLAG | - | ## Quick setup --- In this example, we will create a Controlling Bridge (e.g. a CRS317-1G-16S+ switch) that will connect to a single Port Extender (e.g. a CRS326-24G-2S+ switch) through an SFP+1 interface. First, configure a bridge with enabled VLAN filtering on a CB device: ```ros /interface/bridge add name=bridge1 vlan-filtering=yes ``` On the same device, configure a port that is connected to the PE device and will act as a cascade port: ```ros /interface/bridge/port-controller set bridge=bridge1 cascade-ports=sfp-sfpplus1 switch=switch1 ``` Last, on a PE device, simply configure a control port, which will be selected as an upstream port: ```ros /interface/bridge/port-extender set control-ports=sfp-sfpplus1 switch=switch1 ``` Once PE and CB devices are connected, all interfaces that are on the same switch group (except for control ports) will be extended and can be further configured on a CB device. An automatic bridge port configuration will be applied on the CB device which adds all extended ports in a single bridge. This configuration can be modified afterward. :::warning In order to exclude a port from being extended (e.g. for out-of-band management purposes), additionally, configure the `excluded-ports` property. ::: :::warning Make sure not to include the `cascade-ports` and `control-ports` in any routing or bridging configurations. These ports are recommended only for CB and PE usage. ::: ## Discovery and control protocols --- Before frame forwarding on extended ports is possible, Controlling Bridge and Port Extender must discover each other and exchange essential information. CB and PE enabled devices are using a neighbor discovery protocol LLDP with a specific Port Extension TLV. This allows CB and PE devices to advertise their support on cascade and control ports. :::warning CB and PE configuration can override the neighbor discovery settings, for example, if a cascade port is not included in a neighbor discovery interface list, the LLDP messages will still be sent. ::: Once LLDP messages are exchanged between CB and PE, a Control and Status Protocol (CSP) over an Edge Control Protocol (ECP) will be initiated. The CSP is used between CB and PE to assert control and receive status information from the associated PE - it assigns unique IDs for extended ports, controls data-path settings (e.g. port VLAN membership) and sends port status information (e.g. interface stats, PoE-out monitoring). The ECP provides reliable and sequenced frame delivery (encoded with EtherType 0x8940). :::danger The current CB implementation does not support any failover techniques. Once the CB device becomes unavailable, the PE devices will lose all the control and data forwarding rules. ::: ## Packet flow --- To better understand the underlying principles of Controlling Bridge and Port Extender, a packet walkthrough is provided below: 1. An L2 packet is received on the extended port. 2. The Port Extender encapsulates the packet with an E-TAG header (EtherType 0x893F) and forwards it through an upstream port, towards the Controller Bridge. An E-TAG packet contains information regarding the PE source port ID. The PE device does not make any local switching decisions. 3. The Controller Bridge receives the E-TAG packet and knows exactly which extended interface received it. The CB then internally decapsulates the packet and processes it through a regular switching decision (host learning, destination address lookup, VLAN filtering, etc.). 4. Once a switching decision is made, the CB will again encapsulate the original packet with an E-TAG and send it through a cascade port, towards Port Extender. 1. For a single destination packet (unicast), the CB will include the PE destination port ID in the E-TAG and send it through a correct cascade port. 2. For a multi-destination packet (broadcast, multicast or unknown-unicast), the CB will include a target group mark and source port ID in the E-TAG and send a single packet replica per cascade port. 5. Once a PE device receives an E-TAG packet on the upstream port, PE decapsulates it and sends the original L2 packet through the extended port. 1. For a single destination packet (unicast), the PE will send the packet only to the correct extended port. 2. For a multi-destination packet (broadcast, multicast or unknown-unicast), the PE will send a single packet replica per extended port (except for the source port where the packet was received). | | | | :-- | :-- | ![CB Unicast 3](./img/controller-bridge-and-port-extender-02.webp) ![CB Broadcast 2](./img/controller-bridge-and-port-extender-03.webp) ## Controller Bridge settings and monitoring --- This section describes the Controller Bridge settings and monitoring options. **Sub-menu:** `/interface/bridge/port-controller` | Property | Description | | :-- | :-- | | **bridge** (*name;*Default: **none**) | The bridge interface where ports will be extended. The CB will only be enabled when `bridge` and `switch` properties are specified, otherwise, it will be in a disabled state. | | **cascade-ports** (*interfaces;* Default: **none**) | Interfaces that will act as cascade ports. A bonding interface with 802.3ad or balance-xor `mode` is also supported. | | **switch** (*name;*Default: **none**) | The switch that will act as the CB and ensure the control and network traffic. The CB will only be enabled when `bridge` and `switch` properties are specified, otherwise, it will be in a disabled state. | After CB and PE devices are configured and connected, each PE device will be automatically visible on the device menu. Use `print` and `monitor` commands to see more details. ```ros [admin@Controller] > /interface/bridge/port-controller/device/print Flags: I - inactive 0 name="pe1" pe-mac=64:D1:54:EB:AE:BC descr="MikroTik RouterOS 6.48beta35 (testing) CRS328-24P-4S+" control-ports=pe1-sfpplus1,pe1-sfpplus2 1 name="pe2" pe-mac=64:D1:54:C7:3A:58 descr="MikroTik RouterOS 6.48beta35 (testing) CRS326-24G-2S+" control-ports=pe2-sfpplus1 [admin@Controller] > /interface/bridge/port-controller/device/monitor pe2 name: pe2 status: active connected-via-ports: sfp-sfpplus1==pe1-sfpplus1,pe1-sfpplus2==pe2-sfpplus1 connected-via-devs: controller,pe1 ``` **Sub-menu:** `/interface/bridge/port-controller/device` | Property | Description | | :-- | :-- | | **connected-via-devs** (*name*) | Shows the connected devices in the path from PE to CB. | | **connected-via-ports** (*name*) | Shows the connection path from PE to CB. | | **control-ports** (*interfaces*) | PE device control ports. | | **descr** (*name*) | Short PE device description. | | **name** (*name*) | Automatically assigned PE device name. | | **pe-mac** (*MAC address*) | PE device MAC address. | | **status** (*active \| inactive*) | PE device status. | Additionally, each PE device interface can be monitored on the port menu. Use `print` and `monitor` commands to see more details. ```ros [admin@Controller] > /interface/bridge/port-controller/port/print where !disabled Flags: I - inactive, X - disabled, R - running, U - upstream-port, C - cascade-port # NAME DEVICE 0 I pe1-ether1 pe1 1 R pe1-ether2 pe1 2 R pe1-ether3 pe1 3 R pe1-ether4 pe1 4 U pe1-sfpplus1 pe1 5 RC pe1-sfpplus2 pe1 6 I pe2-ether1 pe2 7 R pe2-ether2 pe2 8 R pe2-ether3 pe2 9 R pe2-ether4 pe2 10 U pe2-sfpplus1 pe2 [admin@Controller] > /interface/bridge/port-controller/port/monitor [find where !disabled] name: pe1-ether1 pe1-ether2 pe1-ether3 pe1-ether4 pe1-sfpplus1 pe1-sfpplus2 pe2-ether1 pe2-ether2 pe2-ether3 pe2-ether4 pe2-sfpplus1 status: unknown link-ok link-ok link-ok no-link link-ok unknown link-ok link-ok link-ok no-link rate: 1Gbps 1Gbps 1Gbps 10Gbps 10Gbps 1Gbps 1Gbps 1Gbps 10Gbps port-status: not-added ok ok ok ok ok not-added ok ok ok ok pcid: 457 458 459 480 481 509 510 511 532 ``` **Sub-menu:** `/interface/bridge/port-controller/port` | Property | Description | | :-- | :-- | | **device** (*name*) | Automatically assigned PE device name. | | **name** (*name*) | Automatically assigned PE port name. | | **pcid** (*integer*) | Automatically assigned port identifier. | | **port-status** (*dev-inactive \| not-added \| ok*) | PE port status. | | **rate** (*bps*) | Data rate of the connection. | | **status** (*link-ok \| no-link \| unknown*) | PE port link status. | The Controller Bridge can monitor the PoE-out related information from Port Extenders on the port PoE menu. Use `print` and `monitor` commands to see more details. For more information regarding PoE-out, please visit the [PoE-out manual](../../hardware/poe-out.mdx). ```ros [admin@Controller] > /interface/bridge/port-controller/port/poe/print # NAME DEVICE 0 pe1-ether1 pe1 1 pe1-ether2 pe1 2 pe1-ether3 pe1 3 pe1-ether4 pe1 4 pe1-ether5 pe1 5 pe1-ether6 pe1 6 pe1-ether7 pe1 ... [admin@Controller] > /interface/bridge/port-controller/port/poe/monitor pe1-ether2,pe1-ether3 name: pe1-ether2 pe1-ether3 poe-out-status: powered-on powered-on poe-out-voltage: 52.8V 52.9V poe-out-current: 123mA 95mA poe-out-power: 6.4W 5W ``` ## Port Extender settings --- This section describes the Port Extender settings. **Sub-menu:** `/interface/bridge/port-extender` | Property | Description | | :-- | :-- | | **control-ports** (*interfaces;* Default: **none**) | Interfaces that will either connect to the CB (upstream port) or connect other PE devices in series (cascade port). A bonding interface with 802.3ad or balance-xor `mode` is also supported. | | **excluded-ports** (*interfaces;* Default: **none**) | Interfaces that will not be extended. | | **switch** (*name;*Default: **none**) | The switch that will act as the extender and ensure the control and network traffic. The PE will only be enabled when this property is specified, otherwise, it will be in a disabled state. | ## Configuration examples --- Below are described the most common configuration examples. For CB and PE configuration to work properly, bridge VLAN filtering needs to be enabled, so make sure to understand the filtering principles first - [bridge VLAN filtering](../index.md#bridge-vlan-filtering), [bridge VLAN table](./bridge-vlan-table.md). ### Basic CB and PE configuration In this example, a CRS317-1G-16S+ device is used as a Controller Bridge and a CRS328-24P-4S+ as a Port Extender; see the connection scheme below. ![Basic CB PE Configuration](./img/controller-bridge-and-port-extender-04.webp) First, configure the CB device. This can be done by adding a bridge interface with enabled VLAN filtering. Additionally, add any local interfaces to the same bridge, which allows forwarding traffic between any local interfaces and extended interfaces. In this example, an sfp-sfpplus2 interface is added. ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=sfp-sfpplus2 ``` To enable CB, specify the bridge, switch and at least one cascade port. Make sure that cascade ports are not included in the bridge or routing configurations. These ports are recommended only for CB and PE usage. ```ros /interface/bridge/port-controller set bridge=bridge1 cascade-ports=sfp-sfpplus1 switch=switch1 ``` To enable PE, configure control ports and switch. Additionally, configure one or multiple interfaces that should not be extended with the `excluded-ports` property (e.g. for out-of-band management purposes). In this example, all switch ports will be extended. ```ros /interface/bridge/port-extender set control-ports=sfp-sfpplus4 switch=switch1 ``` Once PE and CB devices finish the discovery and start the Control and Status Protocol (CSP), the RouterOS will permanently create new interfaces and add them into the bridge on the CB device. Interfaces are named by the automatically assigned PE device name, plus the default interface name. These interface names can be modified afterwards. Note that control and excluded ports will also be displayed in the interface list, but they are not included in the bridge. ```ros [admin@Controller_Bridge] > /interface/print where name~"pe" Flags: D - dynamic, X - disabled, R - running, S - slave # NAME TYPE ACTUAL-MTU L2MTU MAX-L2MTU 0 RS pe1-ether1 extport 1500 1584 1 RS pe1-ether2 extport 1500 1584 2 RS pe1-ether3 extport 1500 1584 3 S pe1-ether4 extport 1500 1584 4 S pe1-ether5 extport 1500 1584 5 S pe1-ether6 extport 1500 1584 6 S pe1-ether7 extport 1500 1584 7 S pe1-ether8 extport 1500 1584 8 S pe1-ether9 extport 1500 1584 9 S pe1-ether10 extport 1500 1584 10 S pe1-ether11 extport 1500 1584 11 S pe1-ether12 extport 1500 1584 12 S pe1-ether13 extport 1500 1584 13 S pe1-ether14 extport 1500 1584 14 S pe1-ether15 extport 1500 1584 15 S pe1-ether16 extport 1500 1584 16 S pe1-ether17 extport 1500 1584 17 S pe1-ether18 extport 1500 1584 18 S pe1-ether19 extport 1500 1584 19 S pe1-ether20 extport 1500 1584 20 S pe1-ether21 extport 1500 1584 21 S pe1-ether22 extport 1500 1584 22 S pe1-ether23 extport 1500 1584 23 S pe1-ether24 extport 1500 1584 24 RS pe1-sfpplus1 extport 1500 1584 25 RS pe1-sfpplus2 extport 1500 1584 26 RS pe1-sfpplus3 extport 1500 1584 27 pe1-sfpplus4 extport 1500 1584 [admin@Controller_Bridge] > interface bridge port print Flags: X - disabled, I - inactive, D - dynamic, H - hw-offload # INTERFACE BRIDGE HW PVID PRIORITY PATH-COST INTERNAL-PATH-COST HORIZON 0 H sfp-sfpplus2 bridge1 yes 1 0x80 10 10 none 1 H pe1-ether1 bridge1 yes 1 0x80 10 10 none 2 H pe1-ether2 bridge1 yes 1 0x80 10 10 none 3 H pe1-ether3 bridge1 yes 1 0x80 10 10 none 4 I H pe1-ether4 bridge1 yes 1 0x80 10 10 none 5 I H pe1-ether5 bridge1 yes 1 0x80 10 10 none 6 I H pe1-ether6 bridge1 yes 1 0x80 10 10 none 7 I H pe1-ether7 bridge1 yes 1 0x80 10 10 none 8 I H pe1-ether8 bridge1 yes 1 0x80 10 10 none 9 I H pe1-ether9 bridge1 yes 1 0x80 10 10 none 10 I H pe1-ether10 bridge1 yes 1 0x80 10 10 none 11 I H pe1-ether11 bridge1 yes 1 0x80 10 10 none 12 I H pe1-ether12 bridge1 yes 1 0x80 10 10 none 13 I H pe1-ether13 bridge1 yes 1 0x80 10 10 none 14 I H pe1-ether14 bridge1 yes 1 0x80 10 10 none 15 I H pe1-ether15 bridge1 yes 1 0x80 10 10 none 16 I H pe1-ether16 bridge1 yes 1 0x80 10 10 none 17 I H pe1-ether17 bridge1 yes 1 0x80 10 10 none 18 I H pe1-ether18 bridge1 yes 1 0x80 10 10 none 19 I H pe1-ether19 bridge1 yes 1 0x80 10 10 none 20 I H pe1-ether20 bridge1 yes 1 0x80 10 10 none 21 I H pe1-ether21 bridge1 yes 1 0x80 10 10 none 22 I H pe1-ether22 bridge1 yes 1 0x80 10 10 none 23 I H pe1-ether23 bridge1 yes 1 0x80 10 10 none 24 I H pe1-ether24 bridge1 yes 1 0x80 10 10 none 25 H pe1-sfpplus1 bridge1 yes 1 0x80 10 10 none 26 H pe1-sfpplus2 bridge1 yes 1 0x80 10 10 none 27 H pe1-sfpplus3 bridge1 yes 1 0x80 10 10 none ``` Now the CRS317-1G-16S+ device has extended its ports using the CRS328-24P-4S+ device and packet forwarding can be done between all bridged ports. ### Trunk and Access ports In this example, untagged (access) and tagged (trunk) port configuration will be created on the Controller Bridge device. See the network diagram below. ![CB PE VLANs](./img/controller-bridge-and-port-extender-05.webp)First, configure the CB and PE devices. The configuration is identical to the previous example. Use this configuration for the CB device. ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=sfp-sfpplus2 /interface/bridge/port-controller set bridge=bridge1 cascade-ports=sfp-sfpplus1 switch=switch1 ``` Use this configuration for the PE device. ```ros /interface/bridge/port-extender set control-ports=sfp-sfpplus4 switch=switch1 ``` After extended ports are successfully created and added to the bridge on the CB device, we can start configuring VLAN-related properties. First, configure access ports to their respective VLAN ID using a `pvid` property. Use a `print` command in the `/interface/bridge/port` menu to find out the exact interface name. ```ros /interface/bridge/port set [find interface=pe1-ether1] pvid=10 set [find interface=pe1-ether2] pvid=20 set [find interface=pe1-ether3] pvid=30 ``` Then add bridge VLAN entries and specify tagged, untagged ports. Note that there are two tagged ports - local port named sfp-sfpplus2 and extended port named pe1-sfpplus1. ```ros /interface/bridge/vlan add bridge=bridge1 tagged=pe1-sfpplus1,sfp-sfpplus2 untagged=pe1-ether1 vlan-ids=10 add bridge=bridge1 tagged=pe1-sfpplus1,sfp-sfpplus2 untagged=pe1-ether2 vlan-ids=20 add bridge=bridge1 tagged=pe1-sfpplus1,sfp-sfpplus2 untagged=pe1-ether3 vlan-ids=30 ``` At this point VLANs are configured and devices should be able to communicate through the ports. However, it is recommended to go even a step further and apply some additional filtering options. Enable port `ingress-filtering` on local bridge ports and use frame filtering based on the packet type with the `frame-types` setting. ```ros /interface/bridge/port set [find interface=pe1-ether1] frame-types=admit-only-untagged-and-priority-tagged set [find interface=pe1-ether2] frame-types=admit-only-untagged-and-priority-tagged set [find interface=pe1-ether3] frame-types=admit-only-untagged-and-priority-tagged set [find interface=pe1-sfpplus1] frame-types=admit-only-vlan-tagged set [find interface=sfp-sfpplus2] frame-types=admit-only-vlan-tagged ingress-filtering=yes ``` :::warning Port ingress VLAN filtering is not supported on extended ports. ::: ### Cascading multiple Port Extenders and using bonding interface In this example, two PE devices (CRS328-24P-4S+ and CRS326-24G-2S+) will be added to the CB (CRS317-1G-16S+). To increase throughput for upstream and cascade ports, [bonding interfaces](../../high-availability-solutions/bonding.md) will be created. See the network diagram below. ![Bonding Cascade](./img/controller-bridge-and-port-extender-06.webp) The CB and PE configuration is similar to the first example, the main difference is the bonding interface usage. First, configure the CB device - create a bonding interface for the cascade port, create a bridge and add any needed local bridge ports, lastly, enable the CB. Use the following commands: ```ros /interface/bonding add mode=802.3ad name=bond1 slaves=sfp-sfpplus1,sfp-sfpplus2 /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=sfp-sfpplus3 /interface/bridge/port-controller set bridge=bridge1 cascade-ports=bond1 switch=switch1 ``` Then configure the Port Extender 1 device. This device needs two bonding interfaces - the first one will be used as an upstream port and the second one will be a cascade port for the Port Extender 2 device. Additionally, configure one or multiple interfaces that should not be extended with the `excluded-ports` property (e.g. for out-of-band management purposes). In this example, all switch ports will be extended. ```ros /interface/bonding add mode=802.3ad name=bond1 slaves=sfp-sfpplus1,sfp-sfpplus2 add mode=802.3ad name=bond2 slaves=sfp-sfpplus3,sfp-sfpplus4 /interface/bridge/port-extender set control-ports=bond1,bond2 switch=switch1 ``` Last, configure the Port Extender 2 device - create a bonding interface and enable PE. Additionally, configure one or multiple `excluded-ports` if necessary. In this example, all switch ports will be extended. ```ros /interface/bonding add mode=802.3ad name=bond1 slaves=sfp-sfpplus1,sfp-sfpplus2 /interface/bridge/port-extender set control-ports=bond1 switch=switch1 ``` Now the CRS317-1G-16S+ device has extended its ports with additional 48 Gigabit Ethernet ports and packet forwarding can be achieved between all bridged ports. Use the `monitor` command in the device menu to see the PE device connection path. Also, use the `print` command in the port menu to see which PE interfaces are used as upstream and cascade ports. ```ros [admin@Controller_Bridge] > /interface/bridge/port-controller/device/monitor [find] name: pe1 pe2 status: active active connected-via-ports: bond1==pe1-cntrl-bond1 bond1==pe1-cntrl-bond1 pe1-cntrl-bond2==pe2-cntrl-bond1 connected-via-devs: controller controller pe1 [admin@Controller_Bridge] > /interface/bridge/port-controller/port/print where running or upstream-port Flags: I - inactive, X - disabled, R - running, U - upstream-port, C - cascade-port # NAME DEVICE 0 R pe1-ether2 pe1 1 R pe1-ether3 pe1 2 R pe1-ether4 pe1 3 U pe1-sfpplus1 pe1 4 U pe1-sfpplus2 pe1 5 RC pe1-sfpplus3 pe1 6 RC pe1-sfpplus4 pe1 7 R pe2-ether1 pe2 8 R pe2-ether2 pe2 9 R pe2-ether3 pe2 10 R pe2-ether4 pe2 11 U pe2-sfpplus1 pe2 12 U pe2-sfpplus2 pe2 ``` ### Configuration modification and removal In certain situations, CB and PE device configuration needs to be adjusted (e.g. PE device needs new control ports) or removed completely. To modify the PE device configuration, all related PE device configuration should be removed from the CB device first. Only then can the new configuration be applied. First, to remove PE configuration from CB, disable the PE using the following command: ```ros /interface/bridge/port-extender/set switch=none control-ports="" excluded-ports="" ``` Then, on the CB device, remove the related bridge and other RouterOS configuration where PE interfaces were used (e.g., see the export from `/interface/bridge/port` and `/interface/bridge/vlan` menus). For example, to remove all bridge ports from a specific PE device, use the command below: ```ros /interface/bridge/port/remove [find interface~"pe1"] ``` Once the configuration is removed, PE can be removed from the CB device list. This command will also automatically remove all the PE device interfaces from the CB interface list. In case some PE interface configuration is still applied on the CB, it will not be valid anymore. Use the `print` command to find out the PE device name. ```ros /interface/bridge/port-controller/device/remove [find name=pe1] ``` --- ## CRS1xx/2xx series switches examples --- Basic use cases and configuration examples for Cloud Router Switch features. :::info This article applies to CRS1xx and CRS2xx series switches and not to [MikroTik devices with Marvell Prestera switch](../marvell-prestera-switch-chip-features.md) (e.g. CRS3xx series switches). ::: ## Port switching --- To set up port switching on CRS1xx/2xx series switches, check the [Bridge Hardware Offloading](../#bridge-hardware-offloading) page. :::danger It is possible to create multiple isolated switch groups by using multiple bridges with enabled hardware offloading; this is possible only on CRS1xx/2xx series switches. For more complex setups (for example, VLAN filtering) you should use the port isolation feature instead. ::: ## Management access configuration --- In general, switches are only supposed to forward packets by using the built-in switch chip, but not allow access to the device itself for security reasons. It is possible to use the device's serial port for management access, but in most cases, such an access method is not desired and access using an IP address is more suitable. In such cases, you will need to configure management access. In all types of management access, it is assumed that ports must be switched together. Use the following commands to switch together the required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether3 hw=yes add bridge=bridge1 interface=ether4 hw=yes add bridge=bridge1 interface=ether5 hw=yes ``` You should also assign an IP address to the bridge interface so the device is reachable using an IP address (the device is also reachable using a MAC address): ```ros /ip/address add address=192.168.88.1/24 interface=bridge1 ``` ### Untagged If invalid VLAN filtering is not enabled, management access to the device using tagged or untagged (**VLAN 0**) traffic is already allowed from any port, though this is not a good practice; this can cause security issues and can cause the device's CPU to be overloaded in certain situations (most commonly with a broadcast type of traffic). If you intend to use invalid VLAN filtering (which you should), then ports from which you are going to access the switch must be added to the VLAN table for untagged (**VLAN 0**) traffic, for example, in case you want to access the switch from **ether2**: ```ros /interface/ethernet/switch/vlan add vlan-id=0 ports=ether2,switch1-cpu ``` ### Tagged Allowing only tagged traffic to have management access to the device through a specific port is a much better practice. For example, to allow only **VLAN99** to access the device through **ether2**, you should first add an entry to the VLAN table, which will allow the selected port and the CPU port (**switch1-cpu**) to forward the selected VLAN ID, therefore allowing management access: ```ros /interface/ethernet/switch/vlan add ports=ether2,switch1-cpu vlan-id=99 ``` Packets that will be sent out from the CPU, for example, ping replies, will not have a VLAN tag, to solve this you need to specify which ports should always send out packets with a VLAN tag for a specific VLAN ID: ```ros /interface/ethernet/switch/egress-vlan-tag add tagged-ports=ether2,switch1-cpu vlan-id=99 ``` After a valid VLAN99 configuration has been set up, you can enable unknown/invalid VLAN filtering, which will not allow management access through different ports than specified in the VLAN table: ```ros /interface/ethernet/switch set drop-if-invalid-or-src-port-not-member-of-vlan-on-ports=ether2,ether3,ether4,ether5 ``` In this example VLAN99 will be used to access the device. A VLAN interface on the bridge must be created and an IP address must be assigned to it. ```ros /interface/vlan add interface=bridge1 name=MGMT vlan-id=99 /ip/address add address=192.168.99.1/24 interface=MGMT ``` ## VLAN --- :::danger Risk of Lockout It is highly recommended to have a Serial Console cable tested and ready before configuring VLANs. Misconfigurations can easily lock you out of the CPU or your connected port. ::: :::tip Troubleshooting Cached MAC Addresses Some changes may appear delayed because of already-learned MAC addresses. If traffic isn't flowing as expected after a change, flush the Unicast Forwarding Database: `/interface/ethernet/switch/unicast-fdb/flush` ::: :::info Architectural Best Practice Using multiple hardware-offloaded bridges is a fast way to achieve simple port isolation, but it limits advanced VLAN functionality on the CRS switch-chip. For advanced setups, use a **single bridge** for all ports, configure your VLANs, and isolate port groups using port isolation profiles. ::: ### Port Based VLAN :::warning For CRS3xx series devices, you must use bridge VLAN filtering; you can read more about it in the [Bridge VLAN Filtering](../index.md#bridge-vlan-filtering) section. ::: #### Example 1 (Trunk and Access ports) ![Access Ports](./img/crs1xx-2xx-series-switches-examples-01.webp) Switch together the required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes ``` Specify the VLAN ID that the switch must set on untagged (VLAN0) traffic for each access port: ```ros /interface/ethernet/switch/ingress-vlan-translation add ports=ether6 customer-vid=0 new-customer-vid=200 add ports=ether7 customer-vid=0 new-customer-vid=300 add ports=ether8 customer-vid=0 new-customer-vid=400 ``` :::warning When an entry is created under `/interface/ethernet/switch/ingress-vlan-translation`, the switch chip will add a VLAN tag on ingress frames on the specified port. To remove the VLAN tag on the same port for egress frames, an `/interface/ethernet/switch/egress-vlan-tag` entry should be created for the same VLAN ID where only tagged ports are specified. If a specific VLAN is forwarded only between access ports, the `/interface/ethernet/switch/egress-vlan-tag` entry should still be created without any tagged ports. Another option is to create extra entries under the `/interface/ethernet/switch/egress-vlan-translation` menu to set untagged (VLAN0) traffic. ::: You must also specify which VLANs should be sent out to the trunk port with a VLAN tag. Use the tagged-ports property to set up a trunk port: ```ros /interface/ethernet/switch/egress-vlan-tag add tagged-ports=ether2 vlan-id=200 add tagged-ports=ether2 vlan-id=300 add tagged-ports=ether2 vlan-id=400 ``` Add entries to the VLAN table to specify VLAN memberships for each port and each VLAN ID: ```ros /interface/ethernet/switch/vlan add ports=ether2,ether6 vlan-id=200 add ports=ether2,ether7 vlan-id=300 add ports=ether2,ether8 vlan-id=400 ``` After a valid VLAN configuration has been set up, you can enable unknown/invalid VLAN filtering: ```ros /interface/ethernet/switch set drop-if-invalid-or-src-port-not-member-of-vlan-on-ports=ether2,ether6,ether7,ether8 ``` :::warning It is possible to use the built-in switch chip and the CPU at the same time to create a Switch-Router setup, where a device acts as a switch and as a router simultaneously. ::: #### Example 2 (Trunk and Hybrid Ports) ![Hybrid Ports](./img/crs1xx-2xx-series-switches-examples-02.webp) Switch together the required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes ``` Specify the VLAN ID that the switch must set on untagged (VLAN0) traffic for each access port: ```ros /interface/ethernet/switch/ingress-vlan-translation add ports=ether6 customer-vid=0 new-customer-vid=200 add ports=ether7 customer-vid=0 new-customer-vid=300 add ports=ether8 customer-vid=0 new-customer-vid=400 ``` By specifying ports as tagged-ports, the switch will always send out packets as tagged packets with the corresponding VLAN ID. Add appropriate entries according to the diagram above: ```ros /interface/ethernet/switch/egress-vlan-tag add tagged-ports=ether2,ether7,ether8 vlan-id=200 add tagged-ports=ether2,ether6,ether8 vlan-id=300 add tagged-ports=ether2,ether6,ether7 vlan-id=400 ``` Add entries to the VLAN table to specify VLAN memberships for each port and each VLAN ID: ```ros /interface/ethernet/switch/vlan add ports=ether2,ether6,ether7,ether8 vlan-id=200 learn=yes add ports=ether2,ether6,ether7,ether8 vlan-id=300 learn=yes add ports=ether2,ether6,ether7,ether8 vlan-id=400 learn=yes ``` After a valid VLAN configuration has been set up, you can enable unknown/invalid VLAN filtering: ```ros /interface/ethernet/switch set drop-if-invalid-or-src-port-not-member-of-vlan-on-ports=ether2,ether6,ether7,ether8 ``` ### Protocol Based VLAN ![Protocol Based VLAN](./img/crs1xx-2xx-series-switches-examples-03.webp) Switch together the required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes ``` Set VLAN for IP and ARP protocols: ```ros /interface/ethernet/switch/protocol-based-vlan add port=ether2 protocol=arp set-customer-vid-for=all new-customer-vid=0 add port=ether6 protocol=arp set-customer-vid-for=all new-customer-vid=200 add port=ether2 protocol=ip set-customer-vid-for=all new-customer-vid=0 add port=ether6 protocol=ip set-customer-vid-for=all new-customer-vid=200 ``` Set VLAN for IPX protocol: ```ros /interface/ethernet/switch/protocol-based-vlan add port=ether2 protocol=ipx set-customer-vid-for=all new-customer-vid=0 add port=ether7 protocol=ipx set-customer-vid-for=all new-customer-vid=300 ``` Set VLAN for AppleTalk AARP and AppleTalk DDP protocols: ```ros /interface/ethernet/switch/protocol-based-vlan add port=ether2 protocol=0x80F3 set-customer-vid-for=all new-customer-vid=0 add port=ether8 protocol=0x80F3 set-customer-vid-for=all new-customer-vid=400 add port=ether2 protocol=0x809B set-customer-vid-for=all new-customer-vid=0 add port=ether8 protocol=0x809B set-customer-vid-for=all new-customer-vid=400 ``` ### MAC Based VLAN :::danger Internally, all MAC addresses in MAC-based VLANs are hashed. Certain MAC addresses can have the same hash, which will prevent a MAC address from being loaded into the switch chip if the hash matches with a hash from a MAC address that has been already loaded, for this reason, it is recommended to use Port-based VLANs in combination with MAC-based VLANs. This is a hardware limitation. ::: ![MAC Based VLAN](./img/crs1xx-2xx-series-switches-examples-04.webp) Switch together the required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether7 hw=yes ``` Enable MAC-based VLAN translation on an access port: ```ros /interface/ethernet/switch/port set ether7 allow-fdb-based-vlan-translate=yes ``` Add MAC-to-VLAN mapping entries in the MAC-based VLAN table: ```ros /interface/ethernet/switch/mac-based-vlan add src-mac=A4:12:6D:77:94:43 new-customer-vid=200 add src-mac=84:37:62:DF:04:20 new-customer-vid=300 add src-mac=E7:16:34:A1:CD:18 new-customer-vid=400 ``` Add VLAN200, VLAN300, and VLAN400 tagging on the ether2 port to create it as a VLAN trunk port: ```ros /interface/ethernet/switch/egress-vlan-tag add tagged-ports=ether2 vlan-id=200 add tagged-ports=ether2 vlan-id=300 add tagged-ports=ether2 vlan-id=400 ``` Additionally, add entries to the VLAN table, specify VLAN membership for each port, and enable unknown/invalid VLAN filtering, see an example below - Unknown/Invalid VLAN filtering. This is required for network setups where more interfaces are added to the bridge, as it allows defining VLAN boundaries. ### InterVLAN Routing ![VLAN Routing](./img/crs1xx-2xx-series-switches-examples-05.webp) InterVLAN routing configuration consists of two main parts – VLAN tagging in switch-chip and routing in RouterOS. This configuration can be used in many applications by combining it with a DHCP server, Hotspot, PPP, and other features for each VLAN. Switch together the required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes ``` Set VLAN tagging on the CPU port for all VLANs to make packets tagged before they are routed: ```ros /interface/ethernet/switch/egress-vlan-tag add tagged-ports=switch1-cpu vlan-id=200 add tagged-ports=switch1-cpu vlan-id=300 add tagged-ports=switch1-cpu vlan-id=400 ``` Add ingress VLAN translation rules to ensure that the correct VLAN ID assignment is done on access ports: ```ros /interface/ethernet/switch/ingress-vlan-translation add ports=ether6 customer-vid=0 new-customer-vid=200 add ports=ether7 customer-vid=0 new-customer-vid=300 add ports=ether8 customer-vid=0 new-customer-vid=400 ``` Create the VLAN interfaces on top of the bridge interface: ```ros /interface/vlan add name=VLAN200 interface=bridge1 vlan-id=200 add name=VLAN300 interface=bridge1 vlan-id=300 add name=VLAN400 interface=bridge1 vlan-id=400 ``` :::danger Make sure the VLAN interfaces are created on top of the bridge interface instead of any of the physical interfaces. If the VLAN interfaces are created on a slave interface, then the packet might not be received correctly, and therefore routing might fail. More detailed information can be found in the [VLAN interface on a slave interface](layer2-misconfiguration.md#vlan-interface-on-a-slave-interface) manual page. ::: Add IP addresses on created VLAN interfaces. In this example, three 192.168.x.1 addresses are added to VLAN200, VLAN300, and VLAN400 interfaces: ```ros /ip/address add address=192.168.20.1/24 interface=VLAN200 add address=192.168.30.1/24 interface=VLAN300 add address=192.168.40.1/24 interface=VLAN400 ``` ### Unknown/Invalid VLAN filtering VLAN membership is defined in the VLAN table. Adding entries with VLAN ID and ports makes that VLAN traffic valid on those ports. After a valid VLAN configuration has been set up, unknown/invalid VLAN filtering can be enabled. This VLAN filtering configuration example applies to the InterVLAN Routing setup. ```ros /interface/ethernet/switch/vlan add ports=switch1-cpu,ether6 vlan-id=200 add ports=switch1-cpu,ether7 vlan-id=300 add ports=switch1-cpu,ether8 vlan-id=400 ``` - Option 1: disable invalid VLAN forwarding on specific ports (more common). ```ros /interface/ethernet/switch set drop-if-invalid-or-src-port-not-member-of-vlan-on-ports=ether6,ether7,ether8 ``` - Option 2: disable invalid VLAN forwarding on all ports. ```ros /interface/ethernet/switch set forward-unknown-vlan=no ``` :::danger Using multiple bridges on a single switch chip with enabled unknown/invalid VLAN filtering can cause unexpected behavior. You should always use a single bridge configuration whenever using VLAN filtering. If port isolation is required, then the port isolation feature should be used instead of using multiple bridges. ::: ### VLAN Tunneling (Q-in-Q) This example covers a typical VLAN tunneling use case where service provider devices add another VLAN tag for independent forwarding while allowing customers to use their own VLANs. :::warning This example contains only the Service VLAN tagging part. It is recommended to additionally set Unknown/Invalid VLAN filtering configuration on ports. ::: ![QinQ](./img/crs1xx-2xx-series-switches-examples-06.webp) **CRS-1**: The first switch on the edge of the service provider network has to properly identify traffic from the customer VLAN ID on port and assign a new service VLAN ID with ingress VLAN translation rules. VLAN trunk port configuration for service provider VLAN tags is in the same `egress-vlan-tag` table. The main difference from basic Port-Based VLAN configuration is that the CRS switch-chip has to be set to do forwarding according to service (*outer*) VLAN ID instead of customer (*inner*) VLAN ID. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 hw=yes add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether9 hw=yes /interface/ethernet/switch/ingress-vlan-translation add customer-vid=200 new-service-vid=400 ports=ether1 add customer-vid=300 new-service-vid=500 ports=ether2 /interface/ethernet/switch/egress-vlan-tag add tagged-ports=ether9 vlan-id=400 add tagged-ports=ether9 vlan-id=500 /interface/ethernet/switch set bridge-type=service-vid-used-as-lookup-vid ``` **CRS-2**: The second switch in the service provider network requires only switched ports to do forwarding according to the service (*outer*) VLAN ID instead of the customer (*inner*) VLAN ID. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether9 hw=yes add bridge=bridge1 interface=ether10 hw=yes /interface/ethernet/switch set bridge-type=service-vid-used-as-lookup-vid ``` **CRS-3**: The third switch has a similar configuration to CRS-1: - Ports in a switch group using a bridge. - Ingress VLAN translation rules to define new service VLAN assignments on ports. - tagged-ports for service provider VLAN trunks. - CRS switch-chip set to use service VLAN ID in switching lookup. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether3 hw=yes add bridge=bridge1 interface=ether4 hw=yes add bridge=bridge1 interface=ether10 hw=yes /interface/ethernet/switch/ingress-vlan-translation add customer-vid=200 new-service-vid=400 ports=ether3 add customer-vid=300 new-service-vid=500 ports=ether4 /interface/ethernet/switch/egress-vlan-tag add tagged-ports=ether10 vlan-id=400 add tagged-ports=ether10 vlan-id=500 /interface/ethernet/switch set bridge-type=service-vid-used-as-lookup-vid ``` ### CVID Stacking It is possible to use CRS1xx/CRS2xx series switches for CVID Stacking setups. CRS1xx/CRS2xx series switches are capable of VLAN filtering based on the outer tag of tagged packets that have two CVID tags (double CVID tag). These switches are also capable of adding another CVID tag on top of an existing CVID tag (CVID Stacking). For example, in a setup where **ether1** is receiving tagged packets with CVID 10, but it is required that **ether2** sends out these packets with another tag CVID 20 (VLAN10 inside VLAN20) while filtering out any other VLANs, the following must be configured: Switch together **ether1** and **ether2**: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 hw=yes add bridge=bridge1 interface=ether2 hw=yes ``` Set the switch to filter VLANs based on the service tag (0x88a8): ```ros /interface/ethernet/switch set bridge-type=service-vid-used-as-lookup-vid ``` Add a service tag SVID 20 to packets that have a CVID 10 tag on **ether1**: ```ros /interface/ethernet/switch/ingress-vlan-translation add customer-vid=10 new-service-vid=20 ports=ether1 ``` Specify **ether2** as the tagged/trunk port for SVID 20: ```ros /interface/ethernet/switch/egress-vlan-tag add tagged-ports=ether2 vlan-id=20 ``` Allow **ether1** and **ether2** to forward SVID 20: ```ros /interface/ethernet/switch/vlan add ports=ether1,ether2 vlan-id=20 ``` Override the SVID EtherType (0x88a8) to CVID EtherType (0x8100) on **ether2**: ```ros /interface/ethernet/switch/port set ether2 egress-service-tpid-override=0x8100 ingress-service-tpid-override=0x8100 ``` Enable unknown/invalid VLAN filtering: ```ros /interface/ethernet/switch set drop-if-invalid-or-src-port-not-member-of-vlan-on-ports=ether1,ether2 ``` :::warning Since the switch is set to look up VLAN ID based on the service tag, which is overridden with a different EtherType, VLAN filtering is only done on the outer tag of a packet; the inner tag is not checked. ::: ## Mirroring --- ![Mirroring](./img/crs1xx-2xx-series-switches-examples-07.webp) The Cloud Router Switches support three types of mirroring. Port-based mirroring can be applied to any switch-chip ports, VLAN-based mirroring works for all specified VLANs regardless of switch-chip ports, and MAC-based mirroring copies traffic sent or received from a specific device reachable from the port configured in the Unicast Forwarding Database. ### Port-Based Mirroring The first configuration sets the ether5 port as a mirror0 analyzer port for both ingress and egress mirroring. Mirrored traffic will be sent to this port. Port-based ingress and egress mirroring are enabled from the ether6 port. ```ros /interface/ethernet/switch set ingress-mirror0=ether5 egress-mirror0=ether5 /interface/ethernet/switch/port set ether6 ingress-mirror-to=mirror0 egress-mirror-to=mirror0 ``` ### VLAN Based Mirroring The second example requires ports to be switched in a group. Mirroring configuration sets the ether5 port as a mirror0 analyzer port and sets the mirror0 port to be used when mirroring from VLAN occurs. VLAN table entry enables mirroring only for VLAN 300 traffic between ether2 and ether7 ports. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether7 hw=yes /interface/ethernet/switch set ingress-mirror0=ether5 vlan-uses=mirror0 /interface/ethernet/switch/vlan add ports=ether2,ether7 vlan-id=300 learn=yes ingress-mirror=yes ``` ### MAC Based Mirroring The third configuration also requires ports to be switched as a group. Mirroring configuration sets the ether5 port as a mirror0 analyzer port and sets the mirror0 port to be used when mirroring from the Unicast Forwarding database occurs. The entry from the Unicast Forwarding database enables mirroring for packets with source or destination MAC address E7:16:34:A1:CD:18 from ether8 port. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether8 hw=yes /interface/ethernet/switch set ingress-mirror0=ether5 fdb-uses=mirror0 /interface/ethernet/switch/unicast-fdb add port=ether8 mirror=yes svl=yes mac-address=E7:16:34:A1:CD:18 ``` ## Trunking --- ![Trunking 3](./img/crs1xx-2xx-series-switches-examples-08.webp) Trunking in the Cloud Router Switches provides static link aggregation groups with hardware automatic failover and load balancing. The IEEE802.3ad and IEEE802.1ax compatible Link Aggregation Control Protocol is not supported yet. Up to 8 Trunk groups are supported with up to 8 Trunk member ports per Trunk group. Configuration requires a group of switched ports and an entry in the Trunk table: ```ros /interface/bridge add name=bridge1 protocol-mode=none /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes /interface/ethernet/switch/trunk add name=trunk1 member-ports=ether6,ether7,ether8 ``` This example also shows proper bonding configuration in RouterOS on the other end: ```ros /interface/bonding add name=bonding1 slaves=ether2,ether3,ether4 mode=balance-xor transmit-hash-policy=layer-2-and-3 ``` :::danger Bridge (R)STP is not aware of the underlying switch trunking configuration and some trunk ports can move to a discarding or blocking state. When trunking member ports are connected to other bridges, you should either disable the (R)STP or filter out any BPDU between trunked devices (e.g. with ACL rules). ::: ## Limited MAC Access per Port --- Disabling MAC learning and configuring static MAC addresses gives the ability to control what exact devices can communicate with CRS1xx/2xx switches and through them. Configuration requires a group of switched ports, disabled MAC learning on those ports, and static FDB entries: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether6 hw=yes learn=no unknown-unicast-flood=no add bridge=bridge1 interface=ether7 hw=yes learn=no unknown-unicast-flood=no /interface/ethernet/switch/unicast-fdb add mac-address=4C:5E:0C:00:00:01 port=ether6 svl=yes add mac-address=D4:CA:6D:00:00:02 port=ether7 svl=yes /interface/ethernet/switch/acl add action=drop src-mac-addr-state=sa-not-found src-ports=ether6,ether7 table=egress add action=drop src-mac-addr-state=static-station-move src-ports=ether6,ether7 table=egress ``` CRS1xx/2xx switches also allow learning one dynamic MAC per port to ensure only one end-user device is connected no matter its MAC address: ```ros /interface/ethernet/switch/port set ether6 learn-limit=1 set ether7 learn-limit=1 ``` ## Isolation --- ### Port Level Isolation ![Port Level Isolation](./img/crs1xx-2xx-series-switches-examples-09.webp) Port-level isolation is often used for Private VLAN, where: - One or multiple uplink ports are shared among all users for accessing the gateway or router. - Port group Isolated Ports is for guest users. Communication is through the uplink ports only. - Port group Community 0 is for department A. Communication is allowed between the group members and through uplink ports. - Port group Community X is for department X. Communication is allowed between the group members and through uplink ports. The Cloud Router Switches use port-level isolation profiles for Private VLAN implementation: - Uplink ports – port-level isolation profile 0 - Isolated ports – port-level isolation profile 1 - Community 0 ports - port-level isolation profile 2 - Community X (X \<= 30) ports - port-level isolation profile X **This example requires a group of switched ports. Assume that all ports used in this example are in one switch group.** ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes add bridge=bridge1 interface=ether9 hw=yes add bridge=bridge1 interface=ether10 hw=yes ``` The first part of port isolation configuration is setting the Uplink port – set a port profile to 0 for ether2: ```ros /interface/ethernet/switch/port set ether2 isolation-leakage-profile-override=0 ``` Then continue with setting isolation profile 1 on all isolated ports and adding the communication port for port isolation profile 1: ```ros /interface/ethernet/switch/port set ether5 isolation-leakage-profile-override=1 set ether6 isolation-leakage-profile-override=1 /interface/ethernet/switch/port-isolation add port-profile=1 ports=ether2 type=dst ``` Configuration to set Community 2 and Community 3 ports is similar: ```ros /interface/ethernet/switch/port set ether7 isolation-leakage-profile-override=2 set ether8 isolation-leakage-profile-override=2 /interface/ethernet/switch/port-isolation add port-profile=2 ports=ether2,ether7,ether8 type=dst /interface/ethernet/switch/port set ether9 isolation-leakage-profile-override=3 set ether10 isolation-leakage-profile-override=3 /interface/ethernet/switch/port-isolation add port-profile=3 ports=ether2,ether9,ether10 type=dst ``` ### Protocol Level Isolation ![Protocol Level Isolation](./img/crs1xx-2xx-series-switches-examples-10.webp) Protocol level isolation on CRS switches can be used to enhance network security. For example, restricting DHCP traffic between the users (ether2, ether3, ether4, ether5) and allowing it only to trusted DHCP server ports (ether1) can prevent security risks like DHCP spoofing attacks. The following example shows how to configure it on CRS. Switch together the required ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 hw=yes add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether3 hw=yes add bridge=bridge1 interface=ether4 hw=yes add bridge=bridge1 interface=ether5 hw=yes ``` Set the same Community port profile for all DHCP client ports. Community port profile numbers are from 2 to 30. ```ros /interface/ethernet/switch/port set ether2 isolation-leakage-profile-override=2 set ether3 isolation-leakage-profile-override=2 set ether4 isolation-leakage-profile-override=2 set ether5 isolation-leakage-profile-override=2 ``` And configure port isolation/leakage profile for selected Community (2) to allow DHCP traffic destined only to the port where the trusted DHCP server is located. Registration status and traffic-type properties have to be set empty to apply restrictions only for DHCP protocol. ```ros /interface/ethernet/switch/port-isolation add port-profile=2 protocol-type=dhcpv4 type=dst forwarding-type=bridged ports=ether1 registration-status="" traffic-type="" ``` ## Quality of Service (QoS) --- **QoS configuration schemes** MAC-based traffic scheduling and shaping: [MAC address in UFDB] -> [QoS Group] -> [Priority] -> [Queue] -> [Shaper] VLAN based traffic scheduling and shaping: [VLAN id in VLAN table] -> [QoS Group] -> [Priority] -> [Queue] -> [Shaper] Protocol based traffic scheduling and shaping: [Protocol in Protocol VLAN table] -> [QoS Group] -> [Priority] -> [Queue] -> [Shaper] PCP/DEI based traffic scheduling and shaping: [Switch port PCP/DEI mapping] -> [Priority] -> [Queue] -> [Shaper] DSCP based traffic scheduling and shaping: [QoS DSCP mapping] -> [Priority] -> [Queue] -> [Shaper] ### MAC-based traffic scheduling using internal Priority In Strict Priority scheduling mode, the highest priority queue is served first. The queue number represents the priority, and the queue with the highest queue number has the highest priority. Traffic is transmitted from the highest priority queue until the queue is empty, and then moves to the next highest priority queue, and so on. If no congestion is present at the egress port, a packet is transmitted as soon as it is received. If congestion occurs in the port where high-priority traffic keeps coming, the lower-priority queues starve. On all CRS switches, the scheme where MAC-based egress traffic scheduling is done according to internal Priority would be the following: [MAC address] -> [QoS Group] -> [Priority] -> [Queue]; In this example, host1 (E7:16:34:00:00:01) and host2 (E7:16:34:00:00:02) will have higher priority 1 and the rest of the hosts will have lower priority 0 for transmitted traffic on port ether7. Note that CRS has a maximum of 8 queues per port. ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes ``` Create a QoS group for use in UFDB: ```ros /interface/ethernet/switch/qos-group add name=group1 priority=1 ``` Add UFDB entries to match specific MACs on ether7 and apply the QoS group1: ```ros /interface/ethernet/switch/unicast-fdb add mac-address=E7:16:34:00:00:01 port=ether7 qos-group=group1 svl=yes add mac-address=E7:16:34:00:00:02 port=ether7 qos-group=group1 svl=yes ``` Configure ether7 port queues to work according to Strict Priority and QoS scheme only for the destination address: ```ros /interface/ethernet/switch/port set ether7 per-queue-scheduling="strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0" priority-to-queue=0:0,1:1 qos-scheme-precedence=da-based ``` ### MAC-based traffic shaping using internal Priority The scheme where MAC-based traffic shaping is done according to internal Priority would be as follows: [MAC address] -> [QoS Group] -> [Priority] -> [Queue] -> [Shaper]; In this example, unlimited traffic will have priority 0 and limited traffic will have priority 1 with a bandwidth limit of 10Mbit. Note that CRS has a maximum of 8 queues per port. Create a group of ports for switching: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes ``` Create a QoS group for use in UFDB: ```ros /interface/ethernet/switch/qos-group add name=group1 priority=1 ``` Add a UFDB entry to match a specific MAC on ether8 and apply QoS group1: ```ros /interface/ethernet/switch/unicast-fdb add mac-address=E7:16:34:A1:CD:18 port=ether8 qos-group=group1 svl=yes ``` Configure ether8 port queues to work according to Strict Priority and QoS scheme only for the destination address: ```ros /interface/ethernet/switch/port set ether8 per-queue-scheduling="strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0" priority-to-queue=0:0,1:1 qos-scheme-precedence=da-based ``` Apply bandwidth limit for queue1 on ether8: ```ros /interface/ethernet/switch/shaper add port=ether8 rate=10M target=queue1 ``` If the CRS switch supports Access Control Lists, this configuration is simpler: ```ros /interface/ethernet/switch/acl/policer add name=policer1 yellow-burst=100k yellow-rate=10M /interface/ethernet/switch/acl add mac-dst-address=E7:16:34:A1:CD:18 policer=policer1 ``` ### VLAN-based traffic scheduling + shaping using internal Priorities The best practice is to assign lower internal QoS Priority for traffic limited by shaper to also make it less important in the Strict Priority scheduler. (Higher priority should be more important and unlimited) In this example: Switch port ether6 is using a shaper to limit the traffic that comes from ether7 and ether8. When the link has reached its capacity, the traffic with the highest priority will be sent out first. VLAN10 -> QoS group0 = lowest priority VLAN20 -> QoS group1 = normal priority VLAN30 -> QoS group2 = highest priority ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether6 hw=yes add bridge=bridge1 interface=ether7 hw=yes add bridge=bridge1 interface=ether8 hw=yes ``` Create QoS groups for use in the VLAN table. ```ros /interface/ethernet/switch/qos-group add name=group0 priority=0 add name=group1 priority=1 add name=group2 priority=2 ``` Add VLAN entries to apply QoS groups for certain VLANs. ```ros /interface/ethernet/switch/vlan add ports=ether6,ether7,ether8 qos-group=group0 vlan-id=10 add ports=ether6,ether7,ether8 qos-group=group1 vlan-id=20 add ports=ether6,ether7,ether8 qos-group=group2 vlan-id=30 ``` Configure ether6, ether7, and ether8 port queues to work according to Strict Priority and QoS schemes only for VLAN-based QoS. ```ros /interface/ethernet/switch/port set ether6 per-queue-scheduling="strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0" priority-to-queue=0:0,1:1,2:2 qos-scheme-precedence=vlan-based set ether7 per-queue-scheduling="strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0" priority-to-queue=0:0,1:1,2:2 qos-scheme-precedence=vlan-based set ether8 per-queue-scheduling="strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0" priority-to-queue=0:0,1:1,2:2 qos-scheme-precedence=vlan-based ``` Apply a bandwidth limit on ether6. ```ros /interface/ethernet/switch/shaper add port=ether6 rate=10M ``` ### PCP-based traffic scheduling By default, CRS1xx/CRS2xx series devices will ignore the PCP/CoS/802.1p value and forward packets in a FIFO (First-In-First-Out) manner. When the device's internal queue is not full, then packets are sent in a FIFO manner, but as soon as a queue is filled, then higher-priority traffic can be sent out first. Let us consider a scenario where **ether1** and **ether2** are forwarding data to **ether3**, but when **ether3** is congested, then packets are going to be scheduled. We can configure the switch to hold the lowest priority packets until all higher priority packets are sent out. This is a very common scenario for VoIP type setups, where some traffic needs to be prioritized. To achieve such a behavior, switch together **ether1**, **ether2,** and **ether3** ports: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 hw=yes add bridge=bridge1 interface=ether2 hw=yes add bridge=bridge1 interface=ether3 hw=yes ``` Enable **Strict Policy** for each internal queue on each port: ```ros /interface/ethernet/switch/port set ether1,ether2,ether3 per-queue-scheduling="strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0,strict-priority:0" ``` Map each PCP value to an internal priority value, for convenience reasons, simply map PCP to an internal priority 1-to-1: ```ros /interface/ethernet/switch/port set ether1,ether2,ether3 pcp-based-qos-priority-mapping=0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7 ``` Since the switch will empty the largest queue first and you need the highest priority to be served first, you can assign this internal priority to a queue 1-to-1: ```ros /interface/ethernet/switch/port set ether1,ether2,ether3 priority-to-queue=0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7 ``` Finally, set each switch port to schedule packets based on the PCP value: ```ros /interface/ethernet/switch/port set ether1,ether2,ether3 qos-scheme-precedence=pcp-based ``` ## Bandwidth Limiting --- Both Ingress Port policer and Shaper provide bandwidth-limiting features for CRS switches. - Ingress Port Policer sets RX limit on port: ```ros /interface/ethernet/switch/ingress-port-policer add port=ether5 meter-unit=bit rate=10M ``` - Shaper sets TX limit on a port. ```ros /interface/ethernet/switch/shaper add port=ether5 meter-unit=bit rate=10M ``` ## Traffic Storm Control --- The same Ingress Port policer also can be used for traffic storm control to prevent disruptions on Layer 2 ports caused by broadcast, multicast, or unicast traffic storms. - Broadcast storm control example on the ether5 port with a 500 packet limit per second: ```ros /interface/ethernet/switch/ingress-port-policer add port=ether5 rate=500 meter-unit=packet packet-types=broadcast ``` - Example with multiple packet types which include ARP and ND protocols and unregistered multicast traffic. Unregistered multicast is traffic that is not defined in the Multicast Forwarding Database. ```ros /interface/ethernet/switch/ingress-port-policer add port=ether5 rate=5k meter-unit=packet packet-types=broadcast,arp-or-nd,unregistered-multicast ``` ## See also --- - [Basic VLAN switching](./basic-vlan-switching.md) - [Bridge Hardware Offloading](../#bridge-hardware-offloading) - [Spanning Tree Protocol](./spanning-tree-protocol.md) - [IGMP Snooping](./bridge-igmp-mld-snooping.md) - [DHCP Snooping and Option 82](../#dhcp-snooping-and-dhcp-option-82) - [MTU on RouterBOARD](../../hardware/mtu-in-routeros.md) - [Layer2 misconfiguration](./layer2-misconfiguration.md) --- ## Bridging and Switching Case Studies import DocCardList from '@theme/DocCardList'; These case studies show common RouterOS bridging and switching designs, including VLAN switching, IGMP and MLD snooping, spanning tree, loop protection, and switch-chip behavior. Use them as practical examples for Layer 2 deployments and troubleshooting. --- ## Layer2 misconfiguration --- There are certain configurations that are known to have major flaws by design and should be avoided by all means possible. Misconfigured Layer2 can sometimes cause hard-to-detect network errors, random performance drops, certain segments of a network to be unreachable, certain networking services to be malfunctioning, or a complete network failure. This page will contain some common and not so very common configurations that will cause issues in your network. ## Bridges on a single switch chip --- Consider the following scenario. You have a device with a built-in switch chip and you need to isolate certain ports from each other. For this reason, you have created multiple bridges and enabled hardware offloading on them. Since each bridge is located on a different Layer2 domain, Layer2 frames will not be forwarded between these bridges. As a result, ports in each bridge are isolated from other ports on a different bridge. ### Configuration ```ros /interface/bridge add name=bridge1 add name=bridge2 /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 add bridge=bridge2 interface=ether3 add bridge=bridge2 interface=ether4 ``` ### Problem After a simple performance test, you might notice that one bridge is capable of forwarding traffic at wire speed while the second, third, etc. bridge is not able to forward as much data as the first bridge. Another symptom might be that there exists a huge latency for packets that need to be routed. After a quick inspection, you might notice that the CPU is always at full load. This is because hardware offloading is not available on all bridges, but is available only on one bridge. By checking the hardware offloading status, you will notice that only one bridge has it active: ```ros [admin@MikroTik] > /interface/bridge/port/print Flags: X - disabled, I - inactive, D - dynamic, H - hw-offload # INTERFACE BRIDGE HW 0 H ether1 bridge1 yes 1 H ether2 bridge1 yes 2 ether3 bridge2 yes 3 ether4 bridge2 yes ``` The reason why only one bridge has the hardware offloading flag available is that the device does not support port isolation. If port isolation is not supported, then only one bridge will be able to offload the traffic to the switch chip. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Missing "H" flag to bridge ports. - Low throughput. - High CPU usage. ### Solution Not all devices support port isolation. Currently only CRS1xx/CRS2xx series devices support it and only 7 isolated and hardware offloaded bridges are supported at the same time. Other devices will have to use the CPU to forward the packets on other bridges. This is usually a hardware limitation and a different device might be required. The Bridge split-horizon parameter is a software feature that disables hardware offloading and when using bridge filter rules you need to enable forwarding of all packets to the CPU, which requires the hardware offloading to be disabled. You can control which bridge will be hardware offloaded with the `hw=yes` flag and by setting `hw=no` to other bridges, for example: ```ros /interface/bridge/port/set [find where bridge=bridge1] hw=no /interface/bridge/port/set [find where bridge=bridge2] hw=yes ``` Sometimes it is possible to restructure a network topology to use VLANs, which is the proper way to isolate Layer2 networks. ## Packet flow with hardware offloading and MAC learning --- Consider the following scenario: you set up a bridge and have enabled hardware offloading in order to maximize the throughput for your device; as a result, your device is working as a switch, but you want to use [Sniffer](../../diagnostics-monitoring-and-troubleshooting/packet-sniffer.md) or [Torch](../../diagnostics-monitoring-and-troubleshooting/torch.md) tools for debugging purposes, or maybe you want to implement packet logging. ### Configuration ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 hw=yes interface=ether1 learn=yes add bridge=bridge1 hw=yes interface=ether2 learn=yes ``` ### Problem When running [Sniffer](../../diagnostics-monitoring-and-troubleshooting/packet-sniffer.md) or [Torch](../../diagnostics-monitoring-and-troubleshooting/torch.md) tools to capture packets, you might notice that barely any packets are visible, only some unicast packets, but mostly broadcast/multicast packets are captured, while the interfaces report that much larger traffic is flowing through certain interfaces than the traffic that was captured. If you add two or more Ethernet interfaces to a bridge and enable [Hardware Offloading](../#bridge-hardware-offloading), then the switch chip will be used to forward packets between ports. To understand why only some packets are captured, we must first examine how the switch chip is interconnected with the CPU. In this example, we can use a block diagram from a generic 5-Port Ethernet router: ![Switch Chip Block Diagram](./img/layer2-misconfiguration-01.webp) For this device, each Ethernet port is connected to the switch chip and the switch chip is connected to the CPU using the CPU port (sometimes called the **switch-cpu** port). For packets to be visible in Sniffer or Torch tools, the packet must be sent from an Ethernet port to the CPU port, this means that the packet must be destined to the CPU port (destination MAC address of the packet matches the bridge's MAC address) or the packet's MAC address has not been learnt (packet is flooded to all ports), this behavior is because of **MAC learning**. The switch chip keeps a list of MAC addresses and ports called the **Host table**. Whenever a packet needs to be forwarded, the switch chip checks the packet's destination MAC address against the hosts table to find which port it should use to forward the packet. If the switch chip cannot find the destination MAC address, then the packet is flooded to all ports (including the CPU port). In situations where a packet is supposed to be forwarded from, for example, ether1 to ether2 and the MAC address for the device behind ether2 is in the host table, then the packet is never sent to the CPU and therefore will not be visible to Sniffer or Torch tools. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Packets not visible by Sniffer or Torch tool. - Filter rules not working. ### Solution Packets with a destination MAC address that has been learned will not be sent to the CPU since the packets are not being flooded to all ports. If you do need to send certain packets to the CPU for a packet analyzer or a firewall, then it is possible to copy or redirect the packet to the CPU by using ACL rules. Below is an example of how to send a copy of packets that are meant for **4C:5E:0C:4D:12:4B**: ```ros /interface/ethernet/switch/rule add copy-to-cpu=yes dst-mac-address=4C:5E:0C:4D:12:4B/FF:FF:FF:FF:FF:FF ports=ether1 switch=switch1 ``` :::warning If the packet is sent to the CPU, then the packet must be processed by the CPU; this increases the CPU load. ::: ## LAG interfaces and load balancing --- Consider the following scenario: you have created a LAG interface to increase total bandwidth between 2 network nodes; usually, these are switches. For testing purposes to make sure that the LAG interface is working properly, you have attached two servers that transfer data, most commonly the well-known network performance measurement tool [Iperf](https://en.wikipedia.org/wiki/Iperf) is used to test such setups. For example, you might have made a LAG interface out of two Gigabit Ethernet ports, which gives you a virtual interface that can load balance traffic over both interfaces and theoretically reach 2Gbps throughput, while the servers are connected using a 10Gbps interface, for example, SFP+. ![LACP Setup](./img/layer2-misconfiguration-02.webp) ### Configuration The following configuration is relevant to **SW1** and **SW2**: ```ros /interface/bonding add mode=802.3ad name=bond1 slaves=ether1,ether2 /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=bond1 add bridge=bridge1 interface=sfp-sfpplus1 ``` ### Problem After initial tests, you immediately notice that your network throughput never exceeds the 1Gbps limit even though the CPU load on the servers is low as well as on the network nodes (switches in this case), but the throughput is still limited to only 1Gbps. The reason behind this is that LACP (802.ad) uses transmit hash policy in order to determine if traffic can be balanced over multiple LAG members, in this case, a LAG interface does not create a 2Gbps interface, but rather an interface that can balance traffic over multiple slave interfaces whenever it is possible. For each packet a transmit hash is generated, this determines through which LAG member the packet will be sent, this is needed in order to avoid packets being out of order, there is an option to select the transmit hash policy, usually, there is an option to choose between Layer2 (MAC), Layer3 (IP) and Layer4 (Port), in RouterOS, this can be selected by using the `transmit-hash-policy` parameter. In this case, the transmit hash is the same since you are sending packets to the same destination MAC address, as well as the same IP address and Iperf uses the same port as well, this generates the same transmit hash for all packets and load balancing between LAG members is not possible. Note that packets will not always get balanced over LAG members even though the destination is different, this is because the standardized transmit hash policy can generate the same transmit hash for different destinations, for example, 192.168.0.1/192.168.0.2 will get balanced, but 192.168.0.2/192.168.0.4 will **NOT** get balanced in case `layer2-and-3` transmit hash policy is used and the destination MAC address is the same. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Traffic going through only one LAG member. ### Solution Choose the proper transmit hash policy and test your network's throughput properly. The simplest way to test such setups is to use multiple destinations, for example, instead of sending data to just one server, send data to multiple servers. This will generate a different transmit hash for each packet and will make load balancing across LAG members possible. For some setups, you might want to change the bonding interface mode to increase the total throughput. For UDP traffic `balance-rr` mode might be sufficient, but can cause issues for TCP traffic. You can read more about selecting the right mode for your setup [here](../../high-availability-solutions/bonding.md#bonding-modes). ## VLAN interface on a slave interface --- Consider the following scenario: you have created a bridge and you want a DHCP Server to give out IP addresses only to certain tagged VLAN traffic, for this reason, you have created a VLAN interface, specified a VLAN ID and created a DHCP Server on it, but for some reason, it is not working properly. ### Configuration ```ros /interface/bridge add name=bridge1 /interface/bridge/port add interface=ether1 bridge=bridge1 add interface=ether2 bridge=bridge1 /interface/vlan add name=VLAN99 interface=ether1 vlan-id=99 /ip/pool add name=VLAN99_POOL range=192.168.99.100-192.168.99.200 /ip/address/add address=192.168.99.1/24 interface=VLAN99 /ip/dhcp-server add interface=VLAN99 address-pool=VLAN99_POOL disabled=no /ip/dhcp-server/network add address=192.168.99.0/24 gateway=192.168.99.1 dns-server=192.168.99.1 ``` ### Problem When you add an interface to a bridge, the bridge becomes the master interface and all bridge ports become slave ports. This means that all traffic that is received on a bridge port is captured by the bridge interface and all traffic is forwarded to the CPU using the bridge interface instead of the physical interface. As a result, a VLAN interface that is created on a slave interface will never capture any traffic at all since it is immediately forwarded to the master interface before any packet processing is being done. The usual side effect is that some DHCP clients receive IP addresses and some don't. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - DHCP Client/Server not working properly. - Device is unreachable. - The device behind a bridge is unreachable with tagged traffic. ### Solution Change the interface on which the VLAN interface will be listening for traffic, and change it to the master interface: ```ros /interface/vlan/set VLAN99 interface=bridge1 ``` ## VLAN on a bridge in a bridge --- Consider the following scenario: you have a set of interfaces (don't have to be physical interfaces) and you want all of them to be in the same Layer2 segment. The solution is to add them to a single bridge, but you require that traffic from one port tags all traffic into a certain VLAN. This can be done by creating a VLAN interface on top of the bridge interface and by creating a separate bridge that contains this newly created VLAN interface and an interface that is supposed to add a VLAN tag to all received traffic. A network diagram can be found below: ![VLAN on Bridge in Bridge](./img/layer2-misconfiguration-03.webp) ### Configuration ```ros /interface/bridge add name=bridge1 add name=bridge2 /interface/vlan add interface=bridge1 name=VLAN vlan-id=99 /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 add bridge=bridge2 interface=VLAN add bridge=bridge2 interface=ether3 ``` ### Problem To better understand the underlying problems, let's first look at the bridge host table. ```ros [admin@switch] /interface/bridge/host/print where !local Flags: X - disabled, I - invalid, D - dynamic, L - local, E - external # MAC-ADDRESS VID ON-INTERFACE BRIDGE 0 D CC:2D:E0:E4:B3:A1 ether1 bridge1 1 D CC:2D:E0:E4:B3:A2 ether2 bridge1 2 D CC:2D:E0:E4:B3:A1 VLAN bridge2 3 D CC:2D:E0:E4:B3:A2 VLAN bridge2 4 D CC:2D:E0:E4:B3:A3 ether3 bridge2 ``` Devices on **ether1** and **ether2** need to send tagged packets with VLAN-ID 99 in order to reach the host on **ether3** (other packets do not get passed towards the VLAN interface and further bridged with ether3). We can see in the host table that **bridge2** has learned these hosts. Packets coming from **ether3** to **ether1** will be correctly sent out tagged and traffic will not be flooded in **bridge1**. But since MAC learning is only possible between bridge ports and not on interfaces that are created on top of the bridge interface, packets sent from **ether2** to **ether3** will be flooded in **bridge1**. Also if a device behind **ether3** is using (R)STP, then **ether1** and **ether2** will send out tagged BPDUs which violate the IEEE 802.1W standard. Because of the broken MAC learning functionality and broken (R)STP, this setup and configuration must be avoided. It is also known that in some setups this kind of configuration can prevent you from connecting to the device by using MAC telnet. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Port blocked by RSTP. - Loops in the network. - Port flapping. - Traffic is flooded to all ports. - MAC telnet is unable to connect. - Device is inaccessible. ### Solution Use bridge VLAN filtering. The proper way to tag traffic is to assign a VLAN ID whenever traffic enters a bridge. This behavior can easily be achieved by specifying a **PVID** value for a bridge port and specifying which ports are **tagged** (trunk) ports and which are **untagged** (access) ports. Below is an example of how such a setup should have been configured: ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=ether3 pvid=99 /interface/bridge/vlan add bridge=bridge1 tagged=ether1,ether2 untagged=ether3 vlan-ids=99 ``` :::danger By enabling `vlan-filtering` you will be filtering out traffic destined for the CPU, before enabling VLAN filtering you should make sure that you set up a [Management port](../#management-access-configuration). ::: ## VLAN in a bridge with a physical interface --- Very similar case to [VLAN on a bridge in a bridge](layer2-misconfiguration.md#vlan-on-a-bridge-in-a-bridge). The most popular use case is when you want to bridge a physical interface with a VLAN (simplified trunk/access port setup). In such a setup you might want to send out tagged traffic on one side and untagged on the other side. To accomplish this, you create a VLAN interface on the trunk port (the tagged side), then create a bridge and add both the VLAN interface and the physical interface (the untagged side) as bridge ports. ### Configuration ```ros /interface/vlan add interface=ether1 name=VLAN99 vlan-id=99 /interface/bridge add name=bridge1 /interface/bridge/port add interface=ether2 bridge=bridge1 add interface=VLAN99 bridge=bridge1 ``` ### Problem This setup and configuration will work in most cases, but it violates the IEEE 802.1W standard when (R/M)STP is used. If this is the only device in your Layer2 domain, then this should not cause problems, but problems can arise when there are other vendor switches. The reason for this is that RSTP on a bridge interface is enabled by default, allowing Bridge Protocol Data Units (BPDUs) to be sent from each bridge port. While **ether2** transmits BPDUs correctly without tagging, **VLAN99** interface, being a bridge port, sends tagged BPDUs over ether1. Not all switches can understand tagged BPDUs. Precautions should be made with this configuration in a more complex network where there are multiple network topologies for certain (group of) VLANs. This is relevant to MSTP and PVSTP(+) with mixed vendor devices. In a ring-like topology with multiple network topologies for certain VLANs, one port from the switch will be blocked, but in MSTP and PVSTP(+) a path can be opened for a certain VLAN, in such a situation it is possible that devices that don't support PVSTP(+) will untag the BPDUs and forward the BPDU, as a result, the switch will receive its own packet, trigger a loop detection and block a port. This can happen to other protocols as well, but (R)STP is the most common case. If a switch is using a BPDU guard function, then this type of configuration can trigger it and cause a port to be blocked by STP. It has been reported that this type of configuration can prevent traffic from being forwarded over certain bridge ports over time when using 6.41 or later. This type of configuration does not only break (R/M)STP, but it can cause loop warnings. This can be caused by MNDP packets or any other packets that are directly sent out from an interface. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Port blocked by RSTP. - Loops in the network. - Port flapping. - Traffic stops forwarding over time. - BPDUs ignored by other RSTP enabled devices. ### Solution To avoid compatibility issues you should use bridge VLAN filtering. Below you can find an example of how the same traffic tagging effect can be achieved with a bridge VLAN filtering configuration: ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 pvid=99 /interface/bridge/vlan add bridge=bridge1 tagged=ether1 untagged=ether2 vlan-ids=99 ``` :::danger By enabling `vlan-filtering` you will be filtering out traffic destined to the CPU. Before enabling VLAN filtering you should make sure that you set up a [Management port](../#management-access-configuration). ::: ## Bridged VLAN on physical interfaces --- A very similar case to [VLAN on a bridge in a bridge](layer2-misconfiguration.md#vlan-on-a-bridge-in-a-bridge): consider the following scenario. You have a couple of switches in your network and you are using VLANs to isolate certain Layer2 domains and connect these switches to a router that assigns addresses and routes the traffic to the world. For redundancy, you connect all switches directly to the router and have enabled RSTP, but to be able to set up DHCP Server you decide that you can create a VLAN interface for each VLAN on each physical interface that is connected to a switch and add these VLAN interfaces in a bridge. A network diagram can be found below: ![Bridged VLANs](./img/layer2-misconfiguration-04.webp) ### Configuration Only the router part is relevant to this case, switch configuration doesn't really matter as long as ports are switched. Router configuration can be found below: ```ros /interface/bridge add name=bridge10 add name=bridge20 /interface/vlan add interface=ether1 name=ether1_v10 vlan-id=10 add interface=ether1 name=ether1_v20 vlan-id=20 add interface=ether2 name=ether2_v10 vlan-id=10 add interface=ether2 name=ether2_v20 vlan-id=20 /interface/bridge/port add bridge=bridge10 interface=ether1_v10 add bridge=bridge10 interface=ether2_v10 add bridge=bridge20 interface=ether1_v20 add bridge=bridge20 interface=ether2_v20 ``` ### Problem You might notice that the network is having some weird delays or even the network is unresponsive. You might notice that there is a loop detected (packet received with own MAC address) and some traffic is being generated out of nowhere. The problem occurs because a broadcast packet that is coming from either one of the VLAN interfaces created on the **Router** will be sent out the physical interface, the packet will be forwarded through the physical interface, through a switch and will be received back on a different physical interface, in this case, broadcast packets sent out **ether1\_v10** will be received on **ether2**, the packet will be captured by **ether2\_v10**, which is bridged with **ether1\_v10** and will get forwarded again via the same path (loop). (R)STP might not always detect this loop since (R)STP is not aware of any VLANs. A loop does not exist with untagged traffic, but exists with tagged traffic. In this scenario, it is quite obvious to spot the loop, but in more complex setups it is not always easy to detect the network design flaw. Sometimes this network design flaw might go unnoticed for a very long time if your network does not use broadcast traffic, usually, [Neighbor Discovery Protocol](../../system-information-and-utilities/neighbor-discovery.md) is broadcasting packets from the VLAN interface and will usually trigger a loop detection in such a setup. Sometimes it is useful to capture the packet that triggered a loop detection, this can be done by using a sniffer and analyzing the packet capture file: ```ros /tool/sniffer set filter-mac-address=4C:5E:0C:4D:12:44/FF:FF:FF:FF:FF:FF \ filter-interface=ether1 filter-direction=rx file-name=loop_packet.pcap ``` Or a more convenient way using logging: ```ros /interface/bridge/filter add action=log chain=forward src-mac-address=4C:5E:0C:4D:12:44/FF:FF:FF:FF:FF:FF add action=log chain=input src-mac-address=4C:5E:0C:4D:12:44/FF:FF:FF:FF:FF:FF ``` ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Port blocked by (R)STP. - Loops in the network. - Low throughput. - Port flapping. - Network inaccessible. ### Solution A solution is to use bridge VLAN filtering in order to make all bridges compatible with IEEE 802.1W and IEEE 802.1Q. ```ros /interface/bridge add name=bridge vlan-filtering=yes /interface/bridge/port add bridge=bridge interface=ether1 add bridge=bridge interface=ether2 /interface/bridge/vlan add bridge=bridge tagged=ether1,ether2,bridge vlan-ids=10 add bridge=bridge tagged=ether1,ether2,bridge vlan-ids=20 /interface/vlan add name=vlan10 interface=bridge vlan-id=10 add name=vlan20 interface=bridge vlan-id=20 ``` :::danger By enabling `vlan-filtering` you will be filtering out traffic destined to the CPU. Before enabling VLAN filtering you should make sure that you set up a [Management port](../#management-access-configuration). ::: ## Bridged VLAN --- A more simplified scenario of [Bridged VLAN on physical interfaces](layer2-misconfiguration.md#bridged-vlan-on-physical-interfaces), but in this case, you simply want to bridge two or more VLANs together that are created on different physical interfaces. This is a very common type of setup that deserves a separate article since misconfiguring this type of setup has caused multiple network failures. This type of setup is also used for VLAN translation. ### Configuration ```ros /interface/vlan add interface=ether1 name=ether1_v10 vlan-id=10 add interface=ether2 name=ether2_v10 vlan-id=10 /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1_v10 add bridge=bridge1 interface=ether2_v10 ``` ### Problem You may notice that certain parts of the network are not accessible and/or certain links keep flapping. This is due to (R)STP. This type of configuration forces the device to send out tagged BPDUs that might not be supported by other devices, including RouterOS. Since a device receives a malformed packet (tagged BPDUs should not exist in your network when running (R)STP, which violates IEEE 802.1W and IEEE 802.1Q), the device will not interpret the packet correctly and can have unexpected behavior. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Port blocked by (R)STP. - Port flapping. - Network inaccessible. ### Solution The easiest solution is to simply disable (R)STP on the bridge: ```ros /interface/bridge set bridge1 protocol-mode=none ``` Though it is still recommended to rewrite your configuration to use bridge VLAN filtering: ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 /interface/bridge/vlan add bridge=bridge1 tagged=ether1,ether2 vlan-ids=10 ``` :::danger By enabling `vlan-filtering` you will be filtering out traffic destined to the CPU. Before enabling VLAN filtering you should make sure that you set up a [Management port](../#management-access-configuration). ::: ## Bridge VLAN filtering without hardware offloading --- Consider the following scenario: you found out about the new bridge VLAN filtering feature and you decided to change the configuration on your device. You have a very simple trunk/access port setup and you like the concept of bridge VLAN filtering. ### Configuration ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 pvid=20 add bridge=bridge1 interface=ether3 pvid=30 add bridge=bridge1 interface=ether4 pvid=40 /interface/bridge/vlan add bridge=bridge1 tagged=ether1 untagged=ether2 vlan-ids=20 add bridge=bridge1 tagged=ether1 untagged=ether3 vlan-ids=30 add bridge=bridge1 tagged=ether1 untagged=ether4 vlan-ids=40 ``` ### Problem For example, you use this configuration on a CRS1xx/CRS2xx series device and you start to notice that the CPU usage is very high and when running a performance test to check the network's throughput, you notice that the total throughput is only a fraction of the wire-speed performance that it should easily reach. The cause of the problem is that not all devices support bridge VLAN filtering on a hardware level. All devices are able to be configured with bridge VLAN filtering, but only a few of them will be able to offload the traffic to the switch chip. If an improper configuration method is used on a device with a built-in switch chip, then the CPU will be used to forward the traffic. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Missing "H" flag on bridge ports. - Low throughput. - High CPU usage. ### Solution Before using bridge VLAN filtering, check if your device supports it at the hardware level. A table with compatibility can be found at the [Bridge Hardware Offloading](../#bridge-hardware-offloading) section. Each type of device currently requires a different configuration method. Below is a list of which configuration should be used on a device in order to use the benefits of hardware offloading: - [MikroTik devices with Marvell Prestera switch](../index.md#bridge-vlan-filtering) - [CRS1xx/CRS2xx series devices](./crs1xx-2xx-series-switches-examples.md#vlan) - [Other devices with a switch chip](../switch-chip-features.md#setup-examples) ## VLAN filtering with multiple switch chips --- Consider the following scenario: you have a device with two or more switch chips and you have decided to use a single bridge and set up VLAN filtering (by using the `/interface/ethernet/switch` menu) on a hardware level to be able to reach wire-speed performance on your network. This is very relevant for RB2011 and RB3011 series devices. In this example, let's assume that you want to have a single trunk port and all other ports are access ports, for example, **ether10** is our trunk port and **ether1-ether9** are our access ports. ### Configuration ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=ether3 add bridge=bridge1 interface=ether4 add bridge=bridge1 interface=ether5 add bridge=bridge1 interface=ether6 add bridge=bridge1 interface=ether7 add bridge=bridge1 interface=ether8 add bridge=bridge1 interface=ether9 add bridge=bridge1 interface=ether10 /interface/vlan add interface=bridge1 name=VLAN10 vlan-id=10 /interface/ethernet/switch/port set ether1,ether2,ether3,ether4,ether5,ether6,ether7,ether8,ether9 default-vlan-id=10 vlan-header=always-strip vlan-mode=secure set ether10 vlan-header=add-if-missing vlan-mode=secure set switch1-cpu,switch2-cpu vlan-mode=secure /interface/ethernet/switch/vlan add ports=ether1,ether2,ether3,ether4,ether5,switch1-cpu switch=switch1 vlan-id=10 add ports=ether6,ether7,ether8,ether9,ether10,switch2-cpu switch=switch2 vlan-id=10 ``` ### Problem After running a few tests you might notice that packets from **ether6-ether10** are forwarded as expected, but packets from **ether1-ether5** are not always forwarded correctly (especially through the trunk port). The most noticeable issue would be that packets from **ether1-ether5** through **ether10** are simply dropped. This is because these ports are located on a different switch chip. This means that VLAN filtering is not possible on a hardware level since the switch chip is not aware of the VLAN table's contents on a different switch chip. Packets that are being forwarded between ports that are located on different switch chips are also processed by the CPU, which means you won't be able to achieve wire-speed performance. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Packets being dropped. - Low throughput. ### Solution The proper solution is to take into account this hardware design and plan your network topology accordingly. To solve this issue you must create two separate bridges and configure VLAN filtering on each switch chip. This limits the possibility to forward packets between switch chips, though it is possible to configure routing between both bridges (if devices that are connected on each switch chip are using different network subnets). There is a way to configure the device to have all ports switch together and yet be able to use VLAN filtering on a hardware level, though this solution has some caveats. The idea is to sacrifice a single Ethernet port on each switch chip that will act as a trunk port to forward packets between switch chips, this can be done by plugging an Ethernet cable between both switch chips, for example, let's plug in an Ethernet cable between **ether5** and **ether6** then reconfigure your device assuming that these ports are trunk ports: ```ros /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=ether3 add bridge=bridge1 interface=ether4 add bridge=bridge1 interface=ether5 add bridge=bridge2 interface=ether6 add bridge=bridge2 interface=ether7 add bridge=bridge2 interface=ether8 add bridge=bridge2 interface=ether9 add bridge=bridge2 interface=ether10 /interface/ethernet/switch/port set ether1,ether2,ether3,ether4,ether7,ether8,ether9 default-vlan-id=10 vlan-header=always-strip vlan-mode=secure set ether5,ether6,ether10 vlan-header=add-if-missing vlan-mode=secure default-vlan-id=auto set switch1-cpu,switch2-cpu vlan-mode=secure /interface/ethernet/switch/vlan add ports=ether1,ether2,ether3,ether4,ether5,switch1-cpu switch=switch1 vlan-id=10 add ports=ether6,ether7,ether8,ether9,ether10,switch2-cpu switch=switch2 vlan-id=10 ``` :::warning For 100Mbps switch chips, use `default-vlan-id=0` instead of `default-vlan-id=auto` ::: ## VLAN filtering with simplified bridge VLAN table --- :::info This issue has been resolved since **RouterOS v7.15**. Dynamic VLANs are now always created as separate entries and no longer merge with statically configured ones. ::: You need to create a network setup where multiple clients are connected to separate access ports and isolated by different VLANs. This traffic should be tagged and sent to the appropriate trunk port. Access ports are configured using a pvid property. As the trunk port is used on both VLANs, you decide to simplify configuration by adding a single bridge VLAN table entry and separating VLANs by a comma. This is especially useful when tagged trunk ports are used across large numbers of VLANs or even certain VLAN ranges (e.g. vlan-id=100-200). See the network diagram and configuration below. ![Switch Multiple Untagged](./img/layer2-misconfiguration-05.webp) ### Configuration ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=ether3 pvid=10 add bridge=bridge1 interface=ether4 pvid=20 /interface/bridge/vlan add bridge=bridge1 tagged=ether2 vlan-ids=10,20 ``` ### Problem Traffic is correctly forwarded and tagged from access ports to trunk port, but you might notice that some broadcast or multicast packets are actually flooded between both untagged access ports, although they should be on different VLANs. Furthermore, broadcast and multicast traffic from the tagged port is also flooded to both access ports. This might raise some security concerns as traffic from different networks can be sniffed. When you look at the bridge VLAN table, you notice that a single entry has been created for VLANs 10 and 20, and both untagged ports are part of the same VLAN group. ```ros [admin@SW1] /interface/bridge/vlan/print where tagged=ether2 Columns: BRIDGE, VLAN-IDS, CURRENT-TAGGED, CURRENT-UNTAGGED # BRIDGE VLAN-IDS CURRENT-TAGGED CURRENT-UNTAGGED ;;; port with pvid added to untagged group which might cause problems, consider adding a separate VLAN entry 0 bridge1 10 ether2 ether3 20 ether4 ``` ### Symptoms - Traffic is flooded between different VLANs - Red warning: `port with pvid added to untagged group which might cause problems, consider adding a separate VLAN entry` ### Solution When access ports have been configured using the pvid property, they get dynamically added to the appropriate VLAN entry. After creating a static VLAN entry with multiple VLANs or a VLAN range, the untagged access port with a matching pvid also gets included in the same VLAN group or range. It might be useful to define a large number of VLANs using a single configuration line, but extra caution should be taken when access ports are configured. For this example, separate VLAN entries should be created: ```ros /interface/bridge/vlan add bridge=bridge1 tagged=ether2 untagged=ether3 vlan-ids=10 add bridge=bridge1 tagged=ether2 untagged=ether4 vlan-ids=20 ``` ## MTU on the master interface --- Consider the following scenario: you have created a bridge, added a few interfaces to it and created a VLAN interface on top of the bridge interface, but you need to increase the MTU size on the VLAN interface in order to receive larger packets. ### Configuration ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 /interface/vlan add interface=bridge1 name=VLAN99 vlan-id=99 ``` ### Problem As soon as you try to increase the MTU size on the VLAN interface, you receive an error that RouterOS **Could not set MTU**. This can happen when you are trying to set MTU larger than the L2MTU. In this case, you need to increase the L2MTU size on all slave interfaces, which will update the L2MTU size on the bridge interface. After this has been done, you will be able to set a larger MTU on the VLAN interface. The same principle applies to bond interfaces. You can increase the MTU on interfaces like VLAN, MPLS, VPLS, Bonding and other interfaces only when all physical slave interfaces have the proper L2MTU set. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Cannot change MTU. ### Solution Increase the L2MTU on slave interfaces before changing the MTU on a master interface. ```ros /interface/ethernet set ether1,ether2 l2mtu=9018 /interface/vlan set VLAN99 mtu=9000 ``` ## MTU inconsistency --- Consider the following scenario: you have multiple devices in your network. Most of them are used as a switch/bridge in your network, and there are certain endpoints that are supposed to receive and process traffic. To decrease the overhead in your network, you have decided to increase the MTU size, so you set a larger MTU size on both endpoints, but you start to notice that some packets are being dropped. ![MTU Issues](./img/layer2-misconfiguration-06.webp) ### Configuration In this case, both endpoints can be any type of device, we will assume that they are both Linux servers that are supposed to transfer a large amount of data. In such a scenario, you would have probably set interface MTU to 9000 on **ServerA** and **ServerB** and on your **Switch** you have probably set something similar to this: ```ros /interface/bridge add name=bridge1 /interface/bridge/port add interface=ether1 bridge=bridge1 add interface=ether2 bridge=bridge1 ``` ### Problem This is a very simple problem, but in larger networks, it can be hard to detect. For instance, ping might be working since a generic ping packet will be 70 bytes long (14 bytes for Ethernet header, 20 bytes for IPv4 header, 8 bytes for ICMP header, 28 bytes for ICMP payload), but data transfer might not work properly. The reason why some packets might not get forwarded is that MikroTik devices running RouterOS by default have the MTU set to 1500 and L2MTU set to something around 1580 bytes (depending on the device), but the Ethernet interface will silently drop anything that does not fit into the L2MTU size. Note that the L2MTU parameter is not relevant to x86 or CHR devices. For a device that is only supposed to forward packets, there is no need to increase the MTU size; it is only required to increase the L2MTU size. RouterOS will not allow you to increase the MTU size larger than the L2MTU size. If you require the packet to be received on the interface and the device needs to process this packet rather than just forwarding it, for example, in the case of routing, then it is required to increase the L2MTU and the MTU size, but you can leave the MTU size on the interface to the default value if you are using only IP traffic (that supports packet fragmentation) and don't mind that packets are being fragmented. You can use the ping utility to make sure that all devices are able to forward jumbo frames: ```ros /ping 192.168.88.1 size=9000 do-not-fragment ``` Remember that the L2MTU and MTU size needs to be larger than or equal to the ping packet size on the device from which and to which you are sending a ping packet since ping (ICMP) is IP traffic that is sent out from an interface over Layer3. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Web pages are not able to load up, but ping works properly. - Tunnels dropping traffic. - Specific protocols are broken. - Large packet loss. ### Solution Increase the L2MTU size on your **Switch**: ```ros /interface/ethernet set ether1,ether2 l2mtu=9000 ``` In case your traffic is encapsulated (VLAN, VPN, MPLS, VPLS, or other), then you might need to consider setting an even larger L2MTU size. In this scenario, it is not needed to increase the MTU size for the reason described above. :::warning Full frame MTU is not the same as L2MTU. L2MTU size does not include the Ethernet header (14 bytes) and the CRC checksum (FCS) field. The FCS field is stripped by the Ethernet driver and RouterOS will never show the extra 4 bytes to any packet. For example, if you set MTU and L2MTU to 9000, then the full-frame MTU is 9014 bytes long. This can also be observed when sniffing packets with "`/tool/sniffer/quick"` command. ::: ## Bridge and reserved MAC addresses --- Consider the following scenario: you want to transparently bridge two network segments together, either those are tunnel interfaces like EoIP, Wireless interfaces, Ethernet interface, or any other kind of interfaces that can be added to a bridge. Such a setup allows you to seamlessly connect two devices together like there was only a physical cable between them. This is sometimes called a **transparent bridge** from **DeviceA** to **DeviceB**. ### Configuration For both devices **DeviceA** and **DeviceB** there should be a very similar configuration. ```ros /interface/bridge add name=bridge1 protocol-mode=rstp /interface/bridge/port add interface=ether1 bridge=bridge1 add interface=eoip1 bridge=bridge1 ``` ### Problem Both devices are able to communicate with each other, but some protocols do not work properly. The reason is that as soon as you use any STP variant (STP, RSTP, MSTP), you make the bridge compliant with IEEE 802.1D and IEEE 802.1Q. These standards recommend that packets that are destined to **01:80:C2:00:00:0X** should **NOT** be forwarded. In cases where there are only 2 ports added to a bridge, (R/M)STP should not be used since a loop cannot occur from 2 interfaces and if a loop does occur, the cause is elsewhere and should be fixed on a different bridge. Since (R/M)STP is not needed in transparent bridge setups, it can be disabled. As soon as (R/M)STP is disabled, the RouterOS bridge is not compliant with IEEE 802.1D and IEEE 802.1Q and therefore will forward packets that are destined to **01:80:C2:00:00:0X**. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - LLDP neighbors not showing up. - 802.1x authentication (dot1x) not working. - LACP interface not passing traffic. ### Solution It is possible to partly disable compliance with IEEE 802.1D and IEEE 802.1Q; this can be done by changing the bridge protocol mode. ```ros /interface/bridge set bridge1 protocol-mode=none ``` :::danger The IEEE 802.1x standard is meant to be used between a switch and a client directly. If it is possible to connect a device between the switch and the client, then this creates a security threat. For this reason, it is not recommended to disable compliance with IEEE 802.1D and IEEE 802.1Q, but rather to design a proper network topology. ::: ## Bonding between Wireless links --- Consider the following scenario: you have set up multiple Wireless links and to achieve maximum throughput and yet to achieve redundancy you have decided to place Ethernet interfaces into a bond and depending on the traffic that is being forwarded you have chosen a certain bonding mode. This scenario can be applied to any case where a bonding interface is created between links that are not directly connected to each other. ![LACP over WLAN](./img/layer2-misconfiguration-07.webp) ### Configuration The following configuration is relevant to **R1** and **R2**: ```ros /interface/bonding add mode=802.3ad name=bond1 slaves=ether1,ether2 transmit-hash-policy=layer-2-and-3 /ip/address add address=192.168.1.X/24 interface=bond1 ``` The following configuration is relevant to **AP1**, **AP2**, **ST1,** and **ST2**, where **X** corresponds to an IP address for each device. ```ros /interface/bridge add name=bridge1 protocol-mode=none /interface/bridge/port add interface=ether1 bridge=bridge1 add interface=wlan1 bridge=bridge1 /ip/address add address=192.168.1.X/24 interface=bridge1 ``` ### Problem While traffic is being forwarded properly between **R1** and **R2**, load balancing, link failover are working properly as well, but devices between **R1** and **R2** are not always accessible or some of them are completely inaccessible (in most cases **AP2** and **ST2** are inaccessible). After examining the problem you might notice that packets do not always get forwarded over the required bonding slave and as a result, are never received by the device you are trying to access. This is a network design and bonding protocol limitation. As soon as a packet needs to be sent out through a bonding interface (in this case you might be trying to send ICMP packets to **AP2** or **ST2**), the bonding interface will create a hash based on the selected bonding mode and transmit-hash-policy and will select an interface, through which to send the packet out, regardless of whether the destination is only reachable through a certain interface. Some devices will be accessible because the generated hash matches the interface, on which the device is located, but it might not choose the needed interface as well, which will result in an inaccessible device. Only broadcast bonding mode does not have this kind of protocol limitation, but this bonding mode has a very limited use case. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Limited connectivity - Unstable links (in case of balance-rr) ### Solution Bonding interfaces are not supposed to be connected using indirect links, but it is still possible to create a workaround. The idea behind this workaround is to find a way to bypass packets being sent out using the bonding interface. There are multiple ways to force a packet not to be sent out using the bonding interface, but essentially the solution is to create new interfaces on top of physical interfaces and add these newly created interfaces to a bond instead of the physical interfaces. One way to achieve this is to create EoIP tunnels on each physical interface, but that creates a huge overhead and will reduce overall throughput. You should create a VLAN interface on top of each physical interface instead. This creates a much smaller overhead and will not impact overall performance noticeably. Here is an example of how **R1** and **R2** should be reconfigured: ```ros /interface/vlan add interface=ether1 name=VLAN_ether1 vlan-id=999 add interface=ether2 name=VLAN_ether2 vlan-id=999 /interface/bonding add mode=balance-xor name=bond1 slaves=VLAN_ether1,VLAN_ether2 transmit-hash-policy=layer-2-and-3 /ip/address add address=192.168.1.X/24 interface=bond1 add address=192.168.11.X/24 interface=ether1 add address=192.168.22.X/24 interface=ether2 ``` **AP1** and **ST1** only need updated IP addresses to the correct subnet: ```ros /ip/address add address=192.168.11.X/24 interface=bridge1 ``` The same changes must be applied to **AP2** and **ST2** (make sure to use the correct subnet): ```ros /ip/address add address=192.168.22.X/24 interface=bridge1 ``` With this approach, you create the least overhead and the fewest configuration changes are required. :::warning LACP (802.3ad) is not meant to be used in setups, where devices' bonding slaves are not directly connected, in this case, it is not recommended to use LACP if there are Wireless links between both routers. LACP requires both bonding slaves to be at the same link speeds, Wireless links can change their rates at any time, which will decrease overall performance and stability. Other bonding modes should be used instead. ::: ## Bandwidth testing --- Consider the following scenario: you set up a link between two devices. This can be any link, an Ethernet cable, a wireless link, a tunnel or any other connection. You decide that you want to test the link's bandwidth, but for convenience reasons, you decide to start testing the link with the same devices that are running the link. ![Bad Bandwidth Setup](./img/layer2-misconfiguration-08.webp) ### Problem As soon as you start [Bandwidth test](../../diagnostics-monitoring-and-troubleshooting/bandwidth-test.md) or [Traffic generator](../../diagnostics-monitoring-and-troubleshooting/traffic-generator.md) you notice that the throughput is much smaller than expected. For very powerful routers, which should be able to forward many Gigabits per second (Gbps), you notice that only a few Gigabits per second get forwarded. The reason why this is happening is because of the testing method you are using. You should never test throughput on a router while using the same router for generating traffic because you are adding an additional load on the CPU that reduces the total throughput. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Low throughput. - High CPU usage. ### Solution Use a proper testing method. Don't use Bandwidth-test to test large capacity links and don't run any tool that generates traffic on the same device you are testing. Design your network properly so you can attach devices that will generate and receive traffic on both ends. If you are familiar with **Iperf**, then this concept should be clear. Remember that in the real world, a router or a switch does not generate large amounts of traffic (at least it shouldn't, otherwise, it might indicate an existing security issue), a server/client generates the traffic while a router/switch forwards the traffic (and does some manipulations to the traffic in appropriate cases). ![Good Bandwidth Setup](./img/layer2-misconfiguration-09.webp) ## Bridge split-horizon usage --- Consider the following scenario: you have a bridge and you need to isolate certain bridge ports from each other. There are options to use a built-in switch chip to isolate certain ports on certain switch chips, you can use bridge firewall rules to prevent certain ports from being able to send any traffic to other ports, you can isolate ports in a PVLAN type of setup using port isolation, but there is also a software-based solution to use bridge split-horizon (which disables hardware offloading on all switch chips). ### Configuration ```ros /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 horizon=1 hw=no interface=ether1 add bridge=bridge1 horizon=2 hw=no interface=ether2 add bridge=bridge1 horizon=3 hw=no interface=ether3 add bridge=bridge1 horizon=4 hw=no interface=ether4 ``` ### Problem After setting the bridge split-horizon on each port, you start to notice that ports are still able to send data to each other. The reason for this is the misuse of bridge split-horizon. A bridge port is only not able to communicate with ports that are in the same horizon, for example, horizon=1 is not able to communicate with horizon=1, but is able to communicate with horizon=2, horizon=3, and so on. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - Traffic is being forwarded on different bridge split-horizons. ### Solution Set a proper value as the bridge split-horizon. In case you want to isolate ports from each other (a common scenario for PPPoE setups) and each port is only able to communicate with the bridge itself, then all ports must be in the same bridge split-horizon. ```ros /interface/bridge/port set [f] horizon=1 ``` :::warning Setting all bridge ports in the same bridge split-horizon will result in traffic only being able to reach the bridge interface itself, then packets can only be routed. This is useful when you want other devices to filter out certain traffic. Similar behavior can be achieved using bridge filter rules. ::: ## Unsupported SFP modules --- Consider the following scenario: you have decided to use optical fiber cables to connect your devices together by using SFP or SFP+ optical modules, but for convenience reasons, you have decided to use SFP optical modules that were available. ### Problem As soon as you configure your devices to have connectivity on the ports that are using these SFP optical modules, you might notice that the link is either working properly or experiencing random connectivity issues. There are many vendors that manufacture SFP optical modules, but not all vendors strictly follow SFP MSA, SFF, and IEEE 802.3 standards, which can lead to unpredictable compatibility issues, which is a very common issue when using not well-known or unsupported SFP optical modules in MikroTik devices. ### Symptoms Below is a list of possible symptoms that might be a result of this kind of misconfiguration: - SFP interface does not link up. - Random packet drop. - Unstable link (flapping). - SFP module is not running after a reboot. - SFP module is not running after a power-cycle. - SFP module is running only on one side. ### Solution You should only use supported SFP modules. Always check the [SFP compatibility table](../../wired-connections/mikrotik-wired-interface-compatibility.mdx) if you are intending to use SFP modules manufactured by MikroTik. There are other SFP modules that do work with MikroTik devices as well. Check the [Supported peripherals table](../../hardware/peripherals.mdx#sfp-modules) to find other SFP modules that have been confirmed to work with MikroTik devices. Some unsupported modules might not be working properly at certain speeds and with auto-negotiation. You might want to try to disable it and manually set a link speed. --- ## Loop Protect The loop protect feature can prevent Layer2 loops by sending loop protect protocol packets and shutting down interfaces in case they receive loop protect packets originating from themselves. The feature works by checking the source MAC address of the received loop-protect packet against the MAC addresses of loop-protect enabled interfaces. If the match is found, loop protect disables the interface that received the loop protect packet. A log message warns about this event and the interface is marked with a loop protect comment by the system. The RouterOS loop protect feature can be used on bridged interfaces as well as on Ethernet interfaces which are set for switching in RouterBoard switch chips. Loop Protect works on Ethernet, VLAN, EoIP, VxLAN interfaces and its packets are encapsulated with EtherType 0x9003. The loop protect packet interval and interface disable time can be adjusted. Configuration changes or expiration of disable time resets loop protection on an interface. :::warning Even though loop-protect can work on interfaces that are added to a bridge, it is still recommended to use (R/M)STP rather than loop-protect since (R/M)STP is compatible with most switches, and STP variants provide many more configuration options to fine-tune your network. ::: **Sub-menu:** `/interface/ethernet, /interface/vlan, /interface/eoip, /interface/eoipv6, /interface/vxlan` | Property | Description | | :-- | :-- | | **loop-protect** (*on \| off \| default*; Default: **default**) | Enables or disables loop protect on the selected interface. **default** works as turned off. | | **loop-protect-send-interval** (*time interval*; Default: **5s**) | Sets how often loop protect packets are sent on the selected interface. | | **loop-protect-disable-time** (*time interval \| 0*; Default: **5m**) | Sets how long the selected interface is disabled when a loop is detected. **0** - forever. | ### Read-only properties | Property | Description | | :-- | :-- | | **loop-protect-status** (*on \| off \| disable*) | on - loop-protect feature is turned on, the interface is sending and listening for loop protect packetsoff - loop-protect feature is turned offdisable - loop-protect feature is turned on, the interface has received a loop protect packet and disabled itself to prevent a loop. | --- ## Spanning Tree Protocol --- The purpose of the spanning tree protocol is to provide the ability to create loop-free Layer 2 topologies while having redundant links. While connecting multiple bridges or just cross-connecting bridge ports, it's possible to create network loops that can severely impact the stability of the network. Spanning tree protocol aims to resolve this problem by introducing the concept of the root bridge. All bridges in the same Layer 2 domain will exchange information about the shortest path to the root bridge. Afterward, each bridge will negotiate which ports to use to reach the root bridge. This information exchange is done with the help of Bridge Protocol Data Units (BPDUs). STP will disable certain ports for each bridge to avoid loops, while still ensuring that all bridges can communicate with each other. For an in-depth description of the protocol please refer to IEEE 802.1D. As a best practice, it is always recommended to manually set up each bridge's priority, port priority, and port path cost to ensure proper Layer2 functionality at all times. Leaving STP related values to defaults is acceptable for a network that consists of 1 to 2 bridges running with (R/M)STP enabled, but it is highly recommended to manually set these values for larger networks. Since STP elects a root bridge and root ports by checking STP related values from bridges over the network, leaving STP settings to automatic may elect an undesired root bridge and root ports and in case of a hardware failure can result in an inaccessible network. :::info RouterOS bridge does not work with PVST and its variants. The PVST BPDUs (with a MAC destination 01:00:0C:CC:CC:CD) are treated by RouterOS bridges as typical multicast packets. In simpler terms, they undergo RouterOS bridge/switch forwarding logic and may get tagged or untagged. ::: ## Monitoring --- You can check the STP status of a bridge by using the `/interface/bridge/monitor` command, for example: ```ros /interface/bridge/monitor bridge1 state: enabled current-mac-address: 74:4D:28:6F:31:10 bridge-id: 0x8000.74:4D:28:6F:31:10 root-bridge: no root-bridge-id: 0.74:4D:28:11:70:6B regional-root-bridge-id: 0.74:4D:28:11:70:6B root-path-cost: 0 root-port: combo1 port-count: 2 designated-port-count: 0 mst-config-digest: 4e22fbb9ede77faa45ec995c4ffa8085 fast-forward: no multicast-router: yes igmp-querier: none mld-querier: none declared-vlan-ids: 1 registered-vlan-ids: 1 ``` Note that the root bridge doesn't have any root ports, only designated ports. You can check the STP status of a bridge port by using the `/interface/bridge/port/monitor` command, for example: ```ros /interface/bridge/port/monitor [find interface=combo1] interface: combo1 status: in-bridge port-id: 0x80.1 role: root-port edge-port: no edge-port-discovery: yes point-to-point-port: yes external-fdb: no sending-rstp: yes learning: yes forwarding: yes actual-path-cost: 2000 internal-root-path-cost: 2000 designated-bridge-id: 0.74:4D:28:11:70:6B designated-internal-cost: 0 designated-port-id: 0x80.1 designated-remaining-hops: 20 bpdu-tx-rx: 3/7791 discard-transitions: 0 forward-transitions: 1 tc-tx-rx: 2/2 topology-changes: 1 last-topology-change: 4h19m43s multicast-router: no hw-offload-group: switch1 declared-vlan-ids: 1 100 registered-vlan-ids: 1 100 200-203 ``` Note that `root-bridge-id` consists of the bridge priority and the bridge's MAC address; for non-root bridges the root bridge will be shown as `designated-bridge`. :::warning When using bridges that are set to use 802.1Q as EtherType, they will send out BPDUs to 01:80:C2:00:00:00, which are used by MSTP, RSTP, and STP. When using 802.1ad as the bridge VLAN protocol, the BPDUs are not compatible with 802.1Q bridges and they are sent to 01:80:C2:00:00:08. (R/M)STP will not function properly if there are different bridge VLAN protocols across the Layer2 network. ::: ## STP and RSTP --- STP and Rapid STP are used widely across many networks, but almost all networks have switched over to using only RSTP because of its benefits. STP is a very old protocol and has a convergence time (the time needed to fully learn network topology changes and to continue properly forwarding traffic) of up to 50 seconds. RSTP has a lot of smaller convergence time, a few seconds or even a few milliseconds. It is recommended to use RSTP instead of STP since it is a lot faster and is also backward compatible with STP. One of the reasons why RSTP is faster is because of reduced possible port states, below is a list of possible STP port states: - **Forwarding** - port participates in traffic forwarding and is learning MAC addresses, and is receiving BPDUs. - **Listening** - port does not participate in traffic forwarding and is not learning MAC addresses, and is receiving BPDUs. - **Learning** - port does not participate in traffic forwarding but is learning MAC addresses. - **Blocking** - port is blocked since it is causing loops but is receiving BPDUs. - **Disabled** - port is disabled or inactive. In RSTP the disabled, listening, and blocking port states are replaced with just one state called the **Discarding** state: - **Forwarding** - port participates in traffic forwarding and is learning MAC addresses and is receiving BPDUs (forwarding=yes). - **Learning** - port does not participate in traffic forwarding but is learning MAC addresses (learning=yes). - **Discarding** - port does not participate in traffic forwarding and is not learning MAC addresses and is receiving BPDUs (forwarding=no). In STP ports are primarily categorized by states (e.g., Forwarding, Listening, Learning, Blocking, Disabled). Port behavior is determined dynamically based on the spanning tree algorithm but without explicitly assigning roles. The logic of forwarding or blocking traffic is derived from the calculation of Root Bridge, Root Ports, and Designated Ports, but these are considered part of the spanning tree topology rather than formalized port roles. RSTP explicitly defines port roles and introduces the concept of backup paths, which are explicitly represented through the Alternate Port and Backup Port roles. These roles did not exist in STP because STP treated blocked ports generically, without distinguishing their function as potential backups. Here is a breakdown of the port roles for the RSTP protocol: - **Root Port** - port that is facing towards the root bridge and has the best (lowest cost) path to the root bridge. Only one root port is elected per bridge (except the root bridge itself). - **Designated Port** - port that is facing away from the root bridge and forwards traffic away from the root bridge to downstream devices. - **Alternate Port** - port that is facing towards the root bridge, but is not going to forward traffic. The port provides a backup path to the root bridge if the current root port fails. - **Backup Port** - port that is facing away from the root bridge, but is not going to forward traffic. The port that serves as a backup for a designated port on the same segment. - **Disabled Port** - disabled or inactive port. In STP connectivity between bridges is determined by sending and receiving BPDUs between neighbor bridges. Designated ports are sending BPDUs to root ports. If a BPDU is not received 3 times the **HelloTime** in a row, then the connection is considered unavailable and network topology convergence will commence. It is possible to reduce STP convergence time in certain scenarios by reducing the `forward-delay` timer, which is responsible for how long the port can be in the learning/listening state. In RouterOS, it is possible to specify which bridge ports are edge ports. Edge ports are ports that are not supposed to receive any BPDUs. This is beneficial since this allows STP to skip the learning and the listening state and directly go to the forwarding state. This feature is sometimes called **PortFast**. You can leave this parameter to the default value, which is **auto**, but you can also manually specify it. You can set a port as an edge port manually for ports that should not have any more bridges behind them. Usually, these are access ports. Additionally, bridge port `point-to-point` specifies if a bridge port is connected to a bridge using a point-to-point link for faster convergence in case of failure. By setting this property to `yes`, you are forcing the link to be a point-to-point link, which will skip the checking mechanism, which detects and waits for BPDUs from other devices from this single link. By setting this property to `no`, you are implying that a link can receive BPDUs from multiple devices. By setting the property to `yes`, you are significantly improving (R/M)STP convergence time. In general, you should only set this property to `no`, if it is possible that another device can be connected between a link. This is mostly relevant to Wireless media and Ethernet hubs. If the Ethernet link is full-duplex, `auto` enables point-to-point functionality. This property has no effect when `protocol-mode` is set to `none`. ### Default values When creating a bridge or adding a port to the bridge the following are the default values that are assigned by RouterOS: - Default bridge priority: **32768** / **0x8000** - Default bridge port path cost: **based on interface speed** - Default bridge port priority: **0x80** - BPDU message age increment: **1** - HelloTime: **2** - Default max message age: **20** The bridge interface setting `port-cost-mode` changes the port `path-cost` and `internal-path-cost` mode for bridged ports, utilizing automatic values based on interface speed. This setting does not impact bridged ports with manually configured `path-cost` or `internal-path-cost` properties. Below are examples illustrating the path-costs corresponding to specific data rates (with proportionate calculations for intermediate rates): | Data rate | Long | Short | | :-- | :-- | --: | | 10 Mbps | 2,000,000 | 100 | | 100 Mbps | 200,000 | 19 | | 1 Gbps | 20,000 | 4 | | 10 Gbps | 2,000 | 2 | | 25 Gbps | 800 | 1 | | 40 Gbps | 500 | 1 | | 50 Gbps | 400 | 1 | | 100 Gbps | 200 | 1 | For bonded interfaces, the highest `path-cost` among all bonded member ports is applied, this value remains unaffected by the total link speed of the bonding. For virtual interfaces (such as VLAN, EoIP, VXLAN), as well as wifi, wireless, and 60GHz interfaces, a `path-cost` of 20,000 is assigned for long mode, and 10 for short mode. For dynamically bridged interfaces (e.g. wifi, wireless, PPP, VPLS), the `path-cost` defaults to 20,000 for long mode and 10 for short mode. However, this can be manually overridden by the service that dynamically adds interfaces to bridge, for instance, by using the CAPsMAN `datapath.bridge-cost` setting. RouterOS versions prior to 7.13 do not change port path cost based on the link speed, for 10M, 100M, 1000M, and 10000M link speeds the default path cost value when a port is added to a bridge was always **10**. The age of a BPDU is determined by how many bridges the BPDU has passed times the message age since RouterOS uses **1** as the message age increment, then the BPDU packet can pass as many bridges as specified in the `max-message-age` parameter. By default this value is set to **20**. This means that after the 20th bridge the BPDU packet will be discarded and the next bridge will become a root bridge. Note that if `max-message-age=20` is set, then it is hard to predict which ports will be the designated port on the 21st bridge and may result in traffic not being able to be forwarded properly. :::warning In case bridge filter rules are used, make sure you allow packets with DST-MAC address **01:80:C2:00:00:00** since these packets carry BPDUs that are crucial for STP to work properly. ::: ### Election process To properly configure STP in your network, you need to understand the election process and which parameters are involved in which order. In RouterOS, the root bridge will be elected based on the smallest priority and the smallest MAC address in this particular order: 1. Bridge priority (lowest). 2. Bridge MAC address (lowest). In RouterOS root ports are elected based on the lowest Root port path cost, lowest bridge identifier, and lowest bridge port ID in this particular order: 1. Root port path cost (lowest) 2. Bridge identifier (lowest) 3. Bridge port ID (lowest) First, when the device considers which of its ports to elect as the root port, it will check the **root path cost** seen by its ports. If the root path cost is the same for two or more ports then the **Bridge identifier** of the **upstream** device will be checked and the port connected to the lowest bridge identifier will become the root port. If the same bridge identifier is seen on two or more ports, then the **Bridge port ID** of the **upstream** device will be checked. ## Explanation of attributes Root path cost: all bridges have a Root Path Cost. The root bridge has a root path cost of 0. For all other Bridges, it is the sum of the Port Path Costs on the least-cost path to the Root Bridge. You can modify the local port path cost under `/interface/bridge/port`. The bridge identifier is a combination of "bridge priority" and "bridge MAC", configurable under `/interface/bridge`. Bridge port ID is a combination of "unique ID" and "bridge port priority". The unique ID is automatically assigned to the bridge port upon adding it to the bridge. It cannot be edited. It can be seen in WinBox under the "Bridge Port" "Port Number" column, or with `/interface/bridge/port/monitor`, as `port-number`. :::tip Understanding STP Port Election Make sure you apply path cost and priority to the correct ports: - **Path Cost** affects ports facing *towards* the root bridge. (Setting path cost on a root bridge port has no effect). - **Port Priority** affects ports facing *away* from the root bridge. - **Bridge Identifier** does not impact the device's own root port election; it affects the root port election for *downstream* devices. ::: :::warning Bridge Priority Compatibility RouterOS allows setting any bridge priority value between 0 and 65535. However, the IEEE 802.1W standard strictly requires bridge priorities to be in steps of 4096. To avoid incompatibility with other vendors' equipment, use **only** these priority values: `0, 4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 36864, 40960, 45056, 49152, 53248, 57344, 61440` ::: ### Examples #### Root path cost example ![Root Path](./img/spanning-tree-protocol-01.webp) This example outlines how the root path cost works. SW1 will be the root bridge, due to it having the lowest priority of 0x1000, as the root bridge. Each bridge will calculate the path cost to the root bridge. When calculating root path cost, bridges take into account the configured path cost on their ports + root path cost advertised by neighboring bridges. **SW1**: due to it being the root bridge, it advertises a root path cost of 0 to its neighbors, even though it has a configured path cost of 10. **SW2:****ether1** has a root path cost of 0 + 25=**25**. On the **ether2** path the cost will be 10+10+10+0=**30** **SW3:** **ether2** has a root path cost of 0 + 10=**10**. On the **ether4** path, the path cost will be 10+5+25+0=**40** **SW4:** **ether1** has a root path cost of 0+25+5=**30**. On **ether4**, path cost will be 10+10+0=**20**. The Port with the lowest path cost will be elected as the root port. Every bridge in the STP topology needs a path to the root bridge. After the best path has been found, the redundant path will be blocked, in this case, the path between SW2 and SW4. :::warning You can configure path cost on the root bridge, but it will only be taken into account when the bridge loses its root status. ::: #### STP example ![STP Example 1](./img/spanning-tree-protocol-02.webp) In this example, we want to ensure Layer2 redundancy for connections from ServerA to ServerB. If a port is connected to a device that is not a bridge and not running (R)STP, then this port is considered as an edge port. In this case, ServerA and ServerB are connected to an edge port. This is possible by using STP in a network. Below are configuration examples for each switch: - Configuration for SW1: ```ros /interface/bridge add name=bridge priority=0x1000 /interface/bridge/port add bridge=bridge interface=ether1 priority=0x60 add bridge=bridge interface=ether2 priority=0x50 add bridge=bridge interface=ether3 priority=0x40 add bridge=bridge interface=ether4 priority=0x30 add bridge=bridge interface=ether5 ``` - Configuration for SW2: ```ros /interface/bridge add name=bridge priority=0x2000 /interface/bridge/port add bridge=bridge interface=ether1 add bridge=bridge interface=ether2 add bridge=bridge interface=ether3 ``` - Configuration for SW3 ```ros /interface/bridge add name=bridge priority=0x3000 /interface/bridge/port add bridge=bridge interface=ether1 add bridge=bridge interface=ether2 add bridge=bridge interface=ether3 ``` - Configuration for SW4: ```ros /interface/bridge add name=bridge priority=0x4000 /interface/bridge/port add bridge=bridge interface=ether1 add bridge=bridge interface=ether2 path-cost=20 add bridge=bridge interface=ether3 ``` In this example, **SW1** is the root bridge since it has the lowest bridge priority. **SW2** and **SW3** have ether1,ether2 connected to the root bridge, and ether3 is connected to **SW4**. When all switches are working properly, the traffic will be flowing from ServerA through SW1\_ether2, through SW2, and through SW4 to ServerB. In the case of **SW1** failure, **SW2** becomes the root bridge because of the next lowest priority, indicated by the dotted line in the diagram. Below is a list of ports and their role for each switch: - **root-port** - SW2\_ether2, SW3\_ether2, SW4\_ether1 - **alternate-port** - SW2\_ether1, SW3\_ether1, SW4\_ether2 - **designated-port** - SW1\_ether1, SW1\_ether2, SW1\_ether3, SW1\_ether4, SW1\_ether5, SW2\_ether3, SW3\_ether3, SW4\_ether3 :::note **Note:** According to the 802.1Q recommendations, you should use bridge priorities in steps of 4096. To set a recommended priority, it is more convenient to use hexadecimal notation, for example, 0 is 0x0000, 4096 is 0x1000, 8192 is 0x2000, and so on (0..F). ::: ## Multiple Spanning Tree Protocol --- Multiple Spanning Tree Protocol (MSTP) is used on a bridge interface to ensure loop-free topology across multiple VLANs. MSTP can also provide Layer2 redundancy and can be used as a load balancing technique for VLANs since it has the ability to have different paths across different VLANs. MSTP is operating very similarly to (R)STP and many concepts from (R)STP can be applied to MSTP and it is highly recommended to understand the principles behind (R)STP before using MSTP, but there are some differences that must be taken into account when designing an MSTP-enabled network. In case (R)STP is used, the BPDUs are sent across all physical interfaces in a bridge to determine loops and stop ports from being able to forward traffic if it causes a loop. In case there is a loop inside a certain VLAN, (R)STP might not be able to detect it. Some STP variants solve this problem by running an STP instance on every single VLAN (PVST), but this has been proven to be inefficient, and some STP variants solve this problem by running a single STP instance across all VLANs (CST), but it lacks the possibility to do load balancing for each VLAN or VLAN group. MSTP tends to solve both problems by using MST instances that can define a group of VLANs (VLAN mapping) that can be used for load balancing and redundancy, which means that each VLAN group can have a different root bridge and a different path. Note that it is beneficial to group multiple VLANs in a single instance to reduce the number of CPU cycles for each network topology change. :::danger In RouterOS with MSTP enabled the bridge priority is the CIST's root bridge priority, as stated in the IEEE 802.1Q standard the bridge priority must be in steps of 4096, the 12 lowest bits are ignored. These are valid bridge priorities: 0, 4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 36864, 40960, 45056, 49152, 53248, 57344, 61440. When setting an invalid bridge priority, RouterOS will warn you about it and truncate the value to a valid value, but will save the original value in the configuration since invalid bridge priority values can still be used in (R)STP between devices running RouterOS, though it is recommended to use a valid bridge priority instead. ::: ### MSTP Regions MSTP works in groups called regions. For each region there will be a regional root bridge, and between regions, there will be a root bridge elected. MSTP will use an Internal Spanning Tree (IST) to build the network topology inside a region and a Common Spanning Tree (CST) outside a region to build the network topology between multiple regions. MSTP combines these two protocols into Common and Internal Spanning Tree (CIST), which holds information about topology inside a region and between regions. From CST's perspective, a region will seemingly be a single virtual bridge, because of this MSTP is considered very scalable for large networks. For bridges to be in the same region, their configuration must match. BPDUs will not include VLAN mappings since they can be large, rather a computed hash is being transmitted. If a bridge receives a BPDU through a port and the configuration does not match, then MSTP will consider that port as a boundary port and that it can be used to reach other regions. Below is a list of parameters that need to match for MSTP to consider a BPDU from the same region: - Region name - Region revision - VLAN mappings to MST Instance IDs (computed hash) It is possible to create an MSTP enabled network without regions, though to be able to do load balancing per VLAN group it is required for a bridge to receive a BPDU from a bridge that is connected to it with the same parameters mentioned above. In RouterOS the default region name is empty and the region revision is 0, which are valid values, but you must make sure that they match to get multiple bridges in a single MSTP region. A region cannot exist if its bridges are scattered over the network; these bridges must be connected in at least one way, in which they can send and receive BPDUs without leaving the region, for example, if a bridge with different region related parameters is between two bridges that have the same region related parameters, then there will exist at least 3 different MSTP regions. ![MSTP Topology](./img/spanning-tree-protocol-03.webp) The downside of running every single bridge in a single MSTP region is the excess CPU cycles. In comparison, PVST(+) creates a Spanning Tree Instance for each VLAN ID that exists on the network, since there will be very limited paths that can exist in a network, this approach creates a lot of overhead and unnecessary CPU cycles. This also means that this approach does not scale very well and can overload switches with not very powerful CPUs. MSTP solves this problem by dividing the network into MSTP regions, where each bridge inside this region will exchange and process information about VLANs that exist inside the same region, but will run a single instance of Spanning Tree Protocol in the background to maintain the network topology between regions. This approach has been proven to be much more effective and much more scalable. This means that regions should be used for larger networks to reduce CPU cycles. In regions, you can define MST Instances, which are used to configure load balancing per VLAN group and to elect the regional root bridge. It is worth mentioning that in each region there exists a pre-defined MST Instance, in most documentation, this is referred to as **MSTI0**· This MST Instance is considered as the default MST Instance. There are certain parameters that apply to this special MST Instance. When traffic passes through an MSTP-enabled bridge, MSTP will look for an MST Instance that has a matching VLAN mapping, but if a VLAN mapping does not exist for a certain VLAN ID, then traffic will fall under **MSTI0**. :::warning Since MSTP requires VLAN filtering on the bridge interface to be enabled, then make sure that you have allowed all required VLAN IDs in `/interface/bridge/vlan`, otherwise, the traffic will not be forwarded and it might seem as if MSTP is misconfigured, although this is a VLAN filtering misconfiguration. ::: ### Election process The election process in MSTP can be divided into two sections, intra-region and inter-region. For MSTP to work properly there will always need to be a regional root, that is the root bridge inside a region, and a CIST root, that is the root bridge between regions. A regional root is the root bridge inside a region, and the regional root bridge will be needed to properly set up load balancing for VLAN groups inside a region. The CIST root will be used to configure which ports will be alternate/backup ports (inactive) and which ports will be root ports (active). :::warning Between regions, there is no load balancing per VLAN group, no root port election process, and port blocking between MSTP regions is done the same way as in (R)STP. If CIST has blocked a port that is inside an MSTP region to prevent traffic loops between MSTP regions, then this port can still be active for IST to do load balancing per VLAN group inside an MSTP region. ::: - The following parameters are involved in electing a regional root bridge or root ports inside an MSTP region: | Property | Description | | :-- | :-- | | **priority** (*integer: 0..65535 decimal format or 0x0000-0xffff hex format*; Default: **32768 / 0x8000**) | `/interface/bridge/msti`, MST Instance priority, used to elect a regional root inside an MSTP region. Must be set in steps of 4096 (0x1000); the 12 lowest bits are ignored. Valid values: 0x0000, 0x1000, 0x2000, ..., 0xf000 (or decimal equivalents: 0, 4096, 8192, ..., 61440). | | **internal-path-cost** (*integer: 1..200000000*; Default: ) | `/interface/bridge/port`, path cost to the regional root for unknown VLAN IDs (MSTI0), used on a root port inside an MSTP region. | | **priority** (*0x00 \| 0x10 \| 0x20 \| 0x30 \| 0x40 \| 0x50 \| 0x60 \| 0x70 \| 0x80 \| 0x90 \| 0xa0 \| 0xb0 \| 0xc0 \| 0xd0 \| 0xe0 \| 0xf0*; Default: **0x80**) | `/interface/bridge/port/mst-override`, MST port priority for a defined MST Instance, used on a bridge port on the regional root bridge. Must be set in steps of 16 (0x10). | | **internal-path-cost** (*integer: 1..200000000*; Default: ) | `/interface/bridge/port/mst-override`, MST port path cost for a defined MST Instance, used on a non-root bridge port inside an MSTP region. | - The following parameters are involved in electing a CIST root bridge or CIST root ports: | Property | Description | | :-- | :-- | | **priority** (*integer: 0..65535 decimal format or 0x0000-0xffff hex format*; Default: **32768 / 0x8000**) | `/interface/bridge`, CIST bridge priority, used to elect a CIST root bridge. Must be set in steps of 4096 (0x1000); the 12 lowest bits are ignored. | | **priority** (*0x00 \| 0x10 \| 0x20 \| 0x30 \| 0x40 \| 0x50 \| 0x60 \| 0x70 \| 0x80 \| 0x90 \| 0xa0 \| 0xb0 \| 0xc0 \| 0xd0 \| 0xe0 \| 0xf0*; Default: **0x80**) | `/interface/bridge/port`, CIST port priority, used on a CIST root bridge to elect CIST root ports. Must be set in steps of 16 (0x10). | | **path-cost** (*integer: 1..200000000*; Default: ) | `/interface/bridge/port`, CIST port path cost, used on a CIST non-root bridge port to elect CIST root ports. | :::warning The sequence of parameters in which MSTP checks to elect root bridge/ports is the same as in (R)STP, you can read more about it in the (R)STP Election Process section. ::: ### MST Instance **Sub-menu:** `/interface/bridge/msti` This section is used to group multiple VLAN IDs into a single instance to create a different root bridge for each VLAN group inside an MSTP region. | Property | Description | | :-- | :-- | | **bridge** (*text*; Default: ) | Bridge to which the MST instance is assigned. | | **identifier** (*integer: 1..31*; Default: ) | MST instance identifier. | | **priority** (*integer: 0..65535 decimal format or 0x0000-0xffff hex format*; Default: **32768 / 0x8000**) | MST instance priority is used to determine the root bridge for a group of VLANs in an MSTP region. | | **vlan-mapping** (*integer: 1..4094*; Default: ) | The list of VLAN IDs to assign to the MST instance. This setting accepts the VLAN ID range, as well as comma-separated values. E.g. `vlan-mapping=100-115,120,122,128-130` | ### MST Override **Sub-menu:** `/interface/bridge/port/mst-override` This section is used to select the desired path for each VLAN mapping inside an MSTP region. | Property | Description | | :-- | :-- | | **disabled** (*yes \| no*; Default: **no**) | Whether the entry is disabled. | | **internal-path-cost** (*integer: 1..200000000*; Default: ) | Path cost for an MST instance's VLAN mapping, used on VLANs that are facing towards the root bridge to manipulate path selection; lower path cost is preferred. | | **identifier** (*integer: 1..31*; Default: ) | MST instance identifier. | | **priority** (*integer: 0..240*; Default: **128**) | The priority of an MST instance's VLAN, used on VLANs that are facing away from the root bridge to manipulate path selection; lower priority is preferred. | | **interface** (*name*; Default: ) | Name of the port on which to use configured MST instance's VLAN mappings and defined path cost and priority. | ### Monitoring Similarly to (R)STP, it is also possible to monitor MSTP status. By monitoring the bridge interface itself it is possible to see the current CIST root bridge and the current regional root bridge for MSTI0. It is also possible to see the computed hash of MST Instance identifiers and VLAN mappings. This is useful when making sure that certain bridges are in the same MSTP region. Below you can find an example of monitoring an MSTP bridge: ```ros /interface/bridge/monitor bridge state: enabled current-mac-address: 6C:3B:6B:7B:F0:AA bridge-id: 0x8000.6C:3B:6B:7B:F0:AA root-bridge: no root-bridge-id: 0x1000.64:D1:54:24:23:72 regional-root-bridge-id: 0x4000.6C:3B:6B:7B:F0:AA root-path-cost: 10 root-port: ether4 port-count: 5 designated-port-count: 3 mst-config-digest: 74edbeefdbf82cf63a70cf60e43a56f3 fast-forward: no multicast-router: yes igmp-querier: none mld-querier: none declared-vlan-ids: 1 registered-vlan-ids: 1 ``` In MSTP it is possible to monitor the MST Instance. This is useful to determine the current regional root bridge for a certain MST Instance and VLAN group. Below you can find an example to monitor an MST Instance: ```ros /interface/bridge/msti/monitor 1 state: enabled identifier: 2 current-mac-address: 6C:3B:6B:7B:F0:AA bridge-id: 0x8000.6C:3B:6B:7B:F0:AA root-bridge: no root-bridge-id: 0.00:00:00:00:00:00 regional-root-bridge-id: 0x1002.6C:3B:6B:7B:F9:08 root-path-cost: 0 root-port: ether2 port-count: 5 designated-port-count: 1 ``` It is also possible to monitor a certain MST Override entry. This is useful to determine the port role for a certain MST Instance when configuring root ports and alternate/backup ports in an MSTP region. Below you can find an example to monitor an MST Override entry: ```ros /interface/bridge/port/mst-override/monitor 1 port: ether3 status: active identifier: 2 port-id: 0x80.1 role: alternate-port learning: no forwarding: no internal-root-path-cost: 15 designated-bridge: 0x1002.6C:3B:6B:7B:F9:08 designated-internal-cost: 0 designated-port-id: 0x80.1 designated-remaining-hops: 20 tx-rx-bpdu: 3/7991 discard-transitions: 0 forward-transitions: 1 tx-rx-tc: 2/2 topology-changes: 1 ``` ### MSTP example Let's say that we need to design a topology and configure MSTP in a way that VLAN 10,20 will be forwarded in one path, but VLAN 30,40 will be forwarded in a different path, while all other VLAN IDs will be forwarded in one of those paths. This can easily be done by setting up MST Instances and assigning port path costs. Below you can find a network topology that needs to do load balancing per VLAN group with 3 separate regions as an example: ![MSTP Example](./img/spanning-tree-protocol-04.webp) The topology of an MSTP-enabled network with load balancing per VLAN group Start by adding each interface to a bridge. Initially, you should create a (R)STP bridge without VLAN filtering enabled. This is to prevent losing access to the CPU. Each device in this example is named by the region that it is in (Rx) and a device number (\_x). For larger networks configuring MSTP can be confusing because of the number of links and devices. We recommend using The Dude to monitor and design a network topology. - Use the following commands on **R1\_1**, **R1\_3**, **R2\_1**, **R2\_3**, **R3\_1**, **R3\_3**: ```ros /interface/bridge add name=bridge protocol-mode=rstp vlan-filtering=no /interface/bridge/port add bridge=bridge interface=ether1 add bridge=bridge interface=ether2 add bridge=bridge interface=ether3 add bridge=bridge interface=ether4 ``` - Use the following commands on **R1\_2**, **R2\_2**, **R3\_2**. ```ros /interface/bridge add name=bridge protocol-mode=rstp vlan-filtering=no /interface/bridge/port add bridge=bridge interface=ether1 add bridge=bridge interface=ether2 ``` - Make sure you allow the required VLAN IDs on these devices. Here we will consider that each device will receive tagged traffic that needs to be load balanced per VLAN group. Use these commands on **R1\_1**, **R1\_3**, **R2\_1**, **R2\_3**, **R3\_1**, **R3\_3**: ```ros /interface/bridge/vlan add bridge=bridge tagged=ether1,ether2,ether3,ether4 vlan-ids=10,20,30,40 ``` - Use the following commands on **R1\_2**, **R2\_2**, **R3\_2**: ```ros /interface/bridge/vlan add bridge=bridge tagged=ether1,ether2 vlan-ids=10,20,30,40 ``` :::warning Make sure you add all the needed VLAN IDs and ports to the bridge VLAN table, otherwise, your device will not forward all required VLANs, and/or you will lose access to the device. ::: We need to assign a region name for each bridge that we want to be in a single MSTP region. You can also specify the region revision, but it is optional, though they need to match. In this example, if all bridges have the same region name, then they will all be in a single MSTP bridge. In this case, we want to separate a group of 3 bridges in a different MSTP region to do load balancing per VLAN group and to create diversity and scalability: - Set the appropriate region name (and region revision) for each bridge, and use the following commands on each device (**change the region name!**): ```ros /interface/bridge set bridge region-name=Rx region-revision=1 ``` After we have created 3 different MSTP regions, we need to decide which device is going to be a regional root for each VLAN group. For consistency, we are going to set the first device (\_1) in each region as the regional root for VLAN 10,20 and the third device (\_3) in each region as the regional root for VLAN 30,40. This can be done by creating an MST Instance for each VLAN group and assigning a bridge priority to it. The MST Instance identifier is only relevant inside an MSTP region, outside an MSTP region, these identifiers can be different and mapped to a different VLAN group. - Use the following commands on **R1\_1**, **R2\_1**, **R3\_1**: ```ros /interface/bridge/msti add bridge=bridge identifier=1 priority=0x1000 vlan-mapping=10,20 add bridge=bridge identifier=2 priority=0x3000 vlan-mapping=30,40 ``` - Use the following commands on **R1\_3**, **R2\_3**, **R3\_3**: ```ros /interface/bridge/msti add bridge=bridge identifier=1 priority=0x3000 vlan-mapping=10,20 add bridge=bridge identifier=2 priority=0x1000 vlan-mapping=30,40 ``` - Use the following commands on **R1\_2**, **R2\_2**, **R3\_2**. ```ros /interface/bridge/msti add bridge=bridge identifier=1 priority=0x2000 vlan-mapping=10,20 add bridge=bridge identifier=2 priority=0x2000 vlan-mapping=30,40 ``` Now we need to override the port `path-cost` and/or port priority for each MST Instance. This can be done by adding an MST-Override entry for each port and each MST Instance. To achieve that for a certain MST Instance the traffic flow path is different, we simply need to make sure that the port path cost and/or priority is larger. We can either increase the port path cost or decrease the port path cost for ports that are facing toward the regional root bridge. It doesn't matter if you increase or decrease all values; it is important that in the end, one port's path cost is larger than the other's. - Use the following commands on **R1\_1**, **R2\_1**, **R3\_1**: ```ros /interface/bridge/port/mst-override add identifier=2 interface=ether1 internal-path-cost=5 add identifier=2 interface=ether2 internal-path-cost=15 ``` - Use the following commands on **R1\_2**, **R2\_2**, **R3\_2**: ```ros /interface/bridge/port/mst-override add identifier=1 interface=ether1 internal-path-cost=5 add identifier=2 interface=ether2 internal-path-cost=9 ``` - Use the following commands on **R1\_3**, **R2\_3**, **R3\_3**: ```ros /interface/bridge/port/mst-override add identifier=1 interface=ether2 internal-path-cost=5 add identifier=1 interface=ether3 internal-path-cost=9 ``` In this case for VLAN 10,20 to reach the third device from the first device, it would choose between ether1 and ether2, one port will be blocked and set as an alternate port, and ether1 will have path cost as `5+9=14` and ether2 will have path cost as `10`, ether2 will be elected as the root port for MSTI1 on the third device. In case for VLAN 30,40 to reach the first device from the third device, ether1 will have path cost as `5+9=14` and ether2 will have path cost as `15`, ether1 will be elected as the root port for MSTI2 on the third device. Now we can configure the root ports for **MSTI0**, which will fall under all VLANs that are not assigned to a specific MST Instance, like in our example VLAN 10,20, and VLAN 30,40. To configure this special MST Instance, you will need to specify `internal-path-cost` for a bridge port. This value is only relevant to MSTP regions, it does not have any effect outside an MSTP region. In this example we will choose that all unknown VLANs will be forwarded over the same path as VLAN 30,40, we will simply increase the path cost on one of the ports. - Use the following commands on **R1\_3**, **R2\_3**, **R3\_3**: ```ros /interface/bridge/port set [find where interface=ether3] internal-path-cost=25 ``` At this point, a single region MSTP can be considered configured, and in general, MSTP is fully functional. It is highly recommended to configure the CIST part, but for testing purposes, it can be left with the default values. Before doing any tests, you need to enable MSTP on all bridges. - Use the following commands on **all** devices: ```ros /interface/bridge set bridge protocol-mode=mstp vlan-filtering=yes ``` When MSTP regions have been configured, you can check if they are properly configured by forwarding traffic, for example, sending tagged traffic from the first device to the third device and changing the VLAN ID for the tagged traffic to observe different paths based on VLAN ID. When this is working as expected, then you can continue to configure CIST-related parameters to elect a CIST root bridge and CIST root ports. For consistency, we will choose the first device in the first region to be the CIST root bridge and to ensure consistency in case of failure, we can set a higher priority to all other bridges. - Use the following commands on **R1\_1:** ```ros /interface/bridge set bridge priority=0x1000 ``` - Use the following commands on **R1\_2**: ```ros /interface/bridge set bridge priority=0x2000 ``` - ... - Use the following commands on **R3\_3**: ```ros /interface/bridge set bridge priority=0x9000 ``` We also need to elect a root port on each bridge; for simplicity, we will choose the port that is closest to **R1\_1** as the root port and has the fewest hops. At this point, the procedure to elect root ports is the same as the procedure in (R)STP. - Use the following commands on **R3\_3:** ```ros /interface/bridge/port set [find where interface=ether2] path-cost=30 set [find where interface=ether3] path-cost=40 set [find where interface=ether4] path-cost=20 ``` - Use the following commands on **R1\_3** and **R2\_3:** ```ros /interface/bridge/port set [find where interface=ether2] path-cost=20 set [find where interface=ether3] path-cost=30 ``` - Use the following commands on **R1\_2**: ```ros /interface/bridge/port set [find where interface=ether1] path-cost=30 ``` --- ## Wireless VLAN Trunk A very common task is to forward only a certain set of VLANs over a Wireless Point-to-Point (PtP) link. This can be done using bridge VLAN filtering and should be used instead of any other methods (including bridging VLAN interfaces). Let's say we need to forward 2 different VLANs over a Wireless link and all other VLAN IDs should be dropped. VLAN 10 is going to be our Internet traffic while VLAN 99 is going to be for our management traffic. Below you can find the network topology: ![Wireless VLAN Trunk](./img/wireless-vlan-trunk-01.webp) ## Configuration Start by creating a new bridge on **AP** and **ST** and add **ether1** and **wlan1** ports to it: ```ros /interface/bridge add name=bridge protocol-mode=none /interface/bridge/port add bridge=bridge interface=ether1 add bridge=bridge interface=wlan1 ``` :::info You can enable RSTP if it is required, but generally, RSTP is not required for PtP links since there should not be any way for a loop to occur. ::: For security reasons, you should enable ingress-filtering since you are expecting only tagged traffic. Then you can set the bridge to filter out all untagged traffic. Do the following on **AP** and **ST**: ```ros /interface/bridge/port set [find where interface=ether1 or interface=wlan1] frame-types=admit-only-vlan-tagged ingress-filtering=yes ``` Set up the bridge VLAN table. Since VLAN99 is going to be our management traffic, then we need to allow this VLAN ID to be able to access the bridge interface, otherwise, the traffic will be dropped as soon as you try to access the device. VLAN10 does not need to access the bridge since it is only meant to be forwarded to the other end. To achieve such functionality, add these entries to the bridge VLAN table on **AP** and **ST**: ```ros /interface/bridge/vlan add bridge=bridge tagged=ether1,wlan1 vlan-ids=10 add bridge=bridge tagged=ether1,wlan1,bridge vlan-ids=99 ``` :::info Interface Access Control You can restrict management access to the device by interface. If you wish to prevent access from a specific interface (e.g., `wlan1`), simply remove that interface from the corresponding bridge VLAN entry. ::: :::warning Handling Wireless & HW-Offloaded VLANs For devices with hardware-offloaded VLAN filtering and wireless support (e.g., RB4011, LtAP), exercise caution. Packets flowing from HW-offloaded ports to wireless interfaces may be dropped if CPU access for that VLAN is not explicitly permitted. To allow CPU access for a specific VLAN: * **Add the bridge interface** as a member of that VLAN (see the VLAN99 example). * **Alternatively, disable HW offloading** on the affected bridge ports. ::: All devices (**R1**, **R2**, **AP,** and **ST**) need a VLAN interface created to be able to access the device through the specific VLAN ID. For **AP** and **ST** create the VLAN interface on top of the bridge interface and assign an IP address to it: ```ros /interface/vlan add interface=bridge name=MGMT vlan-id=99 /ip/address add address=192.168.99.X/24 interface=MGMT ``` For **R1** and **R2**, do the same, but the interface, on which you need to create the VLAN interface, will probably change, depending on your setup: ```ros /interface/vlan add interface=ether1 name=MGMT vlan-id=99 /ip/address add address=192.168.99.X/24 interface=MGMT ``` :::info To allow more VLANs to be forwarded, you simply need to specify more VLAN IDs in the bridge VLAN table, you can specify multiple VLANs divided by comma or even VLAN ranges. ::: ### Setup the Wireless link on **AP** ```ros /interface/wireless/security-profiles add authentication-types=wpa2-psk mode=dynamic-keys name=wlan_sec wpa2-pre-shared-key=use_a_long_password_here /interface/wireless set wlan1 band=5ghz-a/n/ac channel-width=20/40/80mhz-Ceee disabled=no mode=bridge scan-list=5180 security-profile=wlan_sec ssid=ptp_test ``` ### Setup the Wireless link on **ST** ```ros /interface/wireless/security-profiles add authentication-types=wpa2-psk mode=dynamic-keys name=wlan_sec wpa2-pre-shared-key=use_a_long_password_here /interface/wireless set wlan1 band=5ghz-a/n/ac channel-width=20/40/80mhz-Ceee disabled=no mode=station-bridge scan-list=5180 security-profile=wlan_sec ssid=ptp_test ``` :::info For each type of setup, there are different requirements. For PtP links NV2 wireless protocol is commonly used. You can read more about NV2 on the [NV2 Manual](../../wireless/abgn/nv2.md) page. ::: When links are set up, you can enable bridge VLAN filtering on **AP** and **ST**: ```ros /interface/bridge set bridge vlan-filtering=yes ``` :::danger Double-check the bridge VLAN table before enabling VLAN filtering. A misconfigured bridge VLAN table can lead to the device being inaccessible and a configuration reset might be required. ::: --- ## WMM and VLAN priority ## How WMM works --- WMM works by dividing traffic into 4 access categories: background, best effort, video, voice. QoS policy (different handling of access categories) is applied to transmitted packets, therefore the transmitting device is treating different packets differently, e.g. AP does not have control over how clients are transmitting packets, and clients do not have control over how AP transmits packets. Mikrotik AP and client classify packets based on the priority assigned to them, according to the table (as per WMM specification): 1,2 - background; 0,3 - best effort; 4,5 - video; 6,7 - voice. To be able to use multiple WMM access categories, not just the best effort where all packets with default priority 0 go, priority must be set for those packets. By default, all packets (incoming and locally generated) inside the router have priority 0. The "Better" access category for a packet does not necessarily mean that it will be sent over the air before all other packets with the "worse" access category. WMM works by executing the DCF method for medium access with different settings for each access category (EDCF), which means that the "better" access category has a higher probability of getting access to the medium - A WMM enabled station can be considered to be 4 stations, one per access category, and the ones with the "better" access category use settings that make them more likely to get a chance to transmit (by using shorter backoff timeouts) when all are contending for the medium. Details can be studied in 802.11e and WMM specifications. :::info WMM support can be enabled using the `wmm-support` setting. It only applies to bands B and G. Other bands will have it enabled regardless of this setting. ::: ## How VLAN priority works --- The VLAN priority is a 3-bit field called Priority Code Point (PCP) within a VLAN-tagged header and values are between 0 and 7. It is used for implementing QoS on bridges and switches. MikroTik devices by default are sending VLAN packets (locally generated or encapsulated) with a priority of 0. The RouterOS bridge forwards VLAN tagged packets unaltered, which means that received VLAN tagged packets with a certain VLAN priority will leave the bridge with the same VLAN priority. The only exception is when the bridge untags the packet; in this situation, VLAN priority is not preserved due to the missing VLAN header. More details can be studied in the IEEE 802.1p specification. ## How to set priority --- Priority of packets can be set using `action=set-priority` in IP firewall mangle rules or bridge filter/nat rules. Priority can be set to a specific value or taken from the ingress priority using the `from-ingress` setting. Ingress priority is the priority value that was detected on the incoming packet, if available. Currently, there are 2 sources of ingress priority - priority in the VLAN header and priority from the WMM packet received over a wireless interface. For all other packets, ingress priority is 0. Note that ingress priority value is not automatically copied to IP mangle `priority` value. The correct rule needs to be set up to do this. There are 2 ways to control priority - assign priority with rules with particular matchers (protocol, addresses, etc.) or set it from ingress priority. Both options require setting up correct rules. This essentially means that if it is not possible or not wanted to classify packets by rules, the configuration of the network must be such that the router can extract ingress priority from incoming frames. Remember there are currently 2 sources for this - VLAN tag in packets and received WMM packets. :::info Do not mix the priority of queues with the priority assigned to packets. Priorities of queues work separately and specify the "importance" of the queue and have meaning only within a particular queue setup. Think of packet priority as some kind of mark that gets attached to the packet by rules. Also, take into account that this mark currently is only used for outgoing packets when going over a WMM enabled link, and in case a VLAN tagged packet is sent out (no matter if that packet is tagged locally or bridged). ::: ### Set VLAN or WMM priority based on specific matchers It is possible to change the VLAN and WMM priorities based on specific matchers in IP mangle or bridge filter/nat rules. In this example, all outgoing ICMP packets will be sent with a VLAN or WMM priority using the IP mangle rule: ```ros /ip/firewall/mangle add action=set-priority chain=output new-priority=2 protocol=icmp ``` ### Custom priority mapping Sometimes certain VLAN or WMM priorities need to be changed or cleared to a default value. We can use the `ingress-priority` matcher in IP mangle or bridge firewall/nat rules to filter only the needed priorities and change them to a different value using the `new-priority` action setting. For example, forwarded VLAN tagged packets over a bridge with a priority of 5 need to be changed to 0. ```ros /interface/bridge/filter add action=set-priority chain=forward ingress-priority=5 new-priority=0 ``` ### Translating WMM priority to VLAN priority inside a bridge When a wireless packet is received with an already set WMM priority, the RouterOS bridge does not automatically translate it to a VLAN header. It means that received wireless packets with WMM priority that get VLAN tagged by the bridge will be forwarded with a VLAN priority of 0. However, we can use a bridge filter rule with the `from-ingress` setting to keep the priority in VLAN packets. For example, we would like to forward wireless packets over ether2 with a VLAN 10 header and keep the already set WMM priority (set by the wireless client). ```ros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/bridge/port add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=wlan2 pvid=10 /interface/bridge/vlan add bridge=bridge1 tagged=ether2 vlan-ids=10 # translates WMM priority to VLAN priority /interface/bridge/filter add action=set-priority chain=forward new-priority=from-ingress out-interface=ether2 ``` The same situation applies when wireless packets are VLAN tagged by the wireless interface using the `vlan-mode=use-tag` and `vlan-id` settings. You still need to use the same bridge filter rule to translate WMM priority to VLAN priority: ```ros /interface/wireless set [ find default-name=wlan2 ] vlan-mode=use-tag vlan-id=10 /interface/bridge add name=bridge1 /interface/bridge/port add bridge=bridge1 interface=ether2 add bridge=bridge1 interface=wlan2 # translates WMM priority to VLAN priority /interface/bridge/filter add action=set-priority chain=forward new-priority=from-ingress out-interface=ether2 ``` :::info The same principles apply in reverse. RouterOS does not automatically translate VLAN priority to WMM priority; you can use the `new-priority=from-ingress` rule to perform this translation. The RouterOS bridge forwards VLAN-tagged packets unaltered, meaning they leave the bridge with the same priority they entered with. The only exception occurs when the bridge untags the packet, as the priority information is lost when the VLAN header is removed. ::: ## Priority from DSCP --- Another way of setting VLAN or WMM priority is by using the DSCP field in the IP header. This can only be done by the IP firewall mangle rule with `new-priority=``from-dscp` or `new-priority=from-dscp-high-3-bits` settings and `set-priority` action property. Note that DSCP in the IP header can have values 0-63, but priority is only 0-7. When using the `new-priority=``from-dscp` setting, the priority will be 3 low bits of the DSCP value, but when using `new-priority=from-dscp-high-3-bits` the priority will be 3 high bits of the DSCP value. Remember that DSCP can only be accessed on IP packets and the DSCP value in the IP header should be set somewhere (either by client devices or IP mangle rules). It is best to set the DSCP value in the IP header of packets on some border router (e.g., a main router used for connection to the Internet), based on traffic type e.g., set the DSCP value for packets coming from the Internet belonging to SIP connections to 7, and 0 for the rest. This way, packets must be marked only in one place. Then all APs on the network can set packet priority from the DSCP value with just one rule. ### Set VLAN or WMM priority from DSCP In this example, the AP device will set WMM priority from DSCP when packets are routed through the wireless interface. ```ros /ip/firewall/mangle add action=set-priority chain=forward new-priority=from-dscp out-interface=wlan2 ``` :::info When packets are forwarded through a bridge, it is possible to pass packets through IP mangle rules with `use-ip-firewall=yes` under the bridge settings. ::: ## DSCP from Priority --- Similarly, the DSCP value can be set if the received packet contains VLAN or WMM priority. This can be achieved with IP mangle rules with `new-dscp=from-priority` or `new-dscp=from-priority-to-high-3-bits` settings and `change-dscp` action property. Note that priority in VLAN or WMM packets can have values 0-7, but DSCP in IP headers is 0-63. When using the `new-dscp=from-priority` setting, the value of priority will set the 3 low bits of the DSCP, but when using `new-dscp=from-priority-to-high-3-bits` the value of priority will set the 3 high bits of the DSCP. However, this setting cannot directly use ingress priority from received VLAN or WMM packets. You first need to set priority using IP mangle or bridge filter/nat rules (ingress priority can be used in this case), and only then apply the DSCP rule. ### Set DSCP from VLAN or WMM priority In this example, the AP device needs to set DSCP from WMM priority when packets are routed. First, add a rule to set priority. It will be needed for the DSCP rule to correctly change the DSCP value. This rule can take priority from ingress. Then add the DSCP rule to change its value. ```ros /ip/firewall/mangle add action=set-priority chain=prerouting in-interface=wlan2 new-priority=from-ingress add action=change-dscp chain=prerouting in-interface=wlan2 new-dscp=from-priority ``` :::info When packets are forwarded through a bridge, it is possible to pass packets through IP mangle rules with `use-ip-firewall=yes` under the bridge settings. ::: ## Combining priority setting and handling solutions --- Complex networks and different situations can be handled by combining different approaches to carrying priority information to ensure QoS and optimize the use of resources, based on the "building blocks" described above. Several suggestions: - The fewer filter rules in the whole network, the better (faster). Try classifying packets only when necessary, prefer to do that on fast routers as most probably connection tracking will be required. - Use DSCP to carry priority information in IP packets forwarded in your network. This way you can use it when needed. - Use VLANs where necessary, as they also carry priority information. Make sure Ethernet bridges and switches in the way are not clearing priority information in the VLAN tag. - Remember that QoS does not improve the throughput of links; it just treats different packets differently, and also that WMM traffic over the wireless link will discriminate regular traffic in the air. ## See also --- - [Packet Flow in RouterOS](../../firewall-and-quality-of-service/packet-flow-in-routeros.md) - [IP mangle](../../firewall-and-quality-of-service/firewall/mangle.md) - [Bridge firewall](../#bridge-firewall) --- ## VLAN **Sub-menu:** `/interface/vlan` **Standards:** `IEEE 802.1Q, IEEE 802.1ad` Virtual Local Area Network (VLAN) is a Layer 2 method that allows multiple Virtual LANs on a single physical interface (ethernet, wireless, etc.), giving the ability to segregate LANs efficiently. You can use MikroTik RouterOS (as well as Cisco IOS, Linux, and other router systems) to mark these packets as well as to accept and route marked ones. As VLAN works on OSI Layer 2, it can be used just like any other network interface without any restrictions. VLAN successfully passes through regular Ethernet bridges. You can also transport VLANs over wireless links and put multiple VLAN interfaces on a single wireless interface. Note that as VLAN is not a full tunnel protocol (i.e., it does not have additional fields to transport MAC addresses of the sender and the recipient), the same limitation applies to bridging over VLAN as to bridging plain wireless interfaces. In other words, while wireless clients may participate in VLANs put on wireless interfaces, it is not possible to have a VLAN put on a wireless interface in station mode bridged with any other interface. ## 802.1Q The most commonly used protocol for Virtual LANs (VLANs) is IEEE 802.1Q. It is a standardized encapsulation protocol that defines how to insert a four-byte VLAN identifier into the Ethernet header. Each VLAN is treated as a separate subnet. It means that by default, a host in a specific VLAN cannot communicate with a host that is a member of another VLAN, although they are connected to the same switch. So if you want inter-VLAN communication, you need a router. RouterOS supports up to 4094 VLAN interfaces, each with a unique VLAN ID, per interface. VLAN priorities may also be used and manipulated. When the VLAN extends over more than one switch, the inter-switch link has to become a 'trunk', where packets are tagged to indicate which VLAN they belong to. A trunk carries the traffic of multiple VLANs; it is like a point-to-point link that carries tagged packets between switches or between a switch and a router. :::info The IEEE 802.1Q standard has reserved VLAN IDs with special use cases; the following VLAN IDs should not be used in generic VLAN setups: 0, 1, 4095 ::: ## Q-in-Q Original 802.1Q allows only one VLAN header; Q-in-Q, on the other hand, allows two or more VLAN headers. In RouterOS, Q-in-Q can be configured by adding one VLAN interface over another. Example: ```ros /interface/vlan add name=vlan1 vlan-id=11 interface=ether1 add name=vlan2 vlan-id=12 interface=vlan1 ``` If any packet is sent over the 'vlan2' interface, two VLAN tags will be added to the Ethernet header - '11' and '12'. ## Properties **Sub-menu:** `/interface/vlan` | Property | Description | | :-- | :-- | | **arp** (*disabled \| enabled \| local-proxy-arp \| proxy-arp \| reply-only*; Default: **enabled**) | Address Resolution Protocol settingdisabled - the interface will not use ARPenabled - the interface will use ARPlocal-proxy-arp - the router performs proxy ARP on the interface and sends replies to the same interfaceproxy-arp - the router performs proxy ARP on the interface and sends replies to other interfacesreply-only - the interface will only reply to requests originated from matching IP address/MAC address combinations which are entered as static entries in the IP/ARP table. No dynamic entries will be automatically stored in the IP/ARP table. Therefore for communications to be successful, a valid static entry must already exist. | | **arp-timeout** (*auto \| integer*; Default: **auto**) | How long the ARP record is kept in the ARP table after no packets are received from IP. Value `auto` equals the value of `arp-timeout` in IP/Settings, default is 30s. | | **disabled** (*yes \| no*; Default: **no**) | Changes whether the interface is disabled. | | **interface** (*name*; Default: ) | Name of the interface on top of which VLAN will work. **Important:** Adding a VLAN interface to a [bridge with vlan-filtering](./#bridge-vlan-filtering) enabled will automatically tag the bridge interface as a member port. A dynamic entry with the comment "added by vlan on bridge" will appear under the `/interface/bridge/vlan` menu. | | **l3-hw-offloading** (*yes \| no*; Default: **yes**) | Enables or disables [L3HW](./l3-hardware-offloading.md) on a per-VLAN interface. This setting is only applicable to devices that support L3HW offloading and is available starting from RouterOS v7.21. More details - [Per-VLAN offloading](l3-hardware-offloading.md#per-vlan-offloading). | | **mvrp** (*yes \| no*; Default: **no**) | Specifies whether this VLAN should declare its attributes through Multiple VLAN Registration Protocol (MVRP) as an applicant. Its main use case is for VLANs that are created on Ethernet interface (such as a "router on a stick" setup) that is connected to a bridge supporting [MVRP](index.md#mvrp). Enabling this option on a VLAN interface that is already part of an MVRP-enabled bridge has no effect, as the bridge manages MVRP in that case. This property only has an effect when `use-service-tag` is disabled. | | **mtu** (*integer: 68..65535*; Default: **1500**) | Layer3 Maximum transmission unit | | **name** (*string*; Default: ) | Interface name | | **use-service-tag** (*yes \| no*; Default: ) | IEEE 802.1ad compatible Service Tag | | **vlan-id** (*integer: 1..4094*; Default: **1**) | Virtual LAN identifier or tag that is used to distinguish VLANs. Must be equal for all computers that belong to the same VLAN. | :::info MTU should be set to 1500 bytes, the same as on Ethernet interfaces. But this may not work with some Ethernet cards that do not support receiving/transmitting full-size Ethernet packets with VLAN header added (1500 bytes data + 4 bytes VLAN header + 14 bytes Ethernet header). In this situation, MTU 1496 can be used, but note that this will cause packet fragmentation if larger packets have to be sent over the interface. At the same time, remember that MTU 1496 may cause problems if path MTU discovery is not working properly between source and destination. ::: ## Setup examples --- ### Video examples [VLANs pt1](http://youtube.com/watch?v=US2EU6cgHQU), [VLANs pt2](http://youtube.com/watch?v=YMwOrc0LDP8), [VLANs pt3](http://youtube.com/watch?v=7a_z1jAdIME) ### Layer2 VLAN examples There are multiple possible configurations that you can use, but each configuration type is designed for a special set of devices since some configuration methods will give you the benefits of the built-in switch chip and gain larger throughput. Check the [Basic VLAN switching](./user-guides/basic-vlan-switching.md) guide to see which configuration to use for each type of device to gain maximum possible throughput and compatibility. The guide shows how to set up a very basic VLAN trunk/access port configuration. There are some other ways to set up VLAN tagging or VLAN switching, but the recommended way is to use [Bridge VLAN Filtering](index.md#bridge-vlan-filtering). Make sure you have not used any [known Layer2 misconfigurations](./user-guides/layer2-misconfiguration.md). ### Layer3 VLAN examples #### Simple VLAN routing Let us assume that we have several MikroTik routers connected to a hub. Remember that a hub is an OSI physical layer device (if there is a hub between routers, then from the L3 point of view it is the same as an Ethernet cable connection between them). For simplification, assume that all routers are connected to the hub using the ether1 interface and have been assigned IP addresses as illustrated in the figure below. Then on each of them the VLAN interface is created. Configuration for R2 and R4 is shown below: R2: ```ros [admin@MikroTik] /interface/vlan> add name=VLAN2 vlan-id=2 interface=ether1 disabled=no [admin@MikroTik] /interface/vlan> print Flags: X - disabled, R - running, S - slave # NAME MTU ARP VLAN-ID INTERFACE 0 R VLAN2 1500 enabled 2 ether1 ``` R4: ```ros [admin@MikroTik] /interface/vlan> add name=VLAN2 vlan-id=2 interface=ether1 disabled=no [admin@MikroTik] /interface/vlan> print Flags: X - disabled, R - running, S - slave # NAME MTU ARP VLAN-ID INTERFACE 0 R VLAN2 1500 enabled 2 ether1 ``` The next step is to assign IP addresses to the VLAN interfaces. R2: ```ros [admin@MikroTik] /ip/address> add address=10.10.10.3/24 interface=VLAN2 [admin@MikroTik] /ip/address> print Flags: X - disabled, I - invalid, D - dynamic # ADDRESS NETWORK BROADCAST INTERFACE 0 10.0.1.4/24 10.0.1.0 10.0.1.255 ether1 1 10.20.0.1/24 10.20.0.0 10.20.0.255 pc1 2 10.10.10.3/24 10.10.10.0 10.10.10.255 vlan2 [admin@MikroTik] /ip/address> ``` R4: ```ros [admin@MikroTik] /ip/address> add address=10.10.10.5/24 interface=VLAN2 [admin@MikroTik] /ip/address> print Flags: X - disabled, I - invalid, D - dynamic # ADDRESS NETWORK BROADCAST INTERFACE 0 10.0.1.5/24 10.0.1.0 10.0.1.255 ether1 1 10.30.0.1/24 10.30.0.0 10.30.0.255 pc2 2 10.10.10.5/24 10.10.10.0 10.10.10.255 vlan2 [admin@MikroTik] /ip/address> ``` At this point, it should be possible to ping router R4 from router R2 and vice versa: ```ros "Ping from R2 to R4:" [admin@MikroTik] /ip/address> /ping 10.10.10.5 10.10.10.5 64 byte ping: ttl=255 time=4 ms 10.10.10.5 64 byte ping: ttl=255 time=1 ms 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 1/2.5/4 ms "From R4 to R2:" [admin@MikroTik] /ip/address> /ping 10.10.10.3 10.10.10.3 64 byte ping: ttl=255 time=6 ms 10.10.10.3 64 byte ping: ttl=255 time=1 ms 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 1/3.5/6 ms ``` To make sure the VLAN setup is working properly, try to ping R1 from R2. If pings are timing out then VLANs are successfully isolated. ```ros "From R2 to R1:" [admin@MikroTik] /ip/address> /ping 10.10.10.2 10.10.10.2 ping timeout 10.10.10.2 ping timeout 3 packets transmitted, 0 packets received, 100% packet loss ``` #### InterVLAN routing If separate VLANs are implemented on a switch, then a router is required to provide communication between VLANs. A switch works at OSI layer 2, so it uses only the Ethernet header to forward and does not check the IP header. For this reason, we must use the router that is working as a gateway for each VLAN. Without a router, a host is unable to communicate outside of its own VLAN. The routing process between VLANs described above is called inter-VLAN communication. To illustrate inter-VLAN communication, we will create a trunk that will carry traffic from three VLANs (VLAN2, VLAN3, and VLAN4) across a single link between a Mikrotik router and a manageable switch that supports VLAN trunking. Each VLAN has its own separate subnet (broadcast domain) as we see in the figure above: - VLAN 2 – 10.10.20.0/24. - VLAN 3 – 10.10.30.0/24. - VLAN 4 – 10.10.40.0/24. VLAN configuration on most switches is straightforward. We need to define which ports are members of the VLANs and define a 'trunk' port that can carry tagged frames between the switch and the router. Create VLAN interfaces: ```ros /interface/vlan add name=VLAN2 vlan-id=2 interface=ether1 disabled=no add name=VLAN3 vlan-id=3 interface=ether1 disabled=no add name=VLAN4 vlan-id=4 interface=ether1 disabled=no ``` Add IP addresses to VLANs: ```ros /ip/address add address=10.10.20.1/24 interface=VLAN2 add address=10.10.30.1/24 interface=VLAN3 add address=10.10.40.1/24 interface=VLAN4 ``` #### RouterOS /32 and IP unnumbered addresses In RouterOS, to create a point-to-point tunnel with addresses you have to use the address with a network mask of '/32' that effectively brings you the same features as some vendors' unnumbered IP address. There are 2 routers, RouterA and RouterB, where each is part of networks 10.22.0.0/24 and 10.23.0.0/24 respectively, and to connect these routers using VLANs as a carrier with the following configuration: RouterA: ```ros /ip/address/add address=10.22.0.1/24 interface=ether1 /interface/vlan/add interface=ether2 vlan-id=1 name=vlan1 /ip/address/add address=10.22.0.1/32 interface=vlan1 network=10.23.0.1 /ip/route/add gateway=10.23.0.1 dst-address=10.23.0.0/24 ``` RouterB: ```ros /ip/address/add address=10.23.0.1/24 interface=ether1 /interface/vlan/add interface=ether2 vlan-id=1 name=vlan1 /ip/address/add address=10.23.0.1/32 interface=vlan1 network=10.22.0.1 /ip/route/add gateway=10.22.0.1 dst-address=10.22.0.0/24 ``` --- ## VXLAN --- Virtual eXtensible Local Area Network (VXLAN) is a tunneling protocol designed to solve the problem of limited VLAN IDs (4096) in IEEE 802.1Q, and it is described by IETF RFC 7348. With VXLAN the size of the identifier is expanded to 24 bits (16777216). It creates a Layer 2 overlay scheme on a Layer 3 network and the protocol runs over UDP. RouterOS VXLAN interface supports IPv4 or IPv6 (since version 7.6), but dual-stack is not supported. :::info VXLAN creates a 50-byte overhead for IPv4 and a 70-byte overhead for IPv6. When configuring VXLAN, it is recommended to ensure that the size of the encapsulated Ethernet frame does not exceed the MTU of the underlying network, by configuring the MTU accordingly or by limiting the size of the Ethernet frames. ::: Only devices within the same VXLAN segment can communicate with each other. Each VXLAN segment is identified through a 24-bit segment ID, termed the VXLAN Network Identifier (VNI). Unlike most tunnels, a VXLAN is a 1-to-N network, not just point-to-point. VXLAN endpoints, which terminate VXLAN tunnels, are known as VXLAN tunnel endpoints (VTEPs). RouterOS only supports statically configured remote VTEPs. When unicast traffic needs to be sent over VXLAN, a device can learn the IP address of the other endpoint dynamically in a manner similar to a learning bridge, and forward traffic only to the necessary VTEP. For traffic that needs to be flooded (broadcast, unknown-unicast, and multicast) to all VTEPs on the same segment, VXLAN can use multicast or unicast with head-end replication to send one replica for every remote VTEP. ## Configuration options --- This section describes the VXLAN interface and VTEP configuration options. **Sub-menu:** `/interface/vxlan` | Property | Description | | :-- | :-- | | **allow-fast-path** (*yes \| no*; Default: **yes**) | Whether to allow [Fast Path](../firewall-and-quality-of-service/packet-flow-in-routeros.md#fast-path) processing. Fragmented and flooded packets over VXLAN are redirected via a slow path. Fast Path is disabled for VXLAN interface that uses VRF. The setting is available since RouterOS version 7.8. | | **arp** (*disabled \| enabled \| local-proxy-arp \| proxy-arp \| reply-only*; Default: **enabled**) | Address Resolution Protocol settingdisabled - the interface will not use ARPenabled - the interface will use ARPlocal-proxy-arp - the router performs proxy ARP on the interface and sends replies to the same interfaceproxy-arp - the router performs proxy ARP on the interface and sends replies to other interfacesreply-only - the interface will only reply to requests originating from matching IP address/MAC address combinations which are entered as static entries in the IP/ARP table. No dynamic entries will be automatically stored in the IP/ARP table. Therefore for communications to be successful, a valid static entry must already exist. | | **arp-timeout** (*auto \| integer*; Default: **auto**) | How long the ARP record is kept in the ARP table after no packets are received from IP. Value `auto` equals to the value of `arp-timeout` in IP/Settings, default is the 30s. | | **bridge** (*name*; Default: ) | Name of the [bridge](../user-guides/routing-and-networking-protocols/unicast/bgp/index.md) interface to which VXLAN interface will be added as a slave port. | | **bridge-pvid** (*integer 1..4094;* Default: **1**) | Used to assign PVID parameter for dynamically bridge port. This property only has an effect when bridge vlan-filtering is set to yes. | | **checksum**(*yes \| no*; Default: **no**) | Setting controls whether a UDP checksum is calculated in the transmitted outer VXLAN packets: no – the UDP checksum is set to zero in transmitted outer packets. This also allows receiving VXLAN packets over IPv6 that have a zero UDP checksum.yes - the UDP checksum is calculated in transmitted outer packets. If hardware offloading is used for packet transmission, this setting is ignored, and the behavior defaults to sending packets with a zero UDP checksum. | | **comment** (*string*; Default: ) | Short description of the interface. | | **disabled** (*yes \| no*; Default: **no**) | Changes whether the interface is disabled. | | **dont-fragment**(*auto \| disabled \| enabled \| inherit*; Default: **auto**) | The Don't Fragment (DF) flag controls whether a packet can be broken into smaller packets, called fragments, before being sent over a network. When configuring VXLAN, this setting determines the presence of the DF flag on the outer IPv4 header and can control packet fragmentation if the encapsulated packet exceeds the outgoing interface MTU. This setting has three options: auto - if the device supports VXLAN offloading, the dont-fragment mode will operate as enabled. if VXLAN offloading is not supported, it will use the inherit mode.disabled - the DF flag is not set on the outer IPv4 header, which means that packets can be fragmented if they are too large to be sent over the outgoing interface. This also allows packet fragmentation when VXLAN uses IPv6 underlay. Disables hardware offloading on compatible devices.enabled - the DF flag is always set on the outer IPv4 header, which means that packets will not be fragmented and will be dropped if they exceed the outgoing interface's MTU. This also avoids packet fragmentation when VXLAN uses IPv6 underlay.inherit - The DF flag on the outer IPv4 header is based on the inner IPv4 DF flag. If the inner IPv4 header has the DF flag set, the outer IPv4 header will also have it set. If the packet exceeds the outgoing interface's MTU and DF is set, it will be dropped. If the inner packet is non-IP, the outer IPv4 header will not have the DF flag set and packets can be fragmented. If the inner packet is IPv6, the outer IPv4 header will always set the DF flag and packets cannot be fragmented. Note that when VXLAN uses IPv6 underlay, this setting does not have any effect and is treated the same as disabled. The setting is available since RouterOS version 7.8. | | **group** (*IPv4 \| IPv6*; Default: ) | When specified, a multicast group address can be used to forward broadcast, unknown-unicast, and multicast traffic between VTEPs. This property requires specifying the `interface` setting. The interface will use IGMP or MLD to join the specified multicast group, make sure to add the necessary PIM and IGMP/MLD configuration. When this property is set, the `vteps-ip-version` automatically gets updated to the used multicast IP version. Disables hardware offloading on compatible devices. | | **hw** (*yes \| no*; Default: **yes**) | Allows to disable hardware offloading, only applies to devices that support VXLAN offloading. | | **interface** (*name*; Default: ) | Interface name used for multicast forwarding. This property requires specifying the `group` setting. Disables hardware offloading on compatible devices. | | **learning**(*yes \| no*; Default: **yes**) | Setting controls whether inner source MAC addresses and remote VTEP IP/IPv6 addresses are learned dynamically from received packets. | | **local-address** (*IPv4 \| IPv6*; Default: ) | Specifies the local source address for the VXLAN interface. If not set, one IP address of the egress interface will be selected as a source address for VXLAN packets. When the property is set, the `vteps-ip-version` automatically gets updated to the used local IP version. The setting is available since RouterOS version 7.7. | | **mac-address** (*MAC*; Default: ) | Static MAC address of the interface. A randomly generated MAC address will be assigned when not specified. | | **max-fdb-size** (*integer: 1*..65535**; Default: **4096**) | Limits the maximum number of MAC addresses that VXLAN can store in the forwarding database (FDB). | | **mtu** (*integer*; Default: **1500**) | For the maximum transmission unit, the VXLAN interface will set MTU to 1500 by default. The `l2mtu` will be set automatically according to the associated `interface` (subtracting 50 bytes corresponding to the VXLAN header). If no interface is specified, the `l2mtu` value of 65535 is used. The `l2mtu` cannot be changed. | | **name** (*text*; Default: **vxlan1**) | Name of the interface. | | **port** (*integer: 1*..65535**; Default: **4789**) | Used UDP port number for listening and sending packets to remote VTEPs. | | **rem-csum** (*both \| none \| rx \| tx*; Default: **none**) | Changes the Remote Checksum Offload (RCO) settings for VXLAN interface. RCO is a technique for eliding the inner checksum of an encapsulated datagram, allowing the outer checksum to be offloaded by network driver. It does, however, involve a change to the encapsulation protocols, which the receiver must also support. For this reason, it is disabled by default and setting is available to ensure compatibility with systems that rely on this feature. RCO is detailed in the following Internet-Drafts: Remote checksum offload for VXLAN, draft-herbert-vxlan-rco-00. Remote checksum offload for encapsulation, draft-herbert-remotecsumoffload-00. If [hardware offloading](./vxlan.md#hardware-offloaded-vxlan) is used, this setting is ignored, and the behavior defaults to none. | | **ttl** (*auto \| integer: 0*..255**; Default: **auto**) | Specifies the TTL value to use in outgoing packets. By default, the TTL is set to 64 when using the `auto` option. However, if VXLAN is using a multicast underlay network, the default TTL is set to 1. If the multicast network involves routing, you will need to increase the TTL to a higher value. | | **vni** (*integer: 1..16777215*; Default: ) | VXLAN Network Identifier (VNI). | | **vtep-vrf** (*name*; Default: **main**) | Set VRF for the VXLAN interface on which the VTEPs listen and make connections. VRF is not supported when using `interface` and multicast `group` settings. The same UDP `port` cannot be used in multiple routing tables at the same time. When using a VRF that is not set as the "main", hardware offloading is disabled on compatible devices. The setting is available since RouterOS version 7.7. | | **vteps-ip-version** (*ipv4 \| ipv6*; Default: **ipv4**) | Used IP protocol version for statically configured VTEPs. The RouterOS VXLAN interface does not support dual-stack, any configured remote VTEPs with the opposite IP version will be ignored. When multicast `group` or `local-address` properties are set, the `vteps-ip-version` automatically gets updated to the used IP version. Using IPv6 disables hardware offloading on compatible devices. The setting is available since RouterOS version 7.6. | **Sub-menu:** `/interface/vxlan/vteps` | Property | Description | | :-- | :-- | | **comment** (*string*; Default: ) | Short description of the configured VTEP. | | **interface** (*name*; Default: ) | Name of the VXLAN interface. | | **remote-ip** (*IPv4 \| IPv6*; Default: ) | Defines the VTEP endpoint IPv4 or IPv6 address which is used when the VXLAN interface needs to send BUM (broadcast, unknown-unicast, multicast) traffic. It is not used as access control. | ## Forwarding table --- Since RouterOS version 7.9, it is possible to monitor the learned MAC addresses from remote VTEPs. **Sub-menu:** `/interface/vxlan/fdb` | Property | Description | | :-- | :-- | | **interface** (*read-only: *name**) | Name of the VXLAN interface. | | **mac-address** (*read-only: MAC address*) | MAC address. | | **remote-ip** (*read-only: IPv4 \| IPv6 address*) | The IPv4 or IPv6 destination address of the remote VTEP. | ```ros [admin@MikroTik] > /interface/vxlan/fdb/print 0 remote-ip=2001::2 mac-address=56:FF:AA:1A:72:33 interface=vxlan1 1 remote-ip=2002::2 mac-address=AE:EC:C4:12:8B:B9 interface=vxlan1 2 remote-ip=192.168.10.20 mac-address=FE:AF:58:31:A7:B6 interface=vxlan2 ``` ## Configuration example --- This configuration example creates a single VXLAN tunnel between two statically configured VTEP endpoints. First, create VXLAN interfaces on both routers. ```ros /interface/vxlan add name=vxlan1 port=4789 vni=10 ``` Then configure VTEPs on both routers with respective IPv4 destination addresses. Both devices should have an active route toward the destination address. ```ros # Router1 /interface/vxlan/vteps add interface=vxlan1 remote-ip=192.168.10.10 # Router2 /interface/vxlan/vteps add interface=vxlan1 remote-ip=192.168.20.20 ``` The configuration is complete. It is possible to include the VXLAN interface into a bridge with other Ethernet interfaces. ## Hardware offloaded VXLAN --- Starting from RouterOS version 7.18, initial support for hardware-offloaded VXLAN was introduced. This makes the offloaded VXLAN data plane possible, supporting encapsulation and decapsulation, and allowing for static one-to-one VLAN-to-VXLAN mappings within a vlan-filtering bridge. Refer to the [L3HW Device Support](./l3-hardware-offloading.md#l3hw-device-support) documentation for a list of compatible devices. At this point, some known features are not yet implemented. ### Underlay (routing encapsulated VXLAN packets) 1. VTEPs are not supported over ECMP. 2. VTEPs are not supported over bond, bridge, VLAN interfaces (only stand-alone routed Ethernet interfaces are supported). 3. VTEPs are not supported over multicast. 4. VTEPs cannot operate within VRFs. 5. VTEPs are not supported with IPv6. ### Overlay (forwarding between Ethernet and VXLAN) 1. VLAN tagging over VXLAN is not supported. 2. Routing between different VXLAN VNIs is not supported. 3. VTEPs are isolated, and there is no mechanism to control "horizon" between them. 4. Bridged VXLAN interfaces do not support IGMP snooping. When snooping is enabled, MDB entries on VXLAN are not offloaded, and multicast traffic gets restricted between Ethernet and VXLAN. 5. Bridged VXLAN interfaces are not supported by MLAG. ### Basic configuration example In this example, static routing is used to reach remote VTEPs, but dynamic routing protocols like OSPF or BGP could also be used. The upstream interface has a higher MTU to support large packets and VXLAN encapsulation. Below is a network topology overview: **sfp-sfpplus1** - upstream (underlay) interface **sfp-sfpplus3** - bridged port for untagged VLAN 10 **sfp-sfpplus4** - bridged port for untagged VLAN 20 **vxlan-10010** - overlay port for untagged VLAN 10 **vxlan-10020** - overlay port for untagged VLAN 20 ```routeros /interface/bridge add name=bridge1 vlan-filtering=yes /interface/ethernet set [ find default-name=sfp-sfpplus1 ] l2mtu=9500 mtu=9500 /interface/vxlan add bridge=bridge1 bridge-pvid=10 local-address=192.168.1.1 name=vxlan-10010 vni=10010 add bridge=bridge1 bridge-pvid=20 local-address=192.168.1.1 name=vxlan-10020 vni=10020 /interface/bridge/port add bridge=bridge1 interface=sfp-sfpplus3 pvid=10 add bridge=bridge1 interface=sfp-sfpplus4 pvid=20 /interface/vxlan/vteps add interface=vxlan-10010 remote-ip=192.168.1.2 add interface=vxlan-10020 remote-ip=192.168.1.2 /ip/address add address=192.168.1.1 interface=lo network=192.168.1.1 add address=192.168.10.10/24 interface=sfp-sfpplus1 network=192.168.10.0 /ip/route add dst-address=192.168.1.2 gateway=192.168.10.20 /interface/ethernet/switch set 0 l3-hw-offloading=yes ``` --- ## app import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # app **Syscap:** app **Package:** container **Type:** Directory Application is disabled (not downloaded/installed or downloaded but disabled) Application is actively running and accessible Custom application created by the user Application installed from a custom app store Specifies the command-line argument(s) to pass to the application when starting the container Enables or disables automatic updating when a new container image version is available Uses HTTPS for the application URL. This option will not work on devices that do not support cloud services Specifies which network the container will use: internal (behind NAT), lan (on the LAN network), or default (varies per application) Sets the Port VLAN ID (PVID) for the container's virtual Ethernet interface in the bridge Allows network outgoing access for the specific container app. When set to no, a mangle drop rule is created Configures port redirection from the host device to the container Provides the YAML composition for the application. See the documentation for configuration examples Mount directories required for the container to start. Format: [dir-on-host]:[dir-in-app] Specifies additional mount points to attach to the container Defines environment variables to be available to the running application. Specify as a list of key-value pair(s) Hardware devices that must be present on the host for the container to start. Format: [host-hw-device]:[device-in-app] Specifies additional hardware devices to pass through to the container application The URL of the app store from which the application was installed The application name as defined in the YAML configuration The application description as defined in the YAML configuration The application project page URL as defined in the YAML configuration Application functional classification The generated URL for the application web interface, if available The default credentials required for the application The current status of the application (acquire veth, configuring container(s), downloading/extracting, starting) The default network used by the application (lan or internal) The VETH interface used by the application The IP address assigned to the VETH interface The current CPU usage percentage by the application The amount of memory currently used by the application The total size of the application The size of the data stored by the application A list of all variables present in the application environment ## app/cleanup **Package:** container **Type:** Command Removes all application data, configuration files, and the container image. This operation is destructive and irreversible. ## app/network **Package:** container **Type:** Directory ## app/remove **Package:** container **Type:** Command Removes the specified application from the system. ## app/restart **Package:** container **Type:** Command Restarts the specified running application. ## app/settings **Package:** container **Type:** Settings Directory Global setting that specifies which disk will be used for storage operations Manually specifies the IP address at which the current RouterOS device can be reached Manually specifies the bridge interface that represents the local area network Manually specifies the directory path where all media files will be stored Manually specifies the directory path where all downloaded content will be stored Controls whether links to enabled applications are displayed on the WebFig login page Global setting that enables automatic updates for all installed applications packages Specifies one or more registry mirror URLs for container image retrieval URL to a custom app store. Must point to a YAML array where each application is an element Automatically detected network IP address of the RouterOS device Automatically detected bridge interface used for LAN connectivity Default media storage path, typically located on the system disk Default download directory path, typically located within the media storage area ## app/setup **Package:** container **Type:** Command Starts the setup wizard that automates networking, storage, and registry configuration for the App system. Selected storage disk for application installation Selected LAN bridge interface for container networking Manual IP address override for the RouterOS device ## app/update **Package:** container **Type:** Command Updates the specified application to the latest available container image. --- ## beep import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # beep **Type:** Command Beep the built-in speaker. Supported only on devices with a beeper. Check device pages at [mikrotik.com](https://mikrotik.com) Sound frequency in Hz Duration of the sound in seconds --- ## blink import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # blink **Conditions:** !i386 **Type:** Command Blink one of the LEDs on the device depending on the model. Most likely the USR LED. Duration of blinking in seconds --- ## Caps Man import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## caps-man/aaa **Package:** wireless-rep **Type:** Settings Directory ### caps-man/acl/access-list **Package:** wireless-rep **Type:** Directory ### caps-man/cfg/configuration **Package:** wireless-rep **Type:** Directory ### caps-man/chancfg/channel **Package:** wireless-rep **Type:** Directory ### caps-man/controller/manager **Package:** wireless-rep **Type:** Settings Directory #### caps-man/controller/manager/interface **Package:** wireless-rep **Type:** Directory ### caps-man/dpathcfg/datapath **Package:** wireless-rep **Type:** Directory ### caps-man/ifaceactual/actual-interface-configuration **Package:** wireless-rep **Type:** Directory ## caps-man/interface **Package:** wireless-rep **Type:** Directory ### caps-man/interface/hw-info **Package:** wireless-rep **Type:** Command ### caps-man/interface/possible-channels **Package:** wireless-rep **Type:** Command ### caps-man/interface/reselect-channel **Package:** wireless-rep **Type:** Command ### caps-man/interface/scan **Package:** wireless-rep **Type:** Command ## caps-man/radio **Package:** wireless-rep **Type:** Directory ### caps-man/radio/hw-info **Package:** wireless-rep **Type:** Command ### caps-man/radio/provision **Package:** wireless-rep **Type:** Command ### caps-man/ratescfg/rates **Package:** wireless-rep **Type:** Directory ### caps-man/remoteap/remote-cap **Package:** wireless-rep **Type:** Directory #### caps-man/remoteap/remote-cap/provision **Package:** wireless-rep **Type:** Command #### caps-man/remoteap/remote-cap/set-identity **Package:** wireless-rep **Type:** Command #### caps-man/remoteap/remote-cap/upgrade **Package:** wireless-rep **Type:** Command ### caps-man/rule/provisioning **Package:** wireless-rep **Type:** Directory ### caps-man/seccfg/security **Package:** wireless-rep **Type:** Directory ### caps-man/sta/registration-table **Package:** wireless-rep **Type:** Directory --- ## certificate import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # certificate **Type:** Directory private-key crl smart-card-key authority issued revoked expired trusted acme-managed dynamic ## certificate/add-acme **Type:** Command comma separated list of domain names or a wildcard domain ## certificate/add-scep **Type:** Command stores private key on smart card if hardware supports it check certificate expiry and refresh it if expired ## certificate/builtin **Type:** Directory ## certificate/card-reinstall **Type:** Command ## certificate/card-verify **Type:** Command ## certificate/create-certificate-request **Type:** Command ## certificate/crl **Type:** Directory expired dynamic invalid ### certificate/crl/download **Type:** Command ### certificate/crl/flush **Type:** Command ## certificate/enable-ssl-certificate **Type:** Command domain name for SSL certificate ACME directory url base64url encoded EAB hmac key EAB account id initialize new private key ## certificate/export-certificate **Type:** Command ## certificate/import **Type:** Command mark as trusted disallow private key export ## certificate/issued-revoke **Type:** Command ## certificate/scep-renew **Type:** Command ## certificate/scep-server **Type:** Directory disabled ### certificate/scep-server/otp **Type:** Directory expired #### certificate/scep-server/otp/generate **Type:** Command ### certificate/scep-server/ra **Type:** Directory disabled smart-card-key stores private key on smart card #### certificate/scep-server/ra/renew **Type:** Command ### certificate/scep-server/requests **Type:** Directory #### certificate/scep-server/requests/grant **Type:** Command ## certificate/settings **Type:** Settings Directory RouterOS provided CA certificates auto CRL download and update perform CRL checking when validating trust chain CRL storage location ## certificate/sign **Type:** Command adds CRL URL to created certificate stores CA's private key on smart card issuer CA ## certificate/sign-certificate-request **Type:** Command --- ## Colon import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## colon/root **Conditions:** CONSOLE_DEBUG **Type:** Directory ### colon/root/terminal **Type:** Directory --- ## console import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # console **Type:** Directory ## console/inspect **Type:** Command ## console/settings **Type:** Settings Directory replace reserved characters in file and script names with underscores write background script failures to log default tab width in fullscreen editor --- ## container import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # container **Package:** container **Type:** Directory ## container/config **Package:** container **Type:** Settings Directory ## container/envs **Package:** container **Type:** Directory ## container/kill **Package:** container **Type:** Command ## container/layers **Package:** container **Type:** Directory ## container/log **Package:** container **Type:** Directory ## container/mounts **Package:** container **Type:** Directory ## container/repull **Package:** container **Type:** Command ## container/restart **Package:** container **Type:** Command ## container/start **Package:** container **Type:** Command ## container/stop **Package:** container **Type:** Command ## container/update **Package:** container **Type:** Command --- ## disk import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # disk **Conditions:** !smips **Type:** Directory disabled acquired empty block-device mounted formatting swap-enabled raid-member-failed raid-member encrypted guid-partition-table partition nvme-tcp-export iscsi-export smb-sharing nfs-sharing media-sharing self-encrypted-and-locked self-encryption-enabled self-encryption-supported ## disk/blink **Conditions:** !smips **Type:** Command ## disk/btrfs **Conditions:** !smips **Syscap:** storage **Type:** Directory ### disk/btrfs/filesystem **Conditions:** !smips **Syscap:** storage **Type:** Directory missing-devs balancing replacing scrubbing #### disk/btrfs/filesystem/add-device **Conditions:** !smips **Type:** Command #### disk/btrfs/filesystem/balance-cancel **Conditions:** !smips **Type:** Command #### disk/btrfs/filesystem/balance-start **Conditions:** !smips **Type:** Command #### disk/btrfs/filesystem/remove-device **Conditions:** !smips **Type:** Command #### disk/btrfs/filesystem/replace-cancel **Conditions:** !smips **Type:** Command #### disk/btrfs/filesystem/replace-device **Conditions:** !smips **Type:** Command #### disk/btrfs/filesystem/reset-counters **Conditions:** !smips **Type:** Command #### disk/btrfs/filesystem/scrub-cancel **Conditions:** !smips **Type:** Command #### disk/btrfs/filesystem/scrub-start **Conditions:** !smips **Type:** Command ### disk/btrfs/subvolume **Conditions:** !smips **Syscap:** storage **Type:** Directory default snapshot read-only dead mounted ### disk/btrfs/transfer **Conditions:** !smips **Syscap:** storage **Type:** Directory ## disk/check **Conditions:** !smips **Syscap:** storage **Type:** Command ## disk/copy **Conditions:** !smips **Type:** Command ## disk/eject **Conditions:** !smips **Type:** Command ## disk/format **Conditions:** !smips **Type:** Command ## disk/monitor-traffic **Conditions:** !smips **Type:** Command ## disk/nvme-discover **Conditions:** !smips **Syscap:** storage **Type:** Command ## disk/raid-scrub **Conditions:** !smips **Syscap:** storage **Type:** Command ## disk/raid-scrub-cancel **Conditions:** !smips **Syscap:** storage **Type:** Command ## disk/repair **Conditions:** !smips **Syscap:** storage **Type:** Command ## disk/reset-counters **Conditions:** !smips **Type:** Command ## disk/scan **Conditions:** !smips **Type:** Command ## disk/settings **Conditions:** !smips **Type:** Settings Directory ## disk/smart-info **Conditions:** !smips **Syscap:** storage **Type:** Command ## disk/test **Conditions:** !smips **Type:** Command initializing running failed ## disk/trim **Conditions:** !smips **Type:** Command --- ## dude import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # dude **Package:** dude **Type:** Settings Directory ## dude/agent **Package:** dude **Type:** Directory ## dude/device **Package:** dude **Type:** Directory ## dude/device-type **Package:** dude **Type:** Directory ## dude/export-db **Package:** dude **Type:** Command ## dude/import-db **Package:** dude **Type:** Command ## dude/notification **Package:** dude **Type:** Directory ## dude/probe **Package:** dude **Type:** Directory ## dude/ros **Package:** dude **Type:** Directory ### dude/ros/address **Package:** dude **Type:** Directory ### dude/ros/arp **Package:** dude **Type:** Directory ### dude/ros/health **Package:** dude **Type:** Directory ### dude/ros/interface **Package:** dude **Type:** Directory ### dude/ros/lease **Package:** dude **Type:** Directory ### dude/ros/neighbor **Package:** dude **Type:** Directory ### dude/ros/queue **Package:** dude **Type:** Directory ### dude/ros/registration-table **Package:** dude **Type:** Directory ### dude/ros/resource **Package:** dude **Type:** Directory ### dude/ros/route **Package:** dude **Type:** Directory ### dude/ros/routerboard **Package:** dude **Type:** Directory ## dude/service **Package:** dude **Type:** Directory ## dude/settings **Package:** dude **Type:** Settings Directory ## dude/vacuum-db **Package:** dude **Type:** Command --- ## environment import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # environment **Type:** Directory --- ## File import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## file/rsync-daemon **Package:** rose-storage **Type:** Settings Directory ## file/sync **Package:** rose-storage **Type:** Directory ### file/sync/monitor **Package:** rose-storage **Type:** Command --- ## import import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # import **Type:** Command .rsc files simulate import without making any configuration changes --- ## CLI Reference The CLI reference documents RouterOS command menus and properties by console path. Use this section to look up command syntax, configuration objects, and operational commands for RouterOS features. ## Argument types - **address** — universal address parameter, rendered as `address (flags=...)`; see [address flags](#address-flags) below - **alt** — alternative type, can accept one of several different value types - **as** — autonomous system number (used in BGP routing) - **bool** — boolean value (true/false, yes/no) - **cfg** — configuration entry identifier - **composite** — combination of multiple arguments treated as a group - **date** — date and time value - **enum** — enumerator, has predefined values listed in parentheses - **expr** — expression or condition (used in routing filters and scripting) - **file** — file path or name reference - **iface_enum** — interface selection list, can usually accept an interface name, or predefined values like `all`, `none`, `dynamic`, `slave`; values listed in braces - **ipAddr** — IPv4 address - **ip6Addr** — IPv6 address - **ipPrefix** — IPv4 address with prefix length - **ip6Prefix** — IPv6 address with prefix length - **ipRange** — IPv4 address range - **macAddr** — MAC address (can specify full address or with wildcards) - **meter** — signal quality level, typically expressed in dBm - **multi** — multi-value argument, accepts multiple values from a defined set - **num** — unsigned integer, can be restricted with a range (e.g. `[3 .. 20]`, `[.. 10]`, `[4 ..]`); 32-bit range if not explicitly specified - **numericon** — numeric value displayed with unit suffix - **object** — structured list of values (e.g. a table of addresses or configuration items) - **pic** — picture/bitmap value - **range** — numeric range (e.g. a set of ports) - **remote** — reference to a remote object (e.g. a routing filter rule) - **string** — text string - **super** — composite type accepting multiple different argument types; sub-types are listed in braces, e.g. `super { bool, time }` - **switch** — on/off toggle without an explicit value argument - **time** — time duration or interval, usually in seconds, may include units like `s`, `m`, `h`, `d` - **timezone** — timezone or UTC offset value - **ubit** — bitfield with named bits, supported bit names listed in parentheses, e.g. `ubit (ip, ipv6)` - **value** — standalone value identifier (typically used as part of a composite or enum) - **varName** — variable name reference (used in scripting) Argument types can be nested, for example `super {num, time, super {bool, ip}}`. The **address** type is rendered as `address (flags=...)` where the flags define which address formats are accepted: | Flag | Meaning | |------|---------| | 4 | IPv4 address | | 6 | IPv6 address | | D | DNS name (hostname) | | i | Interface name | | / | Address with subnet mask (CIDR prefix) | | v | VRF (Virtual Routing and Forwarding instance) | | R | Route distinguisher | | S | Free-form prefix (e.g. EVPN prefix) | | \+ | Address list | | : | Port or zone specifier | | L | Link-local address | | m | multicast address | ## Grafts and Captures If parameters are grouped in captures, then old descriptions are taken from the first parameter with that name found. For example, BGP template and BGP connection uses the same capture, but BGP template is the first one so all the descriptions are taken from there and used for all graft referenced parameters in all menus. ## Headings Currently reference can have only headings that match RouterOS menus, everything else is ignored when comparing previous data. --- ## 6to4 import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/6to4 **Package:** ipv6 **Type:** Directory disabled running --- ## Bonding import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/bonding **Type:** Directory disabled running ### interface/bonding/monitor **Type:** Command ### interface/bonding/monitor-slaves **Type:** Command active partner --- ## Bridge import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/bridge **Conditions:** MSRP_ENABLE **Type:** Directory managed dynamic disabled running Specify the relay agent circuit-id suboption value of the option 82 to be added to the DHCP messages passing through the bridge. The string length is limited to 255 characters with the default value being: $(INTERFACE):$(VID). The string value can contain variables, whose names must be enclosed in parentheses and prepended by a dollar sign. Example: 'some_arbitrary_text $(VID) another_piece_of_text $(INTERFACE)'. The following variables are supported: HOSTNAME, INTERFACE, VID and BRIDGEMAC. For the compatibility with previous versions, where the remote-id value was fixed, the semicolon appearing in the default value expression is not included in the remote-id value, in the case when the vlan filtering is not enabled. Specify the relay agent remote-id suboption value of the option 82 to be added to the DHCP messages passing through the bridge. The string length is limited to 255 characters with the default value being: $(BRIDGEMAC). The string value can contain variables, whose names must be enclosed in parentheses and prepended by a dollar sign. Example: 'some_arbitrary_text $(HOSTNAME) another_piece_of_text $(BRIDGEMAC)'. The following variables are supported: HOSTNAME, INTERFACE, VID and BRIDGEMAC. Specify the DHCPv6 option 18 value to be added to the DHCPv6 messages passing through the bridge. The string length is limited to 255 characters with the default value being: $(INTERFACE):$(VID). The string value can contain variables, whose names must be enclosed in parentheses and prepended by a dollar sign. Example: 'some_arbitrary_text $(VID) another_piece_of_text $(INTERFACE)'. The following variables are supported: HOSTNAME, INTERFACE, VID and BRIDGEMAC. Specify the DHCPv6 option 37 value to be added to the DHCPv6 messages passing through the bridge. The string length is limited to 255 characters with the default value being: $(BRIDGEMAC). The string value can contain variables, whose names must be enclosed in parentheses and prepended by a dollar sign. Example: 'some_arbitrary_text $(VID) another_piece_of_text $(INTERFACE)'. The following variables are supported: HOSTNAME, INTERFACE, VID and BRIDGEMAC. ### interface/bridge/calea **Type:** Directory disabled invalid dynamic #### interface/bridge/calea/reset-counters **Type:** Command #### interface/bridge/calea/reset-counters-all **Type:** Command ### interface/bridge/filter **Type:** Directory disabled invalid dynamic #### interface/bridge/filter/reset-counters **Type:** Command #### interface/bridge/filter/reset-counters-all **Type:** Command ### interface/bridge/host **Type:** Directory disabled invalid dynamic local external aged aged-peer ### interface/bridge/mdb **Type:** Directory disabled invalid dynamic ### interface/bridge/monitor **Type:** Command ### interface/bridge/msrp **Conditions:** MSRP_ENABLE **Type:** Directory disabled dynamic #### interface/bridge/msrp/attributes **Conditions:** MSRP_ENABLE **Type:** Directory #### interface/bridge/msrp/domain **Conditions:** MSRP_ENABLE **Type:** Directory disabled dynamic ##### interface/bridge/msrp/domain/attributes **Conditions:** MSRP_ENABLE **Type:** Directory ##### interface/bridge/msrp/domain/monitor **Conditions:** MSRP_ENABLE **Type:** Command ### interface/bridge/msti **Type:** Directory disabled dynamic #### interface/bridge/msti/monitor **Type:** Command ### interface/bridge/nat **Type:** Directory disabled invalid dynamic #### interface/bridge/nat/reset-counters **Type:** Command #### interface/bridge/nat/reset-counters-all **Type:** Command ### interface/bridge/port **Type:** Directory disabled inactive dynamic hw-offload managed #### interface/bridge/port/monitor **Type:** Command #### interface/bridge/port/mst-override **Type:** Directory disabled dynamic ##### interface/bridge/port/mst-override/monitor **Type:** Command ### interface/bridge/settings **Type:** Settings Directory ### interface/bridge/vlan **Type:** Directory managed disabled dynamic #### interface/bridge/vlan/mvrp **Type:** Directory --- ## Detect Internet import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/detect-internet **Type:** Settings Directory ### interface/detect-internet/state **Type:** Directory --- ## Dot1x(Interface) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/dot1x **Conditions:** !smips **Type:** Directory ### interface/dot1x/client **Conditions:** !smips **Type:** Directory inactive disabled ### interface/dot1x/server **Conditions:** !smips **Type:** Directory inactive disabled #### interface/dot1x/server/active **Conditions:** !smips **Type:** Directory #### interface/dot1x/server/state **Conditions:** !smips **Type:** Directory --- ## Eoip import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/eoip **Type:** Directory disabled running --- ## Eoipv6 import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/eoipv6 **Package:** ipv6 **Type:** Directory disabled running --- ## Ethernet import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/ethernet **Conditions:** i386 **Type:** Directory disabled running slave ### interface/ethernet/switch **Conditions:** !smips **Syscap:** multiswitch **Type:** Directory Layer 3 hardware offloading Quality of Service hardware offloading #### interface/ethernet/switch/qos **Syscap:** crs_prestera **Type:** Directory ##### interface/ethernet/switch/qos/profile **Syscap:** crs_prestera **Type:** Directory QoS Profile name Should DSCP and PCP values be automatically mapped to the profile? ##### interface/ethernet/switch/qos/map **Syscap:** crs_prestera **Type:** Directory QoS Map name ###### interface/ethernet/switch/qos/map/vlan **Syscap:** crs_prestera **Type:** Directory Map only if DEI/CFI bit is set ###### interface/ethernet/switch/qos/map/ip **Syscap:** crs_prestera **Type:** Directory ##### interface/ethernet/switch/qos/priority-flow-control **Syscap:** !prestera-ac3 **Type:** Directory PFC Profile name Receive (and obey) PFC frames Transmit PFC frames Transmit a pause frame (XOFF) when the total size of queued packets reaches this threshold Transmit a resume frame (XON) when the total size of queued packets lowers down to this threshold ##### interface/ethernet/switch/qos/tx-manager **Syscap:** crs_prestera **Type:** Directory Tx Manager name The number of bytes (or %) exclusively reserved for the Tx Manager. The value gets split on active queues of assigned ports. ###### interface/ethernet/switch/qos/tx-manager/queue **Syscap:** crs_prestera **Type:** Directory Schedule tx either by strict priority of the traffic class or round-robin within the group Weight value for priority group Per-queue reserved buffers. The number of bytes (or % of tx-manager) exclusively reserved for the queue. Allow using the shared buffer pool when the port or queue buffers are full Weighted Random Early Detection Explicit Congestion Notification - ECN marking Actual WRED value Actual ECN value ##### interface/ethernet/switch/qos/settings **Type:** Settings Directory Maximum amount of packet buffers for multicast traffic (% of total buffer memory) Maximum amount of packet buffers for mirrored traffic (% of total buffer memory) A QoS profile to apply to mirrored packets Amount of packet buffers that are shared between ports (% of total buffer memory) The size of the lossless shared pool (% of shared buffers) A relative queue fill level to start a random tail drop or ECN marking ##### interface/ethernet/switch/qos/monitor **Type:** Command ##### interface/ethernet/switch/qos/port **Type:** Directory QoS profile to assign to ingress packets by default QoS Packet-to-Profile mapping Trust Layer 2 header (PCP) for QoS mapping Trust Layer 3 header (DSCP) for QoS mapping QoS Tx Manager for egress traffic on this port Priority Flow Control profile for ingress traffic on this port ###### interface/ethernet/switch/qos/port/reset-counters **Type:** Command #### interface/ethernet/switch/port **Type:** Directory ##### interface/ethernet/switch/port/reset-counters **Type:** Command #### interface/ethernet/switch/unicast-fdb **Type:** Directory ##### interface/ethernet/switch/unicast-fdb/flush **Type:** Command #### interface/ethernet/switch/multicast-fdb **Type:** Directory #### interface/ethernet/switch/reserved-fdb **Type:** Directory #### interface/ethernet/switch/vlan **Type:** Directory #### interface/ethernet/switch/egress-vlan-tag **Type:** Directory #### interface/ethernet/switch/ingress-vlan-translation **Type:** Directory #### interface/ethernet/switch/egress-vlan-translation **Type:** Directory #### interface/ethernet/switch/mac-based-vlan **Type:** Directory #### interface/ethernet/switch/one2one-vlan-switching **Type:** Directory #### interface/ethernet/switch/protocol-based-vlan **Type:** Directory #### interface/ethernet/switch/dscp-to-dscp **Type:** Directory #### interface/ethernet/switch/dscp-qos-map **Type:** Directory #### interface/ethernet/switch/qos-group **Type:** Directory #### interface/ethernet/switch/shaper **Type:** Directory #### interface/ethernet/switch/port-isolation **Type:** Directory #### interface/ethernet/switch/port-leakage **Type:** Directory #### interface/ethernet/switch/acl **Type:** Directory ##### interface/ethernet/switch/acl/policer **Type:** Directory #### interface/ethernet/switch/trunk **Type:** Directory #### interface/ethernet/switch/ingress-port-policer **Type:** Directory #### interface/ethernet/switch/policer-qos-map **Type:** Directory #### interface/ethernet/switch/l3hw-settings **Syscap:** crs_prestera **Type:** Settings Directory Automatically restarts L3HW in case of driver failure Hardware offloading of FastTrack connections IPv6 hardware offloading In case of a packet error (TTL, MTU, etc.), either redirect the packet to the CPU for ICMP reply (yes) or silently drop (no) Does the hardware supports FastTrack offloading? ##### interface/ethernet/switch/l3hw-settings/advanced **Syscap:** crs_prestera **Type:** Settings Directory Disable indexing if the number of routes in queue exceeds this value Re-enable indexing if the number of routes in queue drops down to this value Reset the Shortest HW Prefix and try the full route table offloading after this amount of changes in the routing table Minimum number of routes for incremental adding in partial offloading Minimum time between route processing and table indexing Maximum time between route processing and table indexing The interval between keeping alive hw-offloaded neighbors (hosts) The interval between sending ARP/ND requests to check availability of hw-offloaded neighbors Limits the amount or ARP/ND requests that can be sent at once The interval between ARP/ND request bursts The maximum retry count to offload a neighbor table in case of failure ###### interface/ethernet/switch/l3hw-settings/advanced/monitor **Type:** Command ##### interface/ethernet/switch/l3hw-settings/monitor **Type:** Command #### interface/ethernet/switch/reset-counters **Conditions:** !smips **Type:** Command #### interface/ethernet/switch/port **Type:** Directory Layer 3 Hardware Offloading. Hardware routing via this port. ##### interface/ethernet/switch/port/reset-counters **Type:** Command #### interface/ethernet/switch/port-isolation **Type:** Directory #### interface/ethernet/switch/host **Syscap:** oldswitch **Type:** Directory #### interface/ethernet/switch/vlan **Syscap:** oldswitch **Type:** Directory #### interface/ethernet/switch/rule **Type:** Directory Set new-dst-ports to an empty string to drop packets on the hardware level Assign QoS profile to the matched packets Keep the original QoS fields (PCP, DSCP) or replace them from the QoS profile? Assign VRF to the matched packets ##### interface/ethernet/switch/prbs/start-prbs **Type:** Command ##### interface/ethernet/switch/prbs/stop-prbs **Type:** Command ##### interface/ethernet/switch/prbs/reset-prbs **Type:** Command #### interface/ethernet/switch/stats **Conditions:** !smips **Type:** Settings Directory ### interface/ethernet/blink **Type:** Command ### interface/ethernet/cable-test **Type:** Command ### interface/ethernet/monitor **Conditions:** i386 **Type:** Command ### interface/ethernet/poe **Syscap:** (poe or poe-in) **Type:** Directory #### interface/ethernet/poe/monitor **Type:** Command PoE out voltage selection #### interface/ethernet/poe/power-cycle **Syscap:** poe **Type:** Command #### interface/ethernet/poe/settings **Syscap:** poesettings **Type:** Settings Directory ### interface/ethernet/reset-counters **Type:** Command ### interface/ethernet/reset-mac-address **Type:** Command --- ## Gre import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/gre **Type:** Directory disabled running --- ## Gre6 import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/gre6 **Package:** ipv6 **Type:** Directory disabled running --- ## interface import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # interface **Type:** Directory ## interface/blink **Type:** Command ## interface/monitor-traffic **Type:** Command ## interface/reset-counters **Type:** Command --- ## Ipip import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/ipip **Type:** Directory disabled running dynamic --- ## Ipipv6 import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/ipipv6 **Package:** ipv6 **Type:** Directory disabled running --- ## L2tp Client import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/l2tp-client **Package:** ppp **Type:** Directory disabled running ### interface/l2tp-client/monitor **Package:** ppp **Type:** Command --- ## L2tp Ether import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/l2tp-ether **Package:** ppp **Type:** Directory disabled dynamic running unmanaged Ignored for passive (incoming) connections (for incoming connections please use l2tp-server settings) Ignored for passive (incoming) connections (for incoming connections please use l2tp-server settings) L2TPv3 encapsulation mode (IP or UDP) L2TPv3 remote end identifier (virtual circuit ID) Ignored for passive (incoming) connections (for incoming connections please use l2tp-server settings) Ignored for passive (incoming) connections (for incoming connections please use l2tp-server settings) Enables L2TPv3 ethernet pseudowire level 2 default sublayer local IPv4 or IPv6 address (unmanaged L2TP connection) local tunnel ID (unmanaged L2TP connection) local session ID (unmanaged L2TP connection) remote tunnel ID (unmanaged L2TP connection) remote session ID (unmanaged L2TP connection) cookie hex value for received packets (8 or 16 characters or empty) (unmanaged L2TP connection) cookie hex value for sent packets (8 or 16 characters or empty) (unmanaged L2TP connection) enables/disables unmanaged (static) tunnel mode ### interface/l2tp-ether/monitor **Package:** ppp **Type:** Command --- ## L2tp Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/l2tp-server **Package:** ppp **Type:** Directory disabled dynamic running ### interface/l2tp-server/monitor **Package:** ppp **Type:** Command ### interface/l2tp-server/server **Package:** ppp **Type:** Settings Directory --- ## List import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/list **Type:** Directory builtin dynamic ### interface/list/member **Type:** Directory disabled dynamic --- ## Lte import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/lte **Conditions:** !smips **Type:** Directory disabled running inactive string to send upon modem initialization operator locking, use numeric value: mccmnc This setting is ignored if any interface is enabled in /tool/sms LTE band NR band ### interface/lte/apn **Conditions:** !smips **Type:** Directory default in LTE mode use APN provided by the network requested PDN type auto will learn MAC from first packet interface on which to advertise IPv6 prefix ### interface/lte/at-chat **Conditions:** !smips **Type:** Command sends command to modem and waits for any output before returning always wait 3s ### interface/lte/cell-monitor **Conditions:** !smips **Type:** Command ### interface/lte/esim **Conditions:** !smips **Type:** Directory active #### interface/lte/esim/activate **Conditions:** !smips **Type:** Command #### interface/lte/esim/deactivate **Conditions:** !smips **Type:** Command #### interface/lte/esim/delete **Conditions:** !smips **Type:** Command disables profile before deleting it, default: no #### interface/lte/esim/esim-id **Conditions:** !smips **Type:** Command #### interface/lte/esim/provision **Conditions:** !smips **Type:** Command Profile activation code. Example: LPA:1$server.example.io$ABCD10EFGHI5KL6M Activate newly created profile after it is provisioned (default: yes) SM-DP+ server hostname. Example: sm-dp-plus=server.example.io An activation code token. Example: matching-id=ABCD10EFGHI5KL6M An optional code supplied by the operator An optional SM-DP+ supplied by the operator #### interface/lte/esim/refresh-profile-list **Conditions:** !smips **Type:** Command #### interface/lte/esim/send-notifications **Conditions:** !smips **Type:** Command #### interface/lte/esim/set-nickname **Conditions:** !smips **Type:** Command ### interface/lte/firmware-upgrade **Conditions:** !smips **Type:** Command perform the upgrade or just check path or url for the upgrade image firmware update channel ### interface/lte/monitor **Conditions:** !smips **Type:** Command ### interface/lte/scan **Conditions:** !smips **Type:** Command current available forbidden ### interface/lte/settings **Conditions:** !smips, !i386, !mips, !powerpc **Type:** Settings Directory info polling interval in seconds in seconds ### interface/lte/show-capabilities **Conditions:** !smips **Type:** Command --- ## Macsec(Interface) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/macsec **Conditions:** !smips **Type:** Directory inactive disabled running hw-offloaded ### interface/macsec/monitor **Conditions:** !smips **Type:** Command ### interface/macsec/profile **Conditions:** !smips **Type:** Directory default --- ## Macvlan(Interface) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/macvlan **Type:** Directory disabled running Only interfaces with a MAC address are supported for macvlan In bridge mode macvlan interfaces are allowed to talk to eachother --- ## Mesh import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/mesh **Type:** Directory disabled running ### interface/mesh/fdb **Type:** Directory active root ### interface/mesh/port **Type:** Directory disabled inactive dynamic ### interface/mesh/traceroute **Type:** Command --- ## Ovpn Client import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/ovpn-client **Package:** ppp **Type:** Directory disabled running hw-crypto tls-auth tls-crypt If enabled client will not use any routes pushed by server (including def1) Send explicit disconnect notification when using UDP mode ### interface/ovpn-client/import-ovpn-configuration **Package:** ppp **Type:** Command .ovpn client configuration file Ignore certificate information in ovpn file in case these are added by user manualy ### interface/ovpn-client/monitor **Package:** ppp **Type:** Command --- ## Ovpn Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/ovpn-server **Package:** ppp **Type:** Directory disabled dynamic running hw-crypto ### interface/ovpn-server/monitor **Package:** ppp **Type:** Command ### interface/ovpn-server/server **Package:** ppp **Type:** Directory inactive disabled Encryption key re-negotiation interval (0 - disabled) Push 'redirect-gateway def1 ipv6' options to VPN clients Enable ipv6 inside ovpn tunnel Server ipv6 address Prefix length used for tunneled ipv6 #### interface/ovpn-server/server/export-client-configuration **Package:** ppp **Type:** Command Public ip address or dns name clients will use to connect to this vpn server CA certificate used by client ovpn configuration Client certificate used by client ovpn configuration Client private key used by client ovpn configuration --- ## Ppp Client import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/ppp-client **Package:** ppp **Type:** Directory disabled running ### interface/ppp-client/at-chat **Package:** ppp **Type:** Command sends command to modem and waits for any output before returning ### interface/ppp-client/firmware-upgrade **Package:** ppp **Type:** Command perform the upgrade or just check path or url for the upgrade image firmware update channel ### interface/ppp-client/info **Package:** ppp **Type:** Command ### interface/ppp-client/monitor **Package:** ppp **Type:** Command ### interface/ppp-client/scan **Package:** ppp **Type:** Command current available forbidden --- ## Ppp Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/ppp-server **Package:** ppp **Type:** Directory disabled running ### interface/ppp-server/monitor **Package:** ppp **Type:** Command --- ## Pppoe Client import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/pppoe-client **Package:** ppp **Type:** Directory disabled invalid running Hex formatted host-uniq value (optional) ### interface/pppoe-client/monitor **Package:** ppp **Type:** Command ### interface/pppoe-client/scan **Package:** ppp **Type:** Command --- ## Pppoe Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/pppoe-server **Package:** ppp **Type:** Directory disabled dynamic running ### interface/pppoe-server/monitor **Package:** ppp **Type:** Command ### interface/pppoe-server/server **Package:** ppp **Type:** Directory disabled invalid Accept PADI with empty service name if no matching pppoe service is available --- ## Pptp Client import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/pptp-client **Package:** ppp **Type:** Directory disabled running ### interface/pptp-client/monitor **Package:** ppp **Type:** Command --- ## Pptp Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/pptp-server **Package:** ppp **Type:** Directory disabled dynamic running ### interface/pptp-server/monitor **Package:** ppp **Type:** Command ### interface/pptp-server/server **Package:** ppp **Type:** Settings Directory --- ## Pwr Link import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### interface/pwr-link/pwr-line **Syscap:** pwrlink **Type:** Directory disabled running slave #### interface/pwr-link/pwr-line/blink **Type:** Command #### interface/pwr-link/pwr-line/configure **Type:** Command #### interface/pwr-link/pwr-line/join **Type:** Command #### interface/pwr-link/pwr-line/leave **Type:** Command #### interface/pwr-link/pwr-line/monitor **Type:** Command #### interface/pwr-link/pwr-line/reset-counters **Type:** Command #### interface/pwr-link/pwr-line/reset-mac-address **Type:** Command #### interface/pwr-link/pwr-line/upgrade-firmware **Type:** Command --- ## Sstp Client import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/sstp-client **Package:** ppp **Type:** Directory disabled running hw-crypto ### interface/sstp-client/monitor **Package:** ppp **Type:** Command --- ## Sstp Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/sstp-server **Package:** ppp **Type:** Directory disabled dynamic running hw-crypto ### interface/sstp-server/monitor **Package:** ppp **Type:** Command ### interface/sstp-server/server **Package:** ppp **Type:** Settings Directory --- ## Veth import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/veth **Conditions:** !smips **Syscap:** container **Type:** Directory disabled running --- ## Vlan(Interface) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/vlan **Conditions:** !smips **Type:** Directory disabled running hw-offloaded Layer 3 hardware offloading --- ## Vpls import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/vpls **Conditions:** !smips **Type:** Directory List of all VPLS interfaces. This menu also shows dynamically created BGP-based VPLS interfaces. disabled running dynamic bgp-signaled cisco-bgp-signaled Name of the interface. Layer 3 Maximum Transmission Unit. Static MAC address of the interface. Automatically generated when not set. Address Resolution Protocol. Time until an ARP entry expires. Set to `auto` to use the interface-type default value. Specifies whether to detect if an interface is running. If set to `no`, the interface will always have the `running` flag. The IP address of the remote peer (RFC 4762 Section 3.1). A unique number that identifies the VPLS tunnel. Encoding is a 2byte+4byte or 4byte+2byte number (RFC 4762 Section 3.2). Cisco-style VPLS tunnel ID (RFC 4447 FEC type 0x80). Pseudowire type (RFC 4447 Section 5.2). By default, `raw-ethernet` is used. L2MTU value advertised to a remote peer (RFC 4447 Section 5.2). Enables or disables Control Word usage (RFC 4623 Section 4). Default values for regular and Cisco-style VPLS tunnels differ. Cisco-style by default has Control Word usage disabled. Read more in the [VPLS Control Word](../../user-guides/routing-and-networking-protocols/mpls/vpls/control-word.md) article. [Bridge](../interface/bridge.md) the VPLS interface belongs to. Cost of the [bridge port](../interface/bridge.md#path-cost). When set to `none`, [bridge horizon](../interface/bridge.md#horizon) is not used. Port VLAN ID (pvid) assigned to a dynamically bridged interface. Applies only when [bridge `vlan-filtering`](../interface/bridge.md#vlan-filtering) is set to `yes`. Name of the [BGP VPLS](../routing/bgp.md#routingbgpvpls) instance used to create a dynamic VPLS interface (RFC 4761 Section 3.2). Prefix of the [BGP VPLS](../routing/bgp.md#routingbgpvpls) instance used to create a dynamic VPLS interface (RFC 4761 Section 3.2). ### interface/vpls/monitor **Conditions:** !smips **Type:** Command Command displays the current VPLS interface status. For example: ```ros [admin@10.0.11.23] /interface/vpls> monitor vpls2 remote-label: 800000 local-label: 43 remote-status: transport: 10.255.11.201/32 transport-nexthop: 10.0.11.201 imposed-labels: 800000 ``` MPLS label assigned by the remote peer for this pseudowire (RFC 4447 Section 5.1). MPLS label assigned locally for this pseudowire (RFC 4447 Section 5.1). Pseudowire status received from the remote peer via LDP status signaling (RFC 4447 Section 5.4). Group ID of the remote peer, used for LDP status withdrawal aggregation (RFC 4447 Section 5.3). Name of the transport interface. Shown when VPLS is running over a [Traffic Engineering](../../user-guides/routing-and-networking-protocols/mpls/traffic-eng.md) tunnel. Transport nexthops in use. --- ## Vrrp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/vrrp **Type:** Directory disabled invalid grp-authority grp-member running master backup failure deprecated VRRP interface-authority that controls the entire group Connection tracking data exchange between master and backup Forces address of the sender or receiver of Conntrack data Port used for Conntrack data sync --- ## Vxlan(Interface) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/vxlan **Type:** Directory disabled running hw-offloaded ### interface/vxlan/fdb **Type:** Directory ### interface/vxlan/vteps **Type:** Directory dynamic disabled hw-offloaded --- ## W60g import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/w60g **Syscap:** 60ghz **Package:** wireless-rep **Type:** Directory ### interface/w60g/align **Package:** wireless-rep **Type:** Command ### interface/w60g/monitor **Package:** wireless-rep **Type:** Command ### interface/w60g/reset-configuration **Package:** wireless-rep **Type:** Command ### interface/w60g/scan **Package:** wireless-rep **Type:** Command ### interface/w60g/station **Package:** wireless-rep **Type:** Directory #### interface/w60g/station/monitor **Package:** wireless-rep **Type:** Command --- ## Wifi import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/wifi **Package:** wireless-qca **Type:** Directory master dynamic network bound disabled inactive running ### interface/wifi/flat-snoop **Type:** Command ### interface/wifi/aaa **Package:** wireless-qca **Type:** Directory disabled ### interface/wifi/access-list **Package:** wireless-qca **Type:** Directory disabled ### interface/wifi/cap **Package:** wireless-qca **Type:** Settings Directory ### interface/wifi/capsman **Package:** wireless-qca **Type:** Settings Directory #### interface/wifi/capsman/remote-cap **Package:** wireless-qca **Type:** Directory ##### interface/wifi/capsman/remote-cap/provision **Package:** wireless-qca **Type:** Command ##### interface/wifi/capsman/remote-cap/set-identity **Package:** wireless-qca **Type:** Command ##### interface/wifi/capsman/remote-cap/upgrade **Package:** wireless-qca **Type:** Command ### interface/wifi/channel **Package:** wireless-qca **Type:** Directory disabled ### interface/wifi/configuration **Package:** wireless-qca **Type:** Directory disabled #### interface/wifi/dashboard/settings **Package:** wireless-qca **Type:** Settings Directory #### interface/wifi/dashboard/show **Package:** wireless-qca **Type:** Command #### interface/wifi/dashboard/show-clients **Package:** wireless-qca **Type:** Command active #### interface/wifi/dashboard/show-logs **Package:** wireless-qca **Type:** Command ### interface/wifi/datapath **Package:** wireless-qca **Type:** Directory disabled ### interface/wifi/devel **Package:** wireless-qca **Type:** Command #### interface/wifi/dpp-bootstrap-info/gen-qr-code **Package:** wireless-qca **Type:** Command #### interface/wifi/easymesh/bss **Package:** wireless-qca **Type:** Directory active #### interface/wifi/easymesh/dpp-trigger **Package:** wireless-qca **Type:** Command #### interface/wifi/easymesh/sta **Package:** wireless-qca **Type:** Directory #### interface/wifi/easymesh/topology **Package:** wireless-qca **Type:** Directory #### interface/wifi/easymesh/wps-push-button **Package:** wireless-qca **Type:** Command ### interface/wifi/frequency-scan **Package:** wireless-qca **Type:** Command radar primary secondary ### interface/wifi/interworking **Package:** wireless-qca **Type:** Directory disabled ### interface/wifi/liberate **Package:** wireless-qca **Type:** Command ### interface/wifi/monitor **Package:** wireless-qca **Type:** Command ### interface/wifi/network **Package:** wireless-qca **Type:** Directory managed disabled #### interface/wifi/network/radio **Package:** wireless-qca **Type:** Directory managed disabled ### interface/wifi/provisioning **Package:** wireless-qca **Type:** Directory disabled ### interface/wifi/radio **Package:** wireless-qca **Type:** Directory local #### interface/wifi/radio/provision **Package:** wireless-qca **Type:** Command #### interface/wifi/radio/reg-info **Package:** wireless-qca **Type:** Command #### interface/wifi/radio/settings **Package:** wireless-qca **Type:** Settings Directory ### interface/wifi/registration-table **Package:** wireless-qca **Type:** Directory authorized ### interface/wifi/reset-mac-address **Package:** wireless-qca **Type:** Command ### interface/wifi/roam **Package:** wireless-qca **Type:** Command ### interface/wifi/scan **Package:** wireless-qca **Type:** Command active ### interface/wifi/security **Package:** wireless-qca **Type:** Directory disabled #### interface/wifi/security/multi-passphrase **Package:** wireless-qca **Type:** Directory disabled expired ### interface/wifi/sniffer **Package:** wireless-qca **Type:** Command ### interface/wifi/spectral-scan **Package:** wireless-qca **Type:** Command ### interface/wifi/steering **Package:** wireless-qca **Type:** Directory disabled #### interface/wifi/steering/neighbor-group **Package:** wireless-qca **Type:** Directory ### interface/wifi/trigger-radar **Syscap:** dfstest **Package:** wireless-qca **Type:** Command ### interface/wifi/wps-client **Package:** wireless-qca **Type:** Command ### interface/wifi/wps-push-button **Package:** wireless-qca **Type:** Command --- ## Wireguard import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/wireguard **Type:** Directory disabled running ### interface/wireguard/peers **Type:** Directory disabled dynamic #### interface/wireguard/peers/show-client-config **Type:** Command ### interface/wireguard/wg-export **Type:** Command ### interface/wireguard/wg-import **Type:** Command --- ## Wireless import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## interface/wireless **Package:** wireless-rep **Type:** Directory ### interface/wireless/access-list **Package:** wireless-rep **Type:** Directory ### interface/wireless/align **Package:** wireless-rep **Type:** Settings Directory #### interface/wireless/align/monitor **Package:** wireless-rep **Type:** Command #### interface/wireless/align/test-audio **Package:** wireless-rep **Type:** Command ### interface/wireless/cap **Package:** wireless-rep **Type:** Settings Directory ### interface/wireless/channels **Package:** wireless-rep **Type:** Directory ### interface/wireless/connect-list **Package:** wireless-rep **Type:** Directory ### interface/wireless/frequency-monitor **Package:** wireless-rep **Type:** Command ### interface/wireless/info **Package:** wireless-rep **Type:** Directory #### interface/wireless/info/allowed-channels **Package:** wireless-rep **Type:** Command #### interface/wireless/info/country-info **Package:** wireless-rep **Type:** Command #### interface/wireless/info/country-list **Package:** wireless-rep **Type:** Command #### interface/wireless/info/default-scan-list **Package:** wireless-rep **Type:** Command #### interface/wireless/info/hw-info **Package:** wireless-rep **Type:** Command #### interface/wireless/info/scan-list **Package:** wireless-rep **Type:** Command ### interface/wireless/interworking-profiles **Package:** wireless-rep **Type:** Directory ### interface/wireless/manual-tx-power-table **Package:** wireless-rep **Type:** Directory ### interface/wireless/monitor **Package:** wireless-rep **Type:** Command ### interface/wireless/nstreme **Package:** wireless-rep **Type:** Directory ### interface/wireless/nstreme-dual **Package:** wireless-rep **Type:** Directory #### interface/wireless/nstreme-dual/monitor **Package:** wireless-rep **Type:** Command #### interface/wireless/nstreme-dual/reset-counters **Package:** wireless-rep **Type:** Command ### interface/wireless/registration-table **Package:** wireless-rep **Type:** Directory #### interface/wireless/registration-table/reset-counters **Package:** wireless-rep **Type:** Command ### interface/wireless/reset-configuration **Package:** wireless-rep **Type:** Command ### interface/wireless/reset-mac-address **Package:** wireless-rep **Type:** Command ### interface/wireless/scan **Package:** wireless-rep **Type:** Command ### interface/wireless/security-profiles **Package:** wireless-rep **Type:** Directory ### interface/wireless/setup-repeater **Package:** wireless-rep **Type:** Command ### interface/wireless/sniffer **Package:** wireless-rep **Type:** Settings Directory #### interface/wireless/sniffer/packet **Package:** wireless-rep **Type:** Directory #### interface/wireless/sniffer/save **Package:** wireless-rep **Type:** Command #### interface/wireless/sniffer/sniff **Package:** wireless-rep **Type:** Command ### interface/wireless/snooper **Package:** wireless-rep **Type:** Settings Directory #### interface/wireless/snooper/flat-snoop **Package:** wireless-rep **Type:** Command ### interface/wireless/spectral-scan **Package:** wireless-rep **Type:** Command ### interface/wireless/wds **Package:** wireless-rep **Type:** Directory #### interface/wireless/wds/monitor **Package:** wireless-rep **Type:** Command ### interface/wireless/wps-client **Package:** wireless-rep **Type:** Command ### interface/wireless/wps-push-button **Package:** wireless-rep **Type:** Command --- ## Iot import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## iot/bluetooth **Package:** iot **Type:** Directory ### iot/bluetooth/advertisers **Package:** iot **Type:** Directory Address type used in AdvA field #### iot/bluetooth/advertisers/ad-structures **Package:** iot **Type:** Directory ### iot/bluetooth/connections **Package:** iot **Type:** Directory #### iot/bluetooth/connections/async-data **Package:** iot **Type:** Directory ##### iot/bluetooth/connections/async-data/clear **Package:** iot **Type:** Command #### iot/bluetooth/connections/characteristics **Package:** iot **Type:** Directory #### iot/bluetooth/connections/connect **Package:** iot **Type:** Command #### iot/bluetooth/connections/disconnect **Package:** iot **Type:** Command #### iot/bluetooth/connections/read **Package:** iot **Type:** Command #### iot/bluetooth/connections/subscribe **Package:** iot **Type:** Command #### iot/bluetooth/connections/unsubscribe **Package:** iot **Type:** Command #### iot/bluetooth/connections/write **Package:** iot **Type:** Command #### iot/bluetooth/connections/write-no-resp **Package:** iot **Type:** Command ### iot/bluetooth/decode-ad **Package:** iot **Type:** Command ### iot/bluetooth/peripheral-devices **Package:** iot **Type:** Directory Advertisement data in hex format ### iot/bluetooth/reset-counters **Package:** iot **Type:** Command ### iot/bluetooth/scanners **Package:** iot **Type:** Directory Address type used in scan requests Discard duplicate advertisements from the same advertiser #### iot/bluetooth/scanners/advertisements **Package:** iot **Type:** Directory Milliseconds since Unix Epoch Advertiser Bluetooth address Signal strength Advertisement data length Advertisement data in hex format Advertisement primary PHY Advertisement secondary PHY Advertisement legacy compatibility Comment of the matching whitelist filter ##### iot/bluetooth/scanners/advertisements/clear **Package:** iot **Type:** Command ### iot/bluetooth/whitelist **Package:** iot **Type:** Directory ## iot/gpio **Syscap:** gpio **Package:** iot **Type:** Directory ### iot/gpio/analog **Package:** iot **Type:** Directory ### iot/gpio/digital **Package:** iot **Type:** Directory ## iot/lora **Package:** iot **Type:** Directory ### iot/lora/channels **Package:** iot **Type:** Directory ### iot/lora/joineui **Package:** iot **Type:** Directory ### iot/lora/netid **Package:** iot **Type:** Directory ### iot/lora/radios **Package:** iot **Type:** Directory ### iot/lora/reset-devices **Package:** iot **Type:** Command ### iot/lora/send **Package:** iot **Type:** Command device id TX packet payload RF power in dBm Radio TX frequency in MHz (e.g.868500000) LoRa bandwidth in khz [125, 250, 500] Spread Factor modulation type preamble length invert polarity ### iot/lora/servers **Package:** iot **Type:** Directory #### iot/lora/servers/reset-servers **Package:** iot **Type:** Command ### iot/lora/traffic **Package:** iot **Type:** Directory #### iot/lora/traffic/clear **Package:** iot **Type:** Command #### iot/lora/traffic/options **Package:** iot **Type:** Settings Directory log packets with CRC errors limit packets in log ## iot/modbus **Package:** iot **Type:** Settings Directory ### iot/modbus/read-holding-registers **Package:** iot **Type:** Command ### iot/modbus/security-rules **Package:** iot **Type:** Directory ### iot/modbus/transceive **Package:** iot **Type:** Command ## iot/mqtt **Package:** iot **Type:** Settings Directory ### iot/mqtt/brokers **Package:** iot **Type:** Directory ### iot/mqtt/connect **Package:** iot **Type:** Command ### iot/mqtt/disconnect **Package:** iot **Type:** Command ### iot/mqtt/publish **Package:** iot **Type:** Command ### iot/mqtt/subscribe **Package:** iot **Type:** Command ### iot/mqtt/subscriptions **Package:** iot **Type:** Directory #### iot/mqtt/subscriptions/monitor-data **Package:** iot **Type:** Command #### iot/mqtt/subscriptions/recv **Package:** iot **Type:** Directory ##### iot/mqtt/subscriptions/recv/clear **Package:** iot **Type:** Command ### iot/mqtt/unsubscribe **Package:** iot **Type:** Command ## iot/wiliot **Package:** iot **Type:** Settings Directory Used MQTT server supported Wiliot features ### iot/wiliot/bluetooth-traffic **Package:** iot **Type:** Directory Advertiser Bluetooth address Signal strength Payload #### iot/wiliot/bluetooth-traffic/clear **Package:** iot **Type:** Command ### iot/wiliot/clear **Package:** iot **Type:** Command ### iot/wiliot/disable **Package:** iot **Type:** Command ### iot/wiliot/enable **Package:** iot **Type:** Command ### iot/wiliot/mqtt-traffic **Package:** iot **Type:** Directory #### iot/wiliot/mqtt-traffic/clear **Package:** iot **Type:** Command ### iot/wiliot/options **Package:** iot **Type:** Settings Directory handicap for refreshing token mqtt log packet limit ### iot/wiliot/servers **Package:** iot **Type:** Directory #### iot/wiliot/servers/defaults **Package:** iot **Type:** Command --- ## Address import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/address **Type:** Directory disabled invalid dynamic Whether address belongs to an interface which is a slave port to some other master interface. Network address, that is calculated from address parameter using address itself and the netmask. Specifies the interface on which the IPv4 address is configured. You can select it from the pool of interfaces available on the router. Actual interface on which address is set up. For example, if address was configured on ethernet interface and ethernet interface was added to bridge, then actual interface is bridge not ethernet. Indicates which VRF this IP address is associated with. --- ## Arp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/arp **Type:** Directory disabled invalid dhcp dynamic published complete --- ## Cloud import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/cloud **Type:** Settings Directory ### ip/cloud/advanced **Type:** Settings Directory #### ip/cloud/app/update **Type:** Command ### ip/cloud/back-to-home-file **Syscap:** cloud-vpn **Type:** Directory disabled invalid dynamic #### ip/cloud/back-to-home-file/settings **Type:** Settings Directory ### ip/cloud/back-to-home-user **Syscap:** cloud-vpn **Type:** Directory disabled active #### ip/cloud/back-to-home-user/show-client-config **Type:** Command ### ip/cloud/force-update **Type:** Command --- ## Dhcp Client import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/dhcp-client **Package:** dhcp **Type:** Directory disabled invalid dynamic Priority of outgoing packets; applicable for VLAN interface only DSCP of outgoing packets Controls BROADCAST flag of DHCPDISCOVER and DHCPREQUEST (during requesting and rebinding only) messages ### ip/dhcp-client/option **Package:** dhcp **Type:** Directory default ### ip/dhcp-client/release **Package:** dhcp **Type:** Command ### ip/dhcp-client/renew **Package:** dhcp **Type:** Command --- ## Dhcp Relay import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/dhcp-relay **Package:** dhcp **Type:** Directory disabled invalid ### ip/dhcp-relay/monitor **Package:** dhcp **Type:** Command ### ip/dhcp-relay/reset-counters **Package:** dhcp **Type:** Command --- ## Dhcp Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/dhcp-server **Package:** dhcp **Type:** Directory dynamic disabled invalid Used only if add-dns-entries=yes. If non-empty, appends suffix to DNS entry and adds Option 15 (Domain Name) to responses. maximum leases one client MAC can get use ARP and ICMP to test for IP conflict before issuing lease Pass additional Option 82 Suboptions to RADIUS server as described in RFC 4679 and The Broadband Forum TR-101 ### ip/dhcp-server/alert **Package:** dhcp **Type:** Directory disabled invalid #### ip/dhcp-server/alert/reset-alert **Package:** dhcp **Type:** Command ### ip/dhcp-server/config **Package:** dhcp **Type:** Settings Directory ### ip/dhcp-server/lease **Package:** dhcp **Type:** Directory disabled radius dynamic blocked Routes that appear on the server when the client is connected If non-empty, use it to match lease by Option 82 even if MAC or client-id differ If non-empty, use it to match lease by Option 82 even if MAC or client-id differ DHCP option 60 from last received DHCP request #### ip/dhcp-server/lease/check-status **Package:** dhcp **Type:** Command #### ip/dhcp-server/lease/make-static **Package:** dhcp **Type:** Command #### ip/dhcp-server/lease/send-reconfigure **Package:** dhcp **Type:** Command ### ip/dhcp-server/matcher **Package:** dhcp **Type:** Directory disabled global or single server pool used for this entry contents of option to match as string or hex with 0x prefix ### ip/dhcp-server/network **Package:** dhcp **Type:** Directory dynamic no servers will be sent to client no servers will be sent to client siaddr for next bootstrap step ### ip/dhcp-server/option **Package:** dhcp **Type:** Directory 0x - exact hex value, '' - string or IP address value always include this option in reply #### ip/dhcp-server/option/sets **Package:** dhcp **Type:** Directory ### ip/dhcp-server/setup **Package:** dhcp **Type:** Command --- ## Dns import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/dns **Type:** Settings Directory ### ip/dns/adlist **Type:** Directory disabled #### ip/dns/adlist/pause **Type:** Command #### ip/dns/adlist/reload **Type:** Command ### ip/dns/cache **Type:** Directory static #### ip/dns/cache/all **Type:** Directory static negative #### ip/dns/cache/flush **Type:** Command ### ip/dns/forwarders **Type:** Directory disabled ### ip/dns/static **Type:** Directory dynamic disabled --- ## Address List import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/firewall/address-list **Type:** Directory Firewall address lists allow a user to create lists of IP addresses grouped together under a common name. Firewall filter, mangle, and NAT facilities can then use those address lists to match packets against them. The address list records can also be updated dynamically via the `action=add-src-to-address-list` or `action=add-dst-to-address-list` items found in NAT, Mangle, and Filter facilities. Firewall rules with action `add-src-to-address-list` or `add-dst-to-address-list` work in passthrough mode, which means that the matched packets will be passed to the next firewall rules. disabled dynamic Name of the address list where the IP address will be added. A single IP address or range of IPs to add to the address list, or a DNS name. You can input, for example, `192.168.0.0-192.168.1.255` and it will auto-modify the typed entry to 192.168.0.0/23 on saving. IP-IP ranges are supported only for IPv4 addresses. Time after which the address will be removed from the address list. If the timeout is not specified, the address will be stored in the address list permanently otherwise the address will be stored in RAM and will be removed after a system's reboot. Whether the entry is dynamically created. The time when the entry was created. --- ## Calea import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/firewall/calea **Type:** Directory Filter configuration for calea rules. Specifies to which chain the rule will be added. If the input does not match the name of an already defined chain, a new chain will be created. Action to take if a packet is matched by the rule: - `sniff` - sniff the packet. - `sniff-pc` - sniff the packet and send it to the specified Packet Capturer target. IP address to send the sniffed packet to. Port to send the sniffed packet to. ID of the sniffing session. Matches HTTPS traffic based on TLS SNI hostname. Accepts GLOB syntax for wildcard matching. The matcher will not be able to match the hostname if the TLS handshake frame is fragmented into multiple TCP segments. Matches connections per address or address block after a given value is reached. You should use this together with `connection-state=new` and/or with `tcp-flags=syn` because the matcher is very resource-intensive. Layer7 filter name defined in the layer7 protocol menu. Matches the routing realm. IPv4 only. Matches the particular IP protocol specified by protocol name or number. Matches packets whose source is equal to the specified IP or falls into the specified IP range. Matches packets whose destination is equal to the specified IP or falls into the specified IP range. Matches fragmented packets. The first (starting) fragment does not count. If connection tracking is enabled there will be no fragments as the system automatically assembles every packet. IPv4 only. Attempts to detect TCP and UDP scans. Parameters are in the following format: `WeightThreshold, DelayThreshold, LowPortWeight, HighPortWeight`. - `WeightThreshold` - total weight of the latest TCP/UDP packets with different destination ports coming from the same host to be treated as port scan sequence. - `DelayThreshold` - delay for the packets with different destination ports coming from the same host to be treated as possible port scan subsequence. - `LowPortWeight` - the weight of the packets with privileged destination port (<1024). - `HighPortWeight` - the weight of the packets with a non-privileged destination port. IPv4 only. Matches IPv4 header options. - `any` - matches packets with at least one of the IPv4 options. - `loose-source-routing` - matches packets with a loose source routing option. - `no-record-route` - matches packets with no record route option. - `no-router-alert` - matches packets with no router alert option. - `no-source-routing` - matches packets with no source routing option. - `no-timestamp` - matches packets with no timestamp option. - `record-route` - matches packets with record route option. - `router-alert` - matches packets with router alert option. - `strict-source-routing` - matches packets with a strict source routing option. - `timestamp` - matches packets with a timestamp. IPv4 only. Matches the source address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in the subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the destination address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the destination address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in a subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the source address of a packet against a user-defined address list. Supports only one list. Matches the destination address of a packet against a user-defined address list. Supports only one list. Matches packets received from HotSpot clients against various HotSpot matchers. - `auth` - matches authenticated HotSpot client packets. - `from-client` - matches packets coming from the HotSpot client. - `http` - matches HTTP requests sent to the HotSpot server. - `local-dst` - matches packets destined to the HotSpot server. - `to-client` - matches packets sent to the HotSpot client. IPv4 only. Name of the address list to be used. Applicable if the action is `add-dst-to-address-list` or `add-src-to-address-list`. Time interval after which the address will be removed from the address list specified by the `address-list` parameter. Used in conjunction with `add-dst-to-address-list` or `add-src-to-address-list` actions. - `none-dynamic` (`00:00:00`) will leave the address in the address list till reboot. - `none-static` will leave the address in the address list forever and will be included in the configuration export/backup. Matches the packet TTL value. IPv4 only. Matches packets marked by the mangle facility with a particular connection mark. If `no-mark` is set, the rule will match any unmarked connection. Matches packets from related connections based on information from their connection tracking helpers. A relevant connection helper must be enabled under `/ip/firewall/service-port`. Matches packets only if a given amount of bytes has been transferred through the particular connection. 0 means infinity, for example `connection-bytes=2000000-0` means that the rule matches if more than 2MB has been transferred through the relevant connection. Allows capturing traffic based on the present speed of the connection. Matches packets marked by the mangle facility with a particular routing mark. Interface the packet has entered the router. Interface the packet is leaving the router. Set of interfaces defined in interface list. Works the same as `in-interface`. Set of interfaces defined in interface list. Works the same as `out-interface`. Actual interface the packet has entered the router if the incoming interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Actual interface the packet leaves the router if the outgoing interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Set of interfaces defined in interface list. Works the same as `in-bridge-port`. Set of interfaces defined in interface list. Works the same as `out-bridge-port`. Matches packets marked by the mangle facility with a particular packet mark. If `no-mark` is set, the rule will match any unmarked packet. List of source ports and ranges of source ports. Applicable only if the protocol is TCP or UDP. List of destination port numbers or port number ranges. Matches if any (source or destination) port matches the specified list of ports or port ranges. Applicable only if `protocol` is TCP or UDP. Matches ICMP type:code fields. Matches the source MAC address of the packet. Matches packets that contain the specified text. Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP, or MPLS EXP bit. Matches the packet's priority after a new priority has been set. Priority may be derived from VLAN, WMM, DSCP, MPLS EXP bit, or from the priority set by using the set-priority action. Matches the DSCP IP header field. Matches packets up to a limited rate (packet rate or bit rate). A rule with this matcher will match until this limit is reached. Parameters are written in the following format: `rate[/time],burst:mode`. - `rate` - packet or bit count per time interval to match. - `time` - specifies the time interval in which the packet or bit rate cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets or bits to match: this number gets recharged every 10ms so burst should be at least 1/100 of a rate per second. - `mode` - packet or bit mode. Matches packets until a given rate is exceeded. Rate is defined as packets per time interval. As opposed to the `limit` matcher, every flow has its own limit. Flow is defined by a mode parameter. Parameters are written in the following format: `rate[/time],burst,mode[/expire]`. - `rate` - packet count per time interval per-flow to match. - `time` - specifies the time interval in which the packet count rate per flow cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets per flow to match: this number gets recharged by one every time/rate, up to this number. - `mode` - specifies what unique fields define flow (src-address, dst-address, src-and-dst-address, dst-address-and-port, addresses-and-dst-port). - `expire` - specifies interval after which flow with no packets will be allowed to be deleted (optional). Creates a filter based on the packets' arrival time and date or, for locally generated packets, departure time and date. The matcher takes into account the time and timezone configured on the router. Matches packets randomly with a given probability. Matches every nth packet: `nth=2,1` will match every first packet of 2, hence, 50% of all the traffic matched by the rule. Matches the TCP MSS value of an IP packet. PCC matcher allows dividing traffic into equal streams with the ability to keep packets with a specific set of options in one particular stream. Matches packets of specified size or size range in bytes. Add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. Allows logging of packets even if the action is not `log`, useful for debugging the firewall. Adds the specified text at the beginning of every log message. Applicable if `action=log` or `log=yes` is configured. Matches the policy used by IPsec. Value is written in the following format: `direction, policy`. - `in` - valid in the PREROUTING, INPUT, and FORWARD chains. - `out` - valid in the POSTROUTING, OUTPUT, and FORWARD chains. - `ipsec` - matches if the packet is subject to IPsec processing. - `none` - matches packets that are not subject to IPsec processing. #### ip/firewall/calea/reset-counters **Type:** Command #### ip/firewall/calea/reset-counters-all **Type:** Command --- ## Tracking import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- #### ip/firewall/connection/tracking **Type:** Settings Directory --- ## Connection import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/firewall/connection **Type:** Directory expected seen-reply assured confirmed dying fasttrack hw-offload srcnat dstnat uses-helper Connection protocol. Source IP address of the connection. Source port of the connection. Destination IP address of the connection. Destination port of the connection. Reply source IP address. Reply source port. Reply destination IP address. Reply destination port. TCP connection state. ICMP type. ICMP code. ICMP ID. GRE protocol. GRE version. GRE key. Connection type. Connection timeout. Connection mark. Number of original direction packets. Number of original direction bytes. Number of original direction fasttrack packets. Number of original direction fasttrack bytes. Number of reply direction packets. Number of reply direction bytes. Number of reply direction fasttrack packets. Number of reply direction fasttrack bytes. Original direction rate. Reply direction rate. --- ## Filter import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/firewall/filter **Type:** Directory Specifies to which chain the rule will be added. If the input does not match the name of an already defined chain, a new chain will be created. Action to take if a packet is matched by the rule: - `accept` - accept the packet. A packet is not passed to the next firewall rule. - `add-dst-to-address-list` - add the destination address to the address list specified by the `address-list` parameter. - `add-src-to-address-list` - add the source address to the address list specified by the `address-list` parameter. - `jump` - jump to the user-defined chain specified by the value of the `jump-target` parameter. - `log` - add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. - `passthrough` - if a packet is matched by the rule, increase the counter and go to the next rule (useful for statistics). - `return` - passes control back to the chain from where the jump took place. - `drop` - drop the packet. - `reject` - reject the packet and send an ICMP response. - `tarpit` - capture and hold the connection open. - `fasttrack-connection` - fasttrack the connection. Name of the target chain to jump to. Applicable only if `action=jump`. Specifies the [ICMP error](https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml) to be sent back if the packet is rejected. Applicable if `action=reject`. - `icmp-network-unreachable` - sends an ICMP port unreachable message. ICMP type 3, code 0 - `icmp-host-unreachable` - sends an ICMP port unreachable message. ICMP type 3, code 1 - `icmp-protocol-unreachable` - sends an ICMP port unreachable message. ICMP type 3, code 2 - `icmp-port-unreachable` - sends an ICMP port unreachable message. ICMP type 3, code 3 - `icmp-net-prohibited` - sends an ICMP address prohibited message. ICMP type 3, code 9 - `icmp-host-prohibited` - sends an ICMP address prohibited message. ICMP type 3, code 10 - `tcp-reset` - sends a TCP segment with the RST flag set. - `icmp-admin-prohibited` - sends an ICMP address prohibited message. ICMP type 3, code 13 Enables or disables [FastTrack hardware offloading](../../../bridging-and-switching/l3-hardware-offloading.md#offloading-fasttrack-connections). Supported only on [switches with FastTrack offloading](../../../bridging-and-switching/l3-hardware-offloading.md#ccr2xxx-crs3xx-crs5xx-switchdx8000anddx4000series) and when `action=fasttrack-connection` is set. Matches the specified TCP flags: - `ack` - acknowledging data. - `cwr` - congestion window reduced. - `ece` - ECN-echo flag (explicit congestion notification). - `fin` - close connection. - `psh` - push function. - `rst` - reset connection. - `syn` - new connection. - `urg` - urgent data. Matches some unencrypted P2P protocols. Deprecated since mostly everything is encrypted and requires deep packet inspection to identify. IPv4 only. Interprets the connection tracking analytics data for a particular packet: - `established` - a packet that belongs to an existing connection. - `invalid` - a packet that does not have a determined state in connection tracking (usually severe out-of-order packets, packets with wrong sequence/ack number, or in case of resource over usage on the router). An invalid packet will not participate in NAT (as only connection-state=new packets do), and will still contain the original source IP address when routed. You should drop all `connection-state=invalid` packets in the firewall filter forward and input chains. - `new` - the packet has started a new connection or is otherwise associated with a connection that has not seen packets in both directions. - `related` - a packet that is related to, but not part of an existing connection, such as ICMP errors or a packet that begins an FTP data connection. - `untracked` - a packet that was set to bypass connection tracking in firewall RAW tables. Matches connections that are source-natted, destination-natted, or both. The `connection-state=related` connections' connection-nat-state is determined by the direction of the first packet, and if connection tracking needs to use dst-nat to deliver this connection to the same hosts as the main connection, it will be in connection-nat-state=dstnat even if there are no dst-nat rules at all. `ein-snat` and `ein-dnat` are source and destination nated connections when endpoint-independent NAT is used. Matches HTTPS traffic based on TLS SNI hostname. Accepts GLOB syntax for wildcard matching. The matcher will not be able to match the hostname if the TLS handshake frame is fragmented into multiple TCP segments. Matches connections per address or address block after a given value is reached. You should use this together with `connection-state=new` and/or with `tcp-flags=syn` because the matcher is very resource-intensive. Layer7 filter name defined in the layer7 protocol menu. Matches the routing realm. IPv4 only. Matches the particular IP protocol specified by protocol name or number. Matches packets whose source is equal to the specified IP or falls into the specified IP range. Matches packets whose destination is equal to the specified IP or falls into the specified IP range. Matches fragmented packets. The first (starting) fragment does not count. If connection tracking is enabled there will be no fragments as the system automatically assembles every packet. IPv4 only. Attempts to detect TCP and UDP scans. Parameters are in the following format: `WeightThreshold, DelayThreshold, LowPortWeight, HighPortWeight`. - `WeightThreshold` - total weight of the latest TCP/UDP packets with different destination ports coming from the same host to be treated as port scan sequence. - `DelayThreshold` - delay for the packets with different destination ports coming from the same host to be treated as possible port scan subsequence. - `LowPortWeight` - the weight of the packets with privileged destination port (<1024). - `HighPortWeight` - the weight of the packets with a non-privileged destination port. IPv4 only. Matches IPv4 header options. - `any` - matches packets with at least one of the IPv4 options. - `loose-source-routing` - matches packets with a loose source routing option. - `no-record-route` - matches packets with no record route option. - `no-router-alert` - matches packets with no router alert option. - `no-source-routing` - matches packets with no source routing option. - `no-timestamp` - matches packets with no timestamp option. - `record-route` - matches packets with record route option. - `router-alert` - matches packets with router alert option. - `strict-source-routing` - matches packets with a strict source routing option. - `timestamp` - matches packets with a timestamp. IPv4 only. Matches the source address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in the subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the destination address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the destination address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in a subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the source address of a packet against a user-defined address list. Supports only one list. Matches the destination address of a packet against a user-defined address list. Supports only one list. Matches packets received from HotSpot clients against various HotSpot matchers. - `auth` - matches authenticated HotSpot client packets. - `from-client` - matches packets coming from the HotSpot client. - `http` - matches HTTP requests sent to the HotSpot server. - `local-dst` - matches packets destined to the HotSpot server. - `to-client` - matches packets sent to the HotSpot client. IPv4 only. Name of the address list to be used. Applicable if the action is `add-dst-to-address-list` or `add-src-to-address-list`. Time interval after which the address will be removed from the address list specified by the `address-list` parameter. Used in conjunction with `add-dst-to-address-list` or `add-src-to-address-list` actions. - `none-dynamic` (`00:00:00`) will leave the address in the address list till reboot. - `none-static` will leave the address in the address list forever and will be included in the configuration export/backup. Matches the packet TTL value. IPv4 only. Matches packets marked by the mangle facility with a particular connection mark. If `no-mark` is set, the rule will match any unmarked connection. Matches packets from related connections based on information from their connection tracking helpers. A relevant connection helper must be enabled under `/ip/firewall/service-port`. Matches packets only if a given amount of bytes has been transferred through the particular connection. 0 means infinity, for example `connection-bytes=2000000-0` means that the rule matches if more than 2MB has been transferred through the relevant connection. Allows capturing traffic based on the present speed of the connection. Matches packets marked by the mangle facility with a particular routing mark. Interface the packet has entered the router. Interface the packet is leaving the router. Set of interfaces defined in interface list. Works the same as `in-interface`. Set of interfaces defined in interface list. Works the same as `out-interface`. Actual interface the packet has entered the router if the incoming interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Actual interface the packet leaves the router if the outgoing interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Set of interfaces defined in interface list. Works the same as `in-bridge-port`. Set of interfaces defined in interface list. Works the same as `out-bridge-port`. Matches packets marked by the mangle facility with a particular packet mark. If `no-mark` is set, the rule will match any unmarked packet. List of source ports and ranges of source ports. Applicable only if the protocol is TCP or UDP. List of destination port numbers or port number ranges. Matches if any (source or destination) port matches the specified list of ports or port ranges. Applicable only if `protocol` is TCP or UDP. Matches ICMP type:code fields. Matches the source MAC address of the packet. Matches packets that contain the specified text. Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP, or MPLS EXP bit. Matches the packet's priority after a new priority has been set. Priority may be derived from VLAN, WMM, DSCP, MPLS EXP bit, or from the priority set by using the set-priority action. Matches the DSCP IP header field. Matches packets up to a limited rate (packet rate or bit rate). A rule with this matcher will match until this limit is reached. Parameters are written in the following format: `rate[/time],burst:mode`. - `rate` - packet or bit count per time interval to match. - `time` - specifies the time interval in which the packet or bit rate cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets or bits to match: this number gets recharged every 10ms so burst should be at least 1/100 of a rate per second. - `mode` - packet or bit mode. Matches packets until a given rate is exceeded. Rate is defined as packets per time interval. As opposed to the `limit` matcher, every flow has its own limit. Flow is defined by a mode parameter. Parameters are written in the following format: `rate[/time],burst,mode[/expire]`. - `rate` - packet count per time interval per-flow to match. - `time` - specifies the time interval in which the packet count rate per flow cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets per flow to match: this number gets recharged by one every time/rate, up to this number. - `mode` - specifies what unique fields define flow (src-address, dst-address, src-and-dst-address, dst-address-and-port, addresses-and-dst-port). - `expire` - specifies interval after which flow with no packets will be allowed to be deleted (optional). Creates a filter based on the packets' arrival time and date or, for locally generated packets, departure time and date. The matcher takes into account the time and timezone configured on the router. Matches packets randomly with a given probability. Matches every nth packet: `nth=2,1` will match every first packet of 2, hence, 50% of all the traffic matched by the rule. Matches the TCP MSS value of an IP packet. PCC matcher allows dividing traffic into equal streams with the ability to keep packets with a specific set of options in one particular stream. Matches packets of specified size or size range in bytes. Add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. Allows logging of packets even if the action is not `log`, useful for debugging the firewall. Adds the specified text at the beginning of every log message. Applicable if `action=log` or `log=yes` is configured. Matches the policy used by IPsec. Value is written in the following format: `direction, policy`. - `in` - valid in the PREROUTING, INPUT, and FORWARD chains. - `out` - valid in the POSTROUTING, OUTPUT, and FORWARD chains. - `ipsec` - matches if the packet is subject to IPsec processing. - `none` - matches packets that are not subject to IPsec processing. #### ip/firewall/filter/reset-counters **Type:** Command #### ip/firewall/filter/reset-counters-all **Type:** Command --- ## Layer7 Protocol import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/firewall/layer7-protocol **Type:** Directory Descriptive name of l7 pattern used by configuration in firewall rules. A POSIX compliant regular expression is used to match a pattern. --- ## Mangle import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/firewall/mangle **Type:** Directory Specifies to which chain the rule will be added. If the input does not match the name of an already defined chain, a new chain will be created. Action to take if a packet is matched by the rule: - `accept` - accept the packet. A packet is not passed to the next firewall rule. - `add-dst-to-address-list` - add the destination address to the address list specified by the `address-list` parameter. - `add-src-to-address-list` - add the source address to the address list specified by the `address-list` parameter. - `jump` - jump to the user-defined chain specified by the value of the `jump-target` parameter. - `log` - add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. - `passthrough` - if a packet is matched by the rule, increase the counter and go to the next rule (useful for statistics). - `return` - passes control back to the chain from where the jump took place. - `sniff-tzsp` - send a packet to a remote TZSP compatible system (such as Wireshark). Set remote target with `sniff-target` and `sniff-target-port` parameters (Wireshark recommends port 37008). After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. - `sniff-pc` - send a packet to a remote RouterOS CALEA server. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. - `drop` - silently drop the packet. - `mark-packet` - mark the packet with the specified `new-packet-mark`. - `mark-connection` - mark the connection with the specified `new-connection-mark`. - `change-mss` - change the Maximum Segment Size field value of the packet to a value specified by the `new-mss` parameter. - `change-dscp` - change the Differentiated Services Code Point (DSCP) field value specified by the `new-dscp` parameter. - `change-ttl` - change the Time to Live field value of the packet to a value specified by the `new-ttl` parameter. - `mark-routing` - place a mark specified by the `new-routing-mark` parameter on a packet. This kind of mark is used for policy routing purposes only. Do not apply any other routing marks besides `main` for packets processed by FastTrack, since FastTrack can only work in the main routing table. - `set-priority` - set the priority of the packet. - `clear-df` - clear the Don't Fragment flag. - `fasttrack-connection` - mark the connection for FastTrack. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. - `route` - forces packets to a gateway IP specified by 'route-dst' parameter, by ignoring normal routing decisions (prerouting chain only). - `strip-ipv4-options` - strip IPv4 option fields from IP header. The action does not actually remove IPv4 options but rather replaces all option octets with NOP. Further matcher with `ipv4-options=any` will still match the packet. Name of the target chain to jump to. Applicable only if `action=jump`. Sets the new packet mark value. Sets the new connection mark value. Sets a new `routing-mark` value. In RouterOS v7 routing mark must be created beforehand as a new [Routing table](../../../user-guides/routing-and-networking-protocols/policy-routing.md) Sets a new MSS for a packet. **Important:** Clamp-to-pmtu feature sets the DF bit in the IP header to dynamically discover the PMTU of a path. The host sends all datagrams on that path with the DF bit set until it receives ICMP Destination Unreachable messages with a code meaning "fragmentation needed and DF set". Upon receipt of such a message, the source host reduces its assumed PMTU for the path. Sets the new DSCP value. Sets a new priority for a packet. This can be the VLAN, WMM, DSCP or MPLS EXP priority [Read more](../../../bridging-and-switching/user-guides/wmm-and-vlan-priority.md). This property can also be used to set an internal priority. Sets the new TTL value. Whether to let the packet pass through to the next rule. Matches the specified TCP flags: - `ack` - acknowledging data. - `cwr` - congestion window reduced. - `ece` - ECN-echo flag (explicit congestion notification). - `fin` - close connection. - `psh` - push function. - `rst` - reset connection. - `syn` - new connection. - `urg` - urgent data. Matches some unencrypted P2P protocols. Deprecated since mostly everything is encrypted and requires deep packet inspection to identify. IPv4 only. Interprets the connection tracking analytics data for a particular packet: - `established` - a packet that belongs to an existing connection. - `invalid` - a packet that does not have a determined state in connection tracking (usually severe out-of-order packets, packets with wrong sequence/ack number, or in case of resource over usage on the router). An invalid packet will not participate in NAT (as only connection-state=new packets do), and will still contain the original source IP address when routed. You should drop all `connection-state=invalid` packets in the firewall filter forward and input chains. - `new` - the packet has started a new connection or is otherwise associated with a connection that has not seen packets in both directions. - `related` - a packet that is related to, but not part of an existing connection, such as ICMP errors or a packet that begins an FTP data connection. - `untracked` - a packet that was set to bypass connection tracking in firewall RAW tables. Matches connections that are source-natted, destination-natted, or both. The `connection-state=related` connections' connection-nat-state is determined by the direction of the first packet, and if connection tracking needs to use dst-nat to deliver this connection to the same hosts as the main connection, it will be in connection-nat-state=dstnat even if there are no dst-nat rules at all. `ein-snat` and `ein-dnat` are source and destination nated connections when endpoint-independent NAT is used. IP address to send the sniffed packet to. Port to send the sniffed packet to. ID of the sniffing session. Specifies the route destination for the `route` action. Matches HTTPS traffic based on TLS SNI hostname. Accepts GLOB syntax for wildcard matching. The matcher will not be able to match the hostname if the TLS handshake frame is fragmented into multiple TCP segments. Matches connections per address or address block after a given value is reached. You should use this together with `connection-state=new` and/or with `tcp-flags=syn` because the matcher is very resource-intensive. Layer7 filter name defined in the layer7 protocol menu. Matches the routing realm. IPv4 only. Matches the particular IP protocol specified by protocol name or number. Matches packets whose source is equal to the specified IP or falls into the specified IP range. Matches packets whose destination is equal to the specified IP or falls into the specified IP range. Matches fragmented packets. The first (starting) fragment does not count. If connection tracking is enabled there will be no fragments as the system automatically assembles every packet. IPv4 only. Attempts to detect TCP and UDP scans. Parameters are in the following format: `WeightThreshold, DelayThreshold, LowPortWeight, HighPortWeight`. - `WeightThreshold` - total weight of the latest TCP/UDP packets with different destination ports coming from the same host to be treated as port scan sequence. - `DelayThreshold` - delay for the packets with different destination ports coming from the same host to be treated as possible port scan subsequence. - `LowPortWeight` - the weight of the packets with privileged destination port (<1024). - `HighPortWeight` - the weight of the packets with a non-privileged destination port. IPv4 only. Matches IPv4 header options. - `any` - matches packets with at least one of the IPv4 options. - `loose-source-routing` - matches packets with a loose source routing option. - `no-record-route` - matches packets with no record route option. - `no-router-alert` - matches packets with no router alert option. - `no-source-routing` - matches packets with no source routing option. - `no-timestamp` - matches packets with no timestamp option. - `record-route` - matches packets with record route option. - `router-alert` - matches packets with router alert option. - `strict-source-routing` - matches packets with a strict source routing option. - `timestamp` - matches packets with a timestamp. IPv4 only. Matches the source address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in the subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the destination address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the destination address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in a subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the source address of a packet against a user-defined address list. Supports only one list. Matches the destination address of a packet against a user-defined address list. Supports only one list. Matches packets received from HotSpot clients against various HotSpot matchers. - `auth` - matches authenticated HotSpot client packets. - `from-client` - matches packets coming from the HotSpot client. - `http` - matches HTTP requests sent to the HotSpot server. - `local-dst` - matches packets destined to the HotSpot server. - `to-client` - matches packets sent to the HotSpot client. IPv4 only. Name of the address list to be used. Applicable if the action is `add-dst-to-address-list` or `add-src-to-address-list`. Time interval after which the address will be removed from the address list specified by the `address-list` parameter. Used in conjunction with `add-dst-to-address-list` or `add-src-to-address-list` actions. - `none-dynamic` (`00:00:00`) will leave the address in the address list till reboot. - `none-static` will leave the address in the address list forever and will be included in the configuration export/backup. Matches the packet TTL value. IPv4 only. Matches packets marked by the mangle facility with a particular connection mark. If `no-mark` is set, the rule will match any unmarked connection. Matches packets from related connections based on information from their connection tracking helpers. A relevant connection helper must be enabled under `/ip/firewall/service-port`. Matches packets only if a given amount of bytes has been transferred through the particular connection. 0 means infinity, for example `connection-bytes=2000000-0` means that the rule matches if more than 2MB has been transferred through the relevant connection. Allows capturing traffic based on the present speed of the connection. Matches packets marked by the mangle facility with a particular routing mark. Interface the packet has entered the router. Interface the packet is leaving the router. Set of interfaces defined in interface list. Works the same as `in-interface`. Set of interfaces defined in interface list. Works the same as `out-interface`. Actual interface the packet has entered the router if the incoming interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Actual interface the packet leaves the router if the outgoing interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Set of interfaces defined in interface list. Works the same as `in-bridge-port`. Set of interfaces defined in interface list. Works the same as `out-bridge-port`. Matches packets marked by the mangle facility with a particular packet mark. If `no-mark` is set, the rule will match any unmarked packet. List of source ports and ranges of source ports. Applicable only if the protocol is TCP or UDP. List of destination port numbers or port number ranges. Matches if any (source or destination) port matches the specified list of ports or port ranges. Applicable only if `protocol` is TCP or UDP. Matches ICMP type:code fields. Matches the source MAC address of the packet. Matches packets that contain the specified text. Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP, or MPLS EXP bit. Matches the packet's priority after a new priority has been set. Priority may be derived from VLAN, WMM, DSCP, MPLS EXP bit, or from the priority set by using the set-priority action. Matches the DSCP IP header field. Matches packets up to a limited rate (packet rate or bit rate). A rule with this matcher will match until this limit is reached. Parameters are written in the following format: `rate[/time],burst:mode`. - `rate` - packet or bit count per time interval to match. - `time` - specifies the time interval in which the packet or bit rate cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets or bits to match: this number gets recharged every 10ms so burst should be at least 1/100 of a rate per second. - `mode` - packet or bit mode. Matches packets until a given rate is exceeded. Rate is defined as packets per time interval. As opposed to the `limit` matcher, every flow has its own limit. Flow is defined by a mode parameter. Parameters are written in the following format: `rate[/time],burst,mode[/expire]`. - `rate` - packet count per time interval per-flow to match. - `time` - specifies the time interval in which the packet count rate per flow cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets per flow to match: this number gets recharged by one every time/rate, up to this number. - `mode` - specifies what unique fields define flow (src-address, dst-address, src-and-dst-address, dst-address-and-port, addresses-and-dst-port). - `expire` - specifies interval after which flow with no packets will be allowed to be deleted (optional). Creates a filter based on the packets' arrival time and date or, for locally generated packets, departure time and date. The matcher takes into account the time and timezone configured on the router. Matches packets randomly with a given probability. Matches every nth packet: `nth=2,1` will match every first packet of 2, hence, 50% of all the traffic matched by the rule. Matches the TCP MSS value of an IP packet. PCC matcher allows dividing traffic into equal streams with the ability to keep packets with a specific set of options in one particular stream. Matches packets of specified size or size range in bytes. Add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. Allows logging of packets even if the action is not `log`, useful for debugging the firewall. Adds the specified text at the beginning of every log message. Applicable if `action=log` or `log=yes` is configured. Matches the policy used by IPsec. Value is written in the following format: `direction, policy`. - `in` - valid in the PREROUTING, INPUT, and FORWARD chains. - `out` - valid in the POSTROUTING, OUTPUT, and FORWARD chains. - `ipsec` - matches if the packet is subject to IPsec processing. - `none` - matches packets that are not subject to IPsec processing. #### ip/firewall/mangle/reset-counters **Type:** Command #### ip/firewall/mangle/reset-counters-all **Type:** Command --- ## Nat import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/firewall/nat **Type:** Directory Specifies to which chain the rule will be added. If the input does not match the name of an already defined chain, a new chain will be created. Action to take if a packet is matched by the rule: - `accept` - accept the packet. A packet is not passed to the next firewall rule. - `add-dst-to-address-list` - add the destination address to the address list specified by the `address-list` parameter. - `add-src-to-address-list` - add the source address to the address list specified by the `address-list` parameter. - `jump` - jump to the user-defined chain specified by the value of the `jump-target` parameter. - `log` - add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. - `passthrough` - if a packet is matched by the rule, increase the counter and go to the next rule (useful for statistics). - `return` - passes control back to the chain from where the jump took place. - `src-nat` - replaces the source address of an IP packet with values specified by `to-addresses` and `to-ports` parameters. - `masquerade` - replaces the source port of an IP packet with one specified by `to-ports` parameter and replaces the source address of an IP packet with the IP determined by the routing facility. - `dst-nat` - replaces the destination address and/or port of an IP packet with values specified by `to-addresses` and `to-ports` parameters. - `redirect` - replaces the destination port of an IP packet with one specified by `to-ports` parameter and destination address to the address of the virtual or physical incoming interface (interface that received the packet). - `same` - gives a particular client the same source/destination IP address from a supplied range for each connection. This is most frequently used for services that expect the same client address for multiple connections from the same client. - `netmap` - creates a static 1:1 mapping of one set of IP addresses to another one. Often used to distribute public IP addresses to hosts on private networks. - `endpoint-independent-nat` - uses endpoint-independent mapping and filtering. Works only with UDP protocol. - `socksify` - routes traffic specified by firewall rules through SOCKS proxy server. Requires `socks5-server` and `socks5-port` parameters or `socksify-service` parameter. [relevant socksify information](../../../network-management/socks/socksify.md) Name of the target chain to jump to. Applicable only if `action=jump`. Replace the original address with the specified one. Applicable if action is `dst-nat`, `netmap`, `same`, `src-nat`. Replace the original port with the specified one. Applicable if action is `dst-nat`, `redirect`, `masquerade`, `netmap`, `same`, `src-nat`. Specifies whether to take into account or not the destination IP address when selecting a new source IP address. Applicable if `action=same`. Randomize the port translation. Name of the SOCKS service. IP address of the SOCKS5 server. Port of the SOCKS5 server. Matches connections per address or address block after a given value is reached. You should use this together with `connection-state=new` and/or with `tcp-flags=syn` because the matcher is very resource-intensive. Layer7 filter name defined in the layer7 protocol menu. Matches the routing realm. IPv4 only. Matches the particular IP protocol specified by protocol name or number. Matches packets whose source is equal to the specified IP or falls into the specified IP range. Matches packets whose destination is equal to the specified IP or falls into the specified IP range. Matches fragmented packets. The first (starting) fragment does not count. If connection tracking is enabled there will be no fragments as the system automatically assembles every packet. IPv4 only. Attempts to detect TCP and UDP scans. Parameters are in the following format: `WeightThreshold, DelayThreshold, LowPortWeight, HighPortWeight`. - `WeightThreshold` - total weight of the latest TCP/UDP packets with different destination ports coming from the same host to be treated as port scan sequence. - `DelayThreshold` - delay for the packets with different destination ports coming from the same host to be treated as possible port scan subsequence. - `LowPortWeight` - the weight of the packets with privileged destination port (<1024). - `HighPortWeight` - the weight of the packets with a non-privileged destination port. IPv4 only. Matches IPv4 header options. - `any` - matches packets with at least one of the IPv4 options. - `loose-source-routing` - matches packets with a loose source routing option. - `no-record-route` - matches packets with no record route option. - `no-router-alert` - matches packets with no router alert option. - `no-source-routing` - matches packets with no source routing option. - `no-timestamp` - matches packets with no timestamp option. - `record-route` - matches packets with record route option. - `router-alert` - matches packets with router alert option. - `strict-source-routing` - matches packets with a strict source routing option. - `timestamp` - matches packets with a timestamp. IPv4 only. Matches the source address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in the subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the destination address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the destination address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in a subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the source address of a packet against a user-defined address list. Supports only one list. Matches the destination address of a packet against a user-defined address list. Supports only one list. Matches packets received from HotSpot clients against various HotSpot matchers. - `auth` - matches authenticated HotSpot client packets. - `from-client` - matches packets coming from the HotSpot client. - `http` - matches HTTP requests sent to the HotSpot server. - `local-dst` - matches packets destined to the HotSpot server. - `to-client` - matches packets sent to the HotSpot client. IPv4 only. Name of the address list to be used. Applicable if the action is `add-dst-to-address-list` or `add-src-to-address-list`. Time interval after which the address will be removed from the address list specified by the `address-list` parameter. Used in conjunction with `add-dst-to-address-list` or `add-src-to-address-list` actions. - `none-dynamic` (`00:00:00`) will leave the address in the address list till reboot. - `none-static` will leave the address in the address list forever and will be included in the configuration export/backup. Matches the packet TTL value. IPv4 only. Matches packets marked by the mangle facility with a particular connection mark. If `no-mark` is set, the rule will match any unmarked connection. Matches packets from related connections based on information from their connection tracking helpers. A relevant connection helper must be enabled under `/ip/firewall/service-port`. Matches packets only if a given amount of bytes has been transferred through the particular connection. 0 means infinity, for example `connection-bytes=2000000-0` means that the rule matches if more than 2MB has been transferred through the relevant connection. Allows capturing traffic based on the present speed of the connection. Matches packets marked by the mangle facility with a particular routing mark. Interface the packet has entered the router. Interface the packet is leaving the router. Set of interfaces defined in interface list. Works the same as `in-interface`. Set of interfaces defined in interface list. Works the same as `out-interface`. Actual interface the packet has entered the router if the incoming interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Actual interface the packet leaves the router if the outgoing interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Set of interfaces defined in interface list. Works the same as `in-bridge-port`. Set of interfaces defined in interface list. Works the same as `out-bridge-port`. Matches packets marked by the mangle facility with a particular packet mark. If `no-mark` is set, the rule will match any unmarked packet. List of source ports and ranges of source ports. Applicable only if the protocol is TCP or UDP. List of destination port numbers or port number ranges. Matches if any (source or destination) port matches the specified list of ports or port ranges. Applicable only if `protocol` is TCP or UDP. Matches ICMP type:code fields. Matches the source MAC address of the packet. Matches packets that contain the specified text. Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP, or MPLS EXP bit. Matches the packet's priority after a new priority has been set. Priority may be derived from VLAN, WMM, DSCP, MPLS EXP bit, or from the priority set by using the set-priority action. Matches the DSCP IP header field. Matches packets up to a limited rate (packet rate or bit rate). A rule with this matcher will match until this limit is reached. Parameters are written in the following format: `rate[/time],burst:mode`. - `rate` - packet or bit count per time interval to match. - `time` - specifies the time interval in which the packet or bit rate cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets or bits to match: this number gets recharged every 10ms so burst should be at least 1/100 of a rate per second. - `mode` - packet or bit mode. Matches packets until a given rate is exceeded. Rate is defined as packets per time interval. As opposed to the `limit` matcher, every flow has its own limit. Flow is defined by a mode parameter. Parameters are written in the following format: `rate[/time],burst,mode[/expire]`. - `rate` - packet count per time interval per-flow to match. - `time` - specifies the time interval in which the packet count rate per flow cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets per flow to match: this number gets recharged by one every time/rate, up to this number. - `mode` - specifies what unique fields define flow (src-address, dst-address, src-and-dst-address, dst-address-and-port, addresses-and-dst-port). - `expire` - specifies interval after which flow with no packets will be allowed to be deleted (optional). Creates a filter based on the packets' arrival time and date or, for locally generated packets, departure time and date. The matcher takes into account the time and timezone configured on the router. Matches packets randomly with a given probability. Matches every nth packet: `nth=2,1` will match every first packet of 2, hence, 50% of all the traffic matched by the rule. Matches the TCP MSS value of an IP packet. PCC matcher allows dividing traffic into equal streams with the ability to keep packets with a specific set of options in one particular stream. Matches packets of specified size or size range in bytes. Add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. Allows logging of packets even if the action is not `log`, useful for debugging the firewall. Adds the specified text at the beginning of every log message. Applicable if `action=log` or `log=yes` is configured. Matches the policy used by IPsec. Value is written in the following format: `direction, policy`. - `in` - valid in the PREROUTING, INPUT, and FORWARD chains. - `out` - valid in the POSTROUTING, OUTPUT, and FORWARD chains. - `ipsec` - matches if the packet is subject to IPsec processing. - `none` - matches packets that are not subject to IPsec processing. #### ip/firewall/nat/reset-counters **Type:** Command #### ip/firewall/nat/reset-counters-all **Type:** Command --- ## Raw import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/firewall/raw **Type:** Directory disabled invalid dynamic Specifies to which chain the rule will be added. If the input does not match the name of an already defined chain, a new chain will be created. Action to take if a packet is matched by the rule: - `accept` - accept the packet. A packet is not passed to the next firewall rule. - `add-dst-to-address-list` - add the destination address to the address list specified by the `address-list` parameter. - `add-src-to-address-list` - add the source address to the address list specified by the `address-list` parameter. - `jump` - jump to the user-defined chain specified by the value of the `jump-target` parameter. - `log` - add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. - `passthrough` - if a packet is matched by the rule, increase the counter and go to the next rule (useful for statistics). - `return` - passes control back to the chain from where the jump took place. - `drop` - drop the packet. - `notrack` - do not send a packet to connection tracking. Useful when you still need to use regular firewall, but do not require connection tracking. Name of the target chain to jump to. Applicable only if `action=jump`. Matches the specified TCP flags: - `ack` - acknowledging data. - `cwr` - congestion window reduced. - `ece` - ECN-echo flag (explicit congestion notification). - `fin` - close connection. - `psh` - push function. - `rst` - reset connection. - `syn` - new connection. - `urg` - urgent data. Matches HTTPS traffic based on TLS SNI hostname. Accepts GLOB syntax for wildcard matching. The matcher will not be able to match the hostname if the TLS handshake frame is fragmented into multiple TCP segments. Interface the packet has entered the router. Interface the packet is leaving the router. Set of interfaces defined in interface list. Works the same as `in-interface`. Set of interfaces defined in interface list. Works the same as `out-interface`. Actual interface the packet has entered the router if the incoming interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Actual interface the packet leaves the router if the outgoing interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Set of interfaces defined in interface list. Works the same as `in-bridge-port`. Set of interfaces defined in interface list. Works the same as `out-bridge-port`. Matches packets marked by the mangle facility with a particular packet mark. If `no-mark` is set, the rule will match any unmarked packet. List of source ports and ranges of source ports. Applicable only if the protocol is TCP or UDP. List of destination port numbers or port number ranges. Matches if any (source or destination) port matches the specified list of ports or port ranges. Applicable only if `protocol` is TCP or UDP. Matches ICMP type:code fields. Matches the source MAC address of the packet. Matches packets that contain the specified text. Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP, or MPLS EXP bit. Matches the packet's priority after a new priority has been set. Priority may be derived from VLAN, WMM, DSCP, MPLS EXP bit, or from the priority set by using the set-priority action. Matches the DSCP IP header field. Matches packets up to a limited rate (packet rate or bit rate). A rule with this matcher will match until this limit is reached. Parameters are written in the following format: `rate[/time],burst:mode`. - `rate` - packet or bit count per time interval to match. - `time` - specifies the time interval in which the packet or bit rate cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets or bits to match: this number gets recharged every 10ms so burst should be at least 1/100 of a rate per second. - `mode` - packet or bit mode. Matches packets until a given rate is exceeded. Rate is defined as packets per time interval. As opposed to the `limit` matcher, every flow has its own limit. Flow is defined by a mode parameter. Parameters are written in the following format: `rate[/time],burst,mode[/expire]`. - `rate` - packet count per time interval per-flow to match. - `time` - specifies the time interval in which the packet count rate per flow cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets per flow to match: this number gets recharged by one every time/rate, up to this number. - `mode` - specifies what unique fields define flow (src-address, dst-address, src-and-dst-address, dst-address-and-port, addresses-and-dst-port). - `expire` - specifies interval after which flow with no packets will be allowed to be deleted (optional). Creates a filter based on the packets' arrival time and date or, for locally generated packets, departure time and date. The matcher takes into account the time and timezone configured on the router. Matches packets randomly with a given probability. Matches every nth packet: `nth=2,1` will match every first packet of 2, hence, 50% of all the traffic matched by the rule. Matches the TCP MSS value of an IP packet. PCC matcher allows dividing traffic into equal streams with the ability to keep packets with a specific set of options in one particular stream. Matches packets of specified size or size range in bytes. Add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. Allows logging of packets even if the action is not `log`, useful for debugging the firewall. Adds the specified text at the beginning of every log message. Applicable if `action=log` or `log=yes` is configured. Matches the policy used by IPsec. Value is written in the following format: `direction, policy`. - `in` - valid in the PREROUTING, INPUT, and FORWARD chains. - `out` - valid in the POSTROUTING, OUTPUT, and FORWARD chains. - `ipsec` - matches if the packet is subject to IPsec processing. - `none` - matches packets that are not subject to IPsec processing. Matches the particular IP protocol specified by protocol name or number. Matches packets whose source is equal to the specified IP or falls into the specified IP range. Matches packets whose destination is equal to the specified IP or falls into the specified IP range. Matches fragmented packets. The first (starting) fragment does not count. If connection tracking is enabled there will be no fragments as the system automatically assembles every packet. IPv4 only. Attempts to detect TCP and UDP scans. Parameters are in the following format: `WeightThreshold, DelayThreshold, LowPortWeight, HighPortWeight`. - `WeightThreshold` - total weight of the latest TCP/UDP packets with different destination ports coming from the same host to be treated as port scan sequence. - `DelayThreshold` - delay for the packets with different destination ports coming from the same host to be treated as possible port scan subsequence. - `LowPortWeight` - the weight of the packets with privileged destination port (<1024). - `HighPortWeight` - the weight of the packets with a non-privileged destination port. IPv4 only. Matches IPv4 header options. - `any` - matches packets with at least one of the IPv4 options. - `loose-source-routing` - matches packets with a loose source routing option. - `no-record-route` - matches packets with no record route option. - `no-router-alert` - matches packets with no router alert option. - `no-source-routing` - matches packets with no source routing option. - `no-timestamp` - matches packets with no timestamp option. - `record-route` - matches packets with record route option. - `router-alert` - matches packets with router alert option. - `strict-source-routing` - matches packets with a strict source routing option. - `timestamp` - matches packets with a timestamp. IPv4 only. Matches the source address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in the subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the destination address type: - `unicast` - an IP address used for point-to-point transmission. - `local` - the destination address is assigned to one of the router's interfaces. - `broadcast` - a packet is sent to all devices in a subnet. - `multicast` - a packet is forwarded to a defined group of devices. Matches the source address of a packet against a user-defined address list. Supports only one list. Matches the destination address of a packet against a user-defined address list. Supports only one list. Matches packets received from HotSpot clients against various HotSpot matchers. - `auth` - matches authenticated HotSpot client packets. - `from-client` - matches packets coming from the HotSpot client. - `http` - matches HTTP requests sent to the HotSpot server. - `local-dst` - matches packets destined to the HotSpot server. - `to-client` - matches packets sent to the HotSpot client. IPv4 only. Name of the address list to be used. Applicable if the action is `add-dst-to-address-list` or `add-src-to-address-list`. Time interval after which the address will be removed from the address list specified by the `address-list` parameter. Used in conjunction with `add-dst-to-address-list` or `add-src-to-address-list` actions. - `none-dynamic` (`00:00:00`) will leave the address in the address list till reboot. - `none-static` will leave the address in the address list forever and will be included in the configuration export/backup. Matches the packet TTL value. IPv4 only. Total amount of bytes matched by the rule. Total amount of packets matched by the rule. #### ip/firewall/raw/reset-counters **Type:** Command #### ip/firewall/raw/reset-counters-all **Type:** Command --- ## Service Port import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/firewall/service-port **Type:** Directory disabled invalid Port numbers used by the service. Whether SIP direct media is enabled. SIP timeout value. Name of the service. --- ## Hotspot import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/hotspot **Package:** hotspot **Type:** Directory disabled invalid HTTPS ### ip/hotspot/active **Package:** hotspot **Type:** Directory radius blocked #### ip/hotspot/active/login **Package:** hotspot **Type:** Command ### ip/hotspot/cookie **Package:** hotspot **Type:** Directory mac-cookie ### ip/hotspot/host **Package:** hotspot **Type:** Directory static DHCP dynamic authorized bypassed #### ip/hotspot/host/make-binding **Package:** hotspot **Type:** Command ### ip/hotspot/ip-binding **Package:** hotspot **Type:** Directory disabled bypassed blocked ### ip/hotspot/profile **Package:** hotspot **Type:** Directory default ### ip/hotspot/reset-html **Package:** hotspot **Type:** Command ### ip/hotspot/service-port **Package:** hotspot **Type:** Directory disabled ### ip/hotspot/user **Package:** hotspot **Type:** Directory default disabled dynamic #### ip/hotspot/user/profile **Package:** hotspot **Type:** Directory default #### ip/hotspot/user/reset-counters **Package:** hotspot **Type:** Command ### ip/hotspot/walled-garden **Package:** hotspot **Type:** Directory disabled dynamic #### ip/hotspot/walled-garden/ip **Package:** hotspot **Type:** Directory disabled invalid #### ip/hotspot/walled-garden/reset-counters **Package:** hotspot **Type:** Command #### ip/hotspot/walled-garden/reset-counters-all **Package:** hotspot **Type:** Command --- ## Setup import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ip/hotspot/setup **Package:** hotspot **Type:** Command --- ## Ipsec import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/ipsec **Package:** security **Type:** Directory ### ip/ipsec/active-peers **Package:** security **Type:** Directory responder natt-peer ppk #### ip/ipsec/active-peers/kill-connections **Package:** security **Type:** Command ### ip/ipsec/identity **Package:** security **Type:** Directory dynamic disabled EAP methods Add dynamic raw notrack rules for dynamic policies identity lookup method for the responder key for raw RSA authentication (ike1 only) remote key for raw RSA authentication (ike1 only) pre-shared key secret local certificate use this certificate when peer does not send one EAP or XAuth user EAP or XAuth password ### ip/ipsec/installed-sa **Package:** security **Type:** Directory seen-traffic hw-aead AH ESP #### ip/ipsec/installed-sa/flush **Package:** security **Type:** Command ### ip/ipsec/key **Package:** security **Type:** Directory #### ip/ipsec/key/psk **Package:** security **Type:** Directory ##### ip/ipsec/key/psk/generate **Package:** security **Type:** Command #### ip/ipsec/key/qkd **Package:** security **Type:** Settings Directory KME device address should match the KME ID in the received TLS certificate in bits this also specifies your SAE ID peer (master or slave) SAE ID number of unused keys to keep in cache number of current unused keys in cache total number of received keys ##### ip/ipsec/key/qkd/get-key **Package:** security **Type:** Command additional SAEs which will also get the generated key number of keys to generate ##### ip/ipsec/key/qkd/get-key-cached **Package:** security **Type:** Command ##### ip/ipsec/key/qkd/get-key-with-ids **Package:** security **Type:** Command ##### ip/ipsec/key/qkd/get-status **Package:** security **Type:** Command if not specified, peer-sae-id will be used #### ip/ipsec/key/rsa **Package:** security **Type:** Directory private-key rsa ##### ip/ipsec/key/rsa/export-pub-key **Package:** security **Type:** Command ##### ip/ipsec/key/rsa/generate-key **Package:** security **Type:** Command ##### ip/ipsec/key/rsa/import **Package:** security **Type:** Command ### ip/ipsec/mode-config **Package:** security **Type:** Directory default responder peer shoud request or send the config send system dns servers to peer dns servers sent to peer, exclusive with system-dns issue one address for peer from this pool issued address netmask additional protected subnets DNS name to be resolved using internal server address list name to be added to srcnat chain for initiator conection-mark to be added to srcnat chain for initiator if the dns servers sent should be used by the initiator ### ip/ipsec/peer **Package:** security **Type:** Directory disabled dynamic responder Passive peer won't initiate connection peer's port static PPK secret with "static-ppk-secret" ID used when no one-time key/psk exist for this peer, ensure the key has 256 bits of entropy ### ip/ipsec/policy **Package:** security **Type:** Directory template backup disabled dynamic invalid active default auto activates peer establishes connection, use with shunt policy which ipsec protocol to use endpoint address endpoint address #### ip/ipsec/policy/group **Package:** security **Type:** Directory default ### ip/ipsec/profile **Package:** security **Type:** Directory default IKEv2 only IKEv1 only IKEv1 only Lifetime check logic (IKEv1 only) IKEv1 only post-quantum preshared key (IKEv2 only) IKEv1 only ### ip/ipsec/proposal **Conditions:** IKE2_DEV **Package:** security **Type:** Directory disabled default ### ip/ipsec/settings **Package:** security **Type:** Settings Directory DDOS cookie activation threshold ### ip/ipsec/statistics **Package:** security **Type:** Settings Directory --- ## Kid Control import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/kid-control **Type:** Directory disabled paused blocked rate-limited time with unlimited rate on Sunday ### ip/kid-control/device **Type:** Directory disabled dynamic blocked limited inactive #### ip/kid-control/device/reset-counters **Type:** Command ### ip/kid-control/pause **Type:** Command ### ip/kid-control/resume **Type:** Command --- ## Media import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/media **Conditions:** !smips **Type:** Directory disabled dynamic Only IP address of this hostname (as known to DHCP server) will be allowed to access content ### ip/media/settings **Conditions:** !smips **Type:** Settings Directory Comma separated list of filenames (should end with .jpg). If name of a file in a directory matches any filename in the list, that file is treated as a thumbnail to any media file in that directory. --- ## Nat Pmp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/nat-pmp **Type:** Settings Directory ### ip/nat-pmp/interfaces **Type:** Directory disabled dynamic --- ## Neighbor import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/neighbor **Type:** Directory ### ip/neighbor/discovery-settings **Type:** Settings Directory ### ip/neighbor/lldp **Type:** Directory --- ## Packing import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/packing **Type:** Directory disabled --- ## Pool import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/pool **Type:** Directory IP pools are used to define a range of IP addresses that can be used by various RouterOS utilities, for example, DHCP server, Point-to-Point servers and more. Separate lists for IPv4 and IPv6 are available. Whenever possible, the same IP address is given out to each client (OWNER/INFO pair). Name of the pool. IP address list of non-overlapping IP address ranges in the form of: `from1-to1,from2-to2,...,fromN-toN`. For example, `10.0.0.1-10.0.0.27,10.0.0.32-10.0.0.47`. When IP address acquisition is performed from a pool that has no free addresses, and the next-pool property is set, then an IP address will be acquired from the next pool. ### ip/pool/used **Type:** Directory Menu lists all used IP addresses from IP pools. Name of the IP pool. IP address that is assigned to a client from the pool. Name of the service which acquired this IP address. Additional info, for example, for DHCP - MAC address from the leases menu and for PPP - connections username of a PPP type client. --- ## Proxy import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/proxy **Type:** Settings Directory ### ip/proxy/access **Type:** Directory disabled redirect URL/append URL #### ip/proxy/access/reset-counters **Type:** Command #### ip/proxy/access/reset-counters-all **Type:** Command ### ip/proxy/cache **Type:** Directory disabled ### ip/proxy/cache-contents **Type:** Directory #### ip/proxy/cache/reset-counters **Type:** Command #### ip/proxy/cache/reset-counters-all **Type:** Command ### ip/proxy/clear-cache **Type:** Command ### ip/proxy/connections **Type:** Directory server client ### ip/proxy/direct **Type:** Directory disabled #### ip/proxy/direct/reset-counters **Type:** Command #### ip/proxy/direct/reset-counters-all **Type:** Command ### ip/proxy/inserts **Type:** Settings Directory ### ip/proxy/lookups **Type:** Settings Directory ### ip/proxy/monitor **Type:** Command ### ip/proxy/refreshes **Type:** Settings Directory ### ip/proxy/reset-html **Type:** Command --- ## Reverse Proxy import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/reverse-proxy **Conditions:** !smips **Type:** Directory disabled dynamic --- ## Route import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/route **Type:** Directory dynamic disabled inactive active connect static rip bgp ospf is-is dhcp vpn modem bgp-mpls-vpn hw-offloaded ecmp ### ip/route/check **Type:** Command --- ## Service import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/service **Type:** Directory dynamic disabled invalid connection ### ip/service/webserver **Type:** Settings Directory --- ## Settings import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/settings **Type:** Settings Directory This menu allows you to configure various IPv4 and IPv6-related kernel and system-wide network parameters. These settings control how the operating system handles IP traffic and network communications. Enable or disable packet forwarding between interfaces. Resets all configuration parameters to defaults according to [RFC 1812](https://tools.ietf.org/html/rfc1812) for routers. Send ICMP redirects. Enable this on routers. Accept packets with the SRR option. Accepting source-routed (SSRR/LSRR) packets is a well-known spoofing/security risk and should be kept disabled unless required by the setup. Accept ICMP redirect messages. Enable on hosts and disable on routers. Accept ICMP redirect messages only for gateways listed in the default gateway list. Enable or disable source validation. - `no` - Do not validate source addresses. - `strict` - Strict mode as defined in [RFC 3704](https://tools.ietf.org/html/rfc3704) Strict Reverse Path. Each incoming packet is tested against the FIB and if the interface is not the best reverse path, the packet check will fail. By default, failed packets are discarded. - `loose` - Loose mode as defined in [RFC 3704](https://tools.ietf.org/html/rfc3704) Loose Reverse Path. Each incoming packet's source address is tested against the FIB and if the source address is not reachable through any interface, the packet check will fail. [RFC 3704](https://tools.ietf.org/html/rfc3704) recommends enabling `strict` mode to prevent IP spoofing from DDoS attacks. If you use asymmetric routing, complex routing, or VRRP, then `strict` mode will cause problems, enable `loose` mode instead. IPv4 hash policy used for [ECMP](../../user-guides/routing-and-networking-protocols/routing-decision.md#multipath-ecmp-routes) routing. - l3 - Layer-3 hashing of source and destination IP addresses. - l3-inner - Layer-3 hashing, or inner layer-3 hashing if available. - l4 - Layer-4 hashing of source and destination IP addresses, IP protocol, source port, and destination port. Send syncookies when the SYN backlog queue of a socket overflows. This helps prevent SYN flood attacks. However, syncookies violate the TCP protocol and prevent the use of TCP extensions, which can degrade some services (for example, SMTP relaying). This degradation may be visible to your clients and relays contacting you. Enable or disable TCP timestamps, or add a random offset to TCP timestamps (default behavior). Disabling timestamps can help reduce performance drop spikes. Sets Linux `gc_thresh3`. A maximum number of allowed neighbors in the ARP table. Default value depends on the installed amount of RAM. It is possible to set a higher value than the default, but it increases the risk of out-of-memory condition. The default values for certain RAM sizes: - 2048 for 64 MiB, - 4096 for 128 MiB, - 8192 for 256 MiB, - 16384 for 512 MiB or higher. The ARP cache stores ARP entries, and if some of these entries are incomplete, they can stay in the cache for an indefinite period of time. This will only happen if the number of entries in the cache is less than one-fourth of the maximum number allowed. The reason for this is to prevent the unnecessary running of the garbage-collector when the ARP table is not close to being full. Sets Linux `base_reachable_time` (`base_reachable_time_ms`) on all interfaces that use ARP. The initial validity of the ARP entry is picked from the interval [`timeout/2 - 3*timeout/2`] (default from 15s to 45s) after the neighbor was found. Can use postfix ms, s, m, h, d for milliseconds, seconds, minutes, hours, or days. If no postfix is set then seconds (s) are used. The parameter means how long a valid ARP record will be considered complete if no one communicates with the specific MAC/IP during this time. The parameter does not represent a time when an ARP entry is removed from the ARP cache (see `max-neighbor-entries` setting). Limit the maximum rates for sending ICMP packets whose type matches icmp-rate-mask to specific targets. Value of `0` disables any limiting, other values indicate the minimum space between responses in milliseconds. Mask of ICMP types for which rates are limited. For more information, see the [Linux man pages](http://man7.org/linux/man-pages/man7/icmp.7.html). When enabled, send ICMP error message replies with a source address equal to the primary address of the receiving interface that caused the error. Use this for complex network debugging. Sets the upper bound of memory (in bytes) the kernel may consume for all fragment reassembly queues combined (every interface and every flow). When the total memory used by the cache reaches this limit the kernel starts dropping newly arriving fragments, causing packets to be discarded. Raising the limit reduces the chance of drops under heavy fragmentation (e.g. high-throughput links with VPNs, or MTU-limited paths), but it also raises the maximum amount of RAM that can be used. The default value depends on the installed amount of RAM: - 512 KiB for 64 MiB of RAM, - 1024 KiB for 128 MiB of RAM, - 2048 KiB for 256 MiB of RAM, - 4096 KiB for 512MiB of RAM, - 16 MiB for 1 GiB of RAM, - 32 MiB for 2 GiB of RAM or higher. Time in seconds to keep an IPv4 fragment in memory. Allows [Fast Path](../../firewall-and-quality-of-service/packet-flow-in-routeros#fast-path) Indicates whether fast-path is active. Amount of fast-pathed packets. Amount of fast-pathed bytes. Indicates whether fasttrack is active. Amount of fasttracked packets. Amount of fasttracked bytes. --- ## Smb import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/smb **Conditions:** !smips **Type:** Settings Directory ### ip/smb/shares **Conditions:** !smips **Type:** Directory dynamic disabled default read-only require-encryption ### ip/smb/users **Conditions:** !smips **Type:** Directory dynamic disabled default read-only --- ## Socks import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/socks **Type:** Settings Directory ### ip/socks/access **Type:** Directory disabled ### ip/socks/connections **Type:** Directory ### ip/socks/users **Type:** Directory disabled --- ## Socksify import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/socksify **Type:** Directory See [Socksify](../../network-management/socks/socksify) for the full documentation. disabled (set by default) dynamic Name of the Socksify service Time in seconds to wait for the SOCKS proxy or destination to respond during connection setup before aborting with an error. Set to 0 to disable timeout (default value: **60s**) TCP port used by the Socksify service (default value: **952**) IP address of the SOCKS5 proxy server, IPv4 only (default value: **0.0.0.0**) Listening port of the SOCKS5 proxy server (default value: **1080**) Username for the SOCKS5 proxy server access Password for the SOCKS5 proxy server access --- ## Ssh import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/ssh **Package:** security **Type:** Settings Directory allowed cipher list control which forwarding is allowed use stronger encryption, HMAC algorithms, use bigger DH primes and disallow weaker ones RSA key size when host key is regenerated ### ip/ssh/export-host-key **Package:** security **Type:** Command ### ip/ssh/import-host-key **Package:** security **Type:** Command ### ip/ssh/regenerate-host-key **Package:** security **Type:** Command --- ## Tftp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/tftp **Type:** Directory disabled ### ip/tftp/settings **Type:** Settings Directory maximum block size allowed to negotiate --- ## Traffic Flow import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/traffic-flow **Type:** Settings Directory ### ip/traffic-flow/ipfix **Type:** Settings Directory ### ip/traffic-flow/monitor **Type:** Command ### ip/traffic-flow/target **Type:** Directory disabled --- ## Upnp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/upnp **Type:** Settings Directory ### ip/upnp/interfaces **Type:** Directory disabled dynamic --- ## Client import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- --- ## Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- --- ## Vrf import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ip/vrf **Type:** Directory disabled builtin --- ## Address(Ipv6) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ipv6/address **Package:** ipv6 **Type:** Directory disabled invalid dynamic global link-local Whether address belongs to an interface which is a slave port to some other master interface. deprecated IPv6 address. Address can also be constructed from the pool if `from-pool` parameter is specified. For example if address is set to `::1/64` then address will be constructed as follows `::1/64` Name of the pool from which prefix will be taken to construct IPv6 address taking last part of the address from address property. Specify how to acquire prefix from pool, if `from-pool` parameter is set. - `recommended` option will use `address` as a postfix and **subnet-id**, if subnet-id is provided. - `strict` will use **address** as a strict postfix. - `without-acquire` will not allocate a prefix from a pool and will allow other services to use the exact same prefix. The `without-acquire` option should be mainly used to create SLAAC address on a router which at the same time will be a DHCPv6 server providing addresses to client from the same subnet. Specifies the interface on which the IPv6 address is configured. You can select it from the pool of interfaces available on the router. Whether to calculate EUI-64 address and use it as last 64 bits of the IPv6 address. Whether to enable stateless address configuration. The prefix of that address is automatically advertised three times to hosts using ICMPv6 protocol. The option is set by default for addresses with prefix length 64. If address is removed or changed, then old prefix will be deprecated by automatically advertising the old prefix with lifetime set to `0s` three times to hosts using ICMPv6 protocol. If enabled (yes) - disables Duplicate Address Detection (DAD) for IPv6 addresses on an interface. This can be useful in scenarios where you want to assign static IPv6 addresses to devices and avoid the delay caused by DAD. If you want to manually add a link‑local address to an interface, this setting lets you override the automatically generated IPv6 link‑local address. Actual interface on which address is set up. For example, if address was configured on ethernet interface and ethernet interface was added to bridge, then actual interface is bridge not ethernet. Indicates which VRF this IP address is associated with. --- ## Dhcp Client(Ipv6) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ipv6/dhcp-client **Package:** dhcp **Type:** Directory dynamic disabled invalid accept prefix even if no address was offered (applied only if both address and prefix were requested) Defines whether to add the default route to the DHCP server (or immediate relay if response was relayed) Whether to accept the DNS settings advertised by DHCP server use DUID generated from current interface MAC used as client DUID, overrides use-interface-duid use Rapid Commit if possible name of the pool that is created from the received prefix (applied only if prefix was requested) prefix length of the pool created from the received prefix (applied only if prefix was requested); if unset, prefix length is determined automatically address lists to which the received prefix will be added (applied only if prefix was requested) ### ipv6/dhcp-client/option **Package:** dhcp **Type:** Directory default ### ipv6/dhcp-client/release **Package:** dhcp **Type:** Command ### ipv6/dhcp-client/renew **Package:** dhcp **Type:** Command --- ## Dhcp Relay(Ipv6) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ipv6/dhcp-relay **Package:** dhcp **Type:** Directory disabled invalid Relay will listen to messages originating from clients on this interface Servers to which the relay message will be forwarded Options that are added to Relay-Forward messages. Note that option 18 (interface-id) is added automatically so that relay can relay the reply message correctly. If secs field in DHCP packet is smaller than delay-threshold, then this packet is ignored Add routes to valid bindings found in reply messages ### ipv6/dhcp-relay/monitor **Package:** dhcp **Type:** Command ### ipv6/dhcp-relay/option **Package:** dhcp **Type:** Directory default Option is added only if packet originated from client (not another relay) and MAC address is deducible ### ipv6/dhcp-relay/reset-counters **Package:** dhcp **Type:** Command ### ipv6/dhcp-relay/routes **Package:** dhcp **Type:** Directory used as gateway --- ## Dhcp Server(Ipv6) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ipv6/dhcp-server **Package:** dhcp **Type:** Directory dynamic disabled invalid Pool from which dynamic prefix bindings will acquire prefixes Pool from which dynamic address bindings will acquire addresses (pool prefix length must be 128) Duration of the newly created and extended bindings Append Rapid Commit option to use two packet Solicit-Reply exchange Use RADIUS server for authentication Advertise message preference, the highest server preference value is preferred over all others distance for issued client bindings in routing table Address lists to which the binding prefix/address will be added (can be overridden by binding address-lists parameter) Server will ignore IA_NA options in the messages sent by the client and will act as if the message didn't contain them ### ipv6/dhcp-server/binding **Package:** dhcp **Type:** Directory invalid disabled radius dynamic Assigns an individual address or prefix to the client hex string Name of the server that can offer this binding to the client for addresses, pool with prefix length 128 Bit rate limit for the client Address lists to which the binding prefix/address will be added (overrides server address-lists parameter) #### ipv6/dhcp-server/binding/make-static **Package:** dhcp **Type:** Command #### ipv6/dhcp-server/binding/send-reconfigure **Package:** dhcp **Type:** Command ### ipv6/dhcp-server/option **Package:** dhcp **Type:** Directory #### ipv6/dhcp-server/option/sets **Package:** dhcp **Type:** Directory --- ## Address List(Firewall) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ipv6/firewall/address-list **Package:** ipv6 **Type:** Directory disabled dynamic Name of the address list where the IP address will be added. A single IPv6 address or prefix to add to the address list, or a DNS name. Time after which the address will be removed from the address list. If the timeout is not specified, the address will be stored in the address list permanently. Whether the entry is dynamically created. The time when the entry was created. --- ## Connection(Firewall) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ipv6/firewall/connection **Package:** ipv6 **Type:** Directory expected seen-reply assured confirmed dying fasttrack hw-offload srcnat dstnat uses-helper Connection protocol. Source IP address of the connection. Source port of the connection. Destination IP address of the connection. Destination port of the connection. Reply source IP address. Reply source port. Reply destination IP address. Reply destination port. TCP connection state. ICMP type. ICMP code. ICMP ID. GRE protocol. GRE version. GRE key. Connection type. Connection timeout. Connection mark. Number of original direction packets. Number of original direction bytes. Number of original direction fasttrack packets. Number of original direction fasttrack bytes. Number of reply direction packets. Number of reply direction bytes. Number of reply direction fasttrack packets. Number of reply direction fasttrack bytes. Original direction rate. Reply direction rate. --- ## Filter(Firewall) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ipv6/firewall/filter **Package:** ipv6 **Type:** Directory Specifies to which chain the rule will be added. If the input does not match the name of an already defined chain, a new chain will be created. Action to take if a packet is matched by the rule: `accept` - accept the packet. A packet is not passed to the next firewall rule. `add-dst-to-address-list` - add the destination address to the address list specified by the `address-list` parameter. `add-src-to-address-list` - add the source address to the address list specified by the `address-list` parameter. `drop` - drop the packet. `fasttrack-connection` - fasttrack the connection. `jump` - jump to the user-defined chain specified by the value of the `jump-target` parameter. `log` - add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. `passthrough` - if a packet is matched by the rule, increase the counter and go to the next rule (useful for statistics). `reject` - reject the packet and send an ICMP response. `return` - passes control back to the chain from where the jump took place. Name of the target chain to jump to. Applicable only if `action=jump`. Specifies the [ICMP error](https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-codes-2) to be sent back if the packet is rejected. Applicable if `action=reject`. - `icmp-no-route` - sends an ICMP address no-route message. ICMP type 1, code 0 - `icmp-admin-prohibited` - sends an ICMP address prohibited message. ICMP type 1, code 1 - `icmp-not-neighbour` - sends an ICMP address not-member message. ICMP type 1, code 2 - `icmp-address-unreachable` - sends an ICMP address unreachable message. ICMP type 1, code 3 - `icmp-port-unreachable` - sends an ICMP port unreachable message. ICMP type 1, code 4 - `tcp-reset` - sends an ICMP message resetting a TCP connection. ICMP type 1, code 6 - `icmp-err-src-routing-header` - sends an ICMP Error in Source Routing Header message. ICMP type 1, code 7 - `icmp-headers-too-long` - sends an ICMP Headers too long message. ICMP type 1, code 8 Matches connections that are source-natted, destination-natted, or both. Matches HTTPS traffic based on TLS SNI hostname. Accepts GLOB syntax for wildcard matching. The matcher will not be able to match the hostname if the TLS handshake frame is fragmented into multiple TCP segments. Interprets the connection tracking analytics data for a particular packet: `established` - a packet that belongs to an existing connection. `invalid` - a packet that does not have a determined state in connection tracking (usually severe out-of-order packets, packets with wrong sequence/ack number, or in case of resource over usage on the router). An invalid packet will not participate in NAT, and will still contain the original source IP address when routed. You should drop all `connection-state=invalid` packets in the firewall filter forward and input chains. `new` - the packet has started a new connection or is otherwise associated with a connection that has not seen packets in both directions. `related` - a packet that is related to, but not part of an existing connection, such as ICMP errors or a packet that begins an FTP data connection. `untracked` - a packet that was set to bypass connection tracking in firewall RAW tables. Matches connections per address or address block after a given value is reached. You should use this together with `connection-state=new` and/or with `tcp-flags=syn` because the matcher is very resource-intensive. Matches the particular IP protocol specified by protocol name or number. Matches packets whose source is equal to the specified IP or falls into the specified IP range. Matches packets whose destination is equal to the specified IP or falls into the specified IP range. Matches the source address of a packet against a user-defined address list. Supports only one list. Matches the destination address of a packet against a user-defined address list. Supports only one list. Name of the address list to be used. Applicable if the action is `add-dst-to-address-list` or `add-src-to-address-list`. Time interval after which the address will be removed from the address list specified by the `address-list` parameter. Used in conjunction with `add-dst-to-address-list` or `add-src-to-address-list` actions. `none-dynamic` (`00:00:00`) will leave the address in the address list till reboot. `none-static` will leave the address in the address list forever and will be included in the configuration export/backup. Matches the source address type: `unicast` - an IP address used for point-to-point transmission. `local` - the address is assigned to one of the router's interfaces. `anycast` - a packet sent to the nearest node in a group. `multicast` - a packet is forwarded to a defined group of devices. `unreachable` - the address is unreachable. Matches the destination address type: `unicast` - an IP address used for point-to-point transmission. `local` - the destination address is assigned to one of the router's interfaces. `anycast` - a packet sent to the nearest node in a group. `multicast` - a packet is forwarded to a defined group of devices. `unreachable` - the address is unreachable. Matches IPv6 next-header. Two types of header matching are possible controlled by the `mode` parameter: `contains` - soft matching, matches at least selected headers. `exact` - matches the exact set of selected headers. Matches the specified TCP flags: `ack` - acknowledging data. `cwr` - congestion window reduced. `ece` - ECN-echo flag (explicit congestion notification). `fin` - close connection. `psh` - push function. `rst` - reset connection. `syn` - new connection. `urg` - urgent data. Matches the hop limit field in the IPv6 header. Matches packets marked by the mangle facility with a particular connection mark. If `no-mark` is set, the rule will match any unmarked connection. Matches packets from related connections based on information from their connection tracking helpers. A relevant connection helper must be enabled under `/ip/firewall/service-port`. Matches packets only if a given amount of bytes has been transferred through the particular connection. 0 means infinity, for example `connection-bytes=2000000-0` means that the rule matches if more than 2MB has been transferred through the relevant connection. Allows capturing traffic based on the present speed of the connection. Matches packets marked by the mangle facility with a particular routing mark. Interface the packet has entered the router. Interface the packet is leaving the router. Set of interfaces defined in interface list. Works the same as `in-interface`. Set of interfaces defined in interface list. Works the same as `out-interface`. Actual interface the packet has entered the router if the incoming interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Actual interface the packet leaves the router if the outgoing interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Set of interfaces defined in interface list. Works the same as `in-bridge-port`. Set of interfaces defined in interface list. Works the same as `out-bridge-port`. Matches packets marked by the mangle facility with a particular packet mark. If `no-mark` is set, the rule will match any unmarked packet. List of source ports and ranges of source ports. Applicable only if the protocol is TCP or UDP. List of destination port numbers or port number ranges. Matches if any (source or destination) port matches the specified list of ports or port ranges. Applicable only if `protocol` is TCP or UDP. Matches ICMP type:code fields. Matches the source MAC address of the packet. Matches packets that contain the specified text. Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP, or MPLS EXP bit. Matches the packet's priority after a new priority has been set. Priority may be derived from VLAN, WMM, DSCP, MPLS EXP bit, or from the priority set by using the set-priority action. Matches the DSCP IP header field. Matches packets up to a limited rate (packet rate or bit rate). A rule with this matcher will match until this limit is reached. Parameters are written in the following format: `rate[/time],burst:mode`. - `rate` - packet or bit count per time interval to match. - `time` - specifies the time interval in which the packet or bit rate cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets or bits to match: this number gets recharged every 10ms so burst should be at least 1/100 of a rate per second. - `mode` - packet or bit mode. Matches packets until a given rate is exceeded. Rate is defined as packets per time interval. As opposed to the `limit` matcher, every flow has its own limit. Flow is defined by a mode parameter. Parameters are written in the following format: `rate[/time],burst,mode[/expire]`. - `rate` - packet count per time interval per-flow to match. - `time` - specifies the time interval in which the packet count rate per flow cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets per flow to match: this number gets recharged by one every time/rate, up to this number. - `mode` - specifies what unique fields define flow (src-address, dst-address, src-and-dst-address, dst-address-and-port, addresses-and-dst-port). - `expire` - specifies interval after which flow with no packets will be allowed to be deleted (optional). Creates a filter based on the packets' arrival time and date or, for locally generated packets, departure time and date. The matcher takes into account the time and timezone configured on the router. Matches packets randomly with a given probability. Matches every nth packet: `nth=2,1` will match every first packet of 2, hence, 50% of all the traffic matched by the rule. Matches the TCP MSS value of an IP packet. PCC matcher allows dividing traffic into equal streams with the ability to keep packets with a specific set of options in one particular stream. Matches packets of specified size or size range in bytes. Add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. Allows logging of packets even if the action is not `log`, useful for debugging the firewall. Adds the specified text at the beginning of every log message. Applicable if `action=log` or `log=yes` is configured. Matches the policy used by IPsec. Value is written in the following format: `direction, policy`. - `in` - valid in the PREROUTING, INPUT, and FORWARD chains. - `out` - valid in the POSTROUTING, OUTPUT, and FORWARD chains. - `ipsec` - matches if the packet is subject to IPsec processing. - `none` - matches packets that are not subject to IPsec processing. #### ipv6/firewall/filter/reset-counters **Type:** Command #### ipv6/firewall/filter/reset-counters-all **Type:** Command --- ## Mangle(Firewall) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ipv6/firewall/mangle **Package:** ipv6 **Type:** Directory Specifies to which chain the rule will be added. If the input does not match the name of an already defined chain, a new chain will be created. Action to take if a packet is matched by the rule: - `accept` - accept the packet. A packet is not passed to the next firewall rule. - `add-dst-to-address-list` - add the destination address to the address list specified by the `address-list` parameter. - `add-src-to-address-list` - add the source address to the address list specified by the `address-list` parameter. - `change-dscp` - change the DSCP value of the packet. - `change-hop-limit` - change the hop limit value of the packet. - `change-mss` - change the MSS value of the packet. - `dnpt` - perform destination IPv6 network prefix translation. - `drop` - drop the packet. - `jump` - jump to the user-defined chain specified by the value of the `jump-target` parameter. - `log` - add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. - `mark-connection` - mark the connection with the specified `new-connection-mark`. - `mark-packet` - mark the packet with the specified `new-packet-mark`. - `mark-routing` - mark the packet for routing with the specified `new-routing-mark`. - `passthrough` - if a packet is matched by the rule, increase the counter and go to the next rule (useful for statistics). - `return` - passes control back to the chain from where the jump took place. - `set-priority` - set the priority of the packet. - `sniff-pc` - sniff the packet and send it to the specified Packet Capturer target. - `sniff-tzsp` - sniff the packet and send it to the specified TZSP target. - `snpt` - perform source IPv6 network prefix translation. Source IPv6 prefix for SNPT/DNPT actions. Destination IPv6 prefix for SNPT/DNPT actions. Name of the target chain to jump to. Applicable only if `action=jump`. Sets the new packet mark value. Sets the new connection mark value. Sets the new routing mark value. Sets the new MSS value. Sets the new DSCP value. Sets the new priority value. Sets the new hop limit value. Whether to let the packet pass through to the next rule. IP address to send the sniffed packet to. Port to send the sniffed packet to. ID of the sniffing session. Matches connections that are source-natted, destination-natted, or both. Matches HTTPS traffic based on TLS SNI hostname. Accepts GLOB syntax for wildcard matching. The matcher will not be able to match the hostname if the TLS handshake frame is fragmented into multiple TCP segments. Interprets the connection tracking analytics data for a particular packet: `established` - a packet that belongs to an existing connection. `invalid` - a packet that does not have a determined state in connection tracking (usually severe out-of-order packets, packets with wrong sequence/ack number, or in case of resource over usage on the router). An invalid packet will not participate in NAT, and will still contain the original source IP address when routed. You should drop all `connection-state=invalid` packets in the firewall filter forward and input chains. `new` - the packet has started a new connection or is otherwise associated with a connection that has not seen packets in both directions. `related` - a packet that is related to, but not part of an existing connection, such as ICMP errors or a packet that begins an FTP data connection. `untracked` - a packet that was set to bypass connection tracking in firewall RAW tables. Matches connections per address or address block after a given value is reached. You should use this together with `connection-state=new` and/or with `tcp-flags=syn` because the matcher is very resource-intensive. Matches the particular IP protocol specified by protocol name or number. Matches packets whose source is equal to the specified IP or falls into the specified IP range. Matches packets whose destination is equal to the specified IP or falls into the specified IP range. Matches the source address of a packet against a user-defined address list. Supports only one list. Matches the destination address of a packet against a user-defined address list. Supports only one list. Name of the address list to be used. Applicable if the action is `add-dst-to-address-list` or `add-src-to-address-list`. Time interval after which the address will be removed from the address list specified by the `address-list` parameter. Used in conjunction with `add-dst-to-address-list` or `add-src-to-address-list` actions. `none-dynamic` (`00:00:00`) will leave the address in the address list till reboot. `none-static` will leave the address in the address list forever and will be included in the configuration export/backup. Matches the source address type: `unicast` - an IP address used for point-to-point transmission. `local` - the address is assigned to one of the router's interfaces. `anycast` - a packet sent to the nearest node in a group. `multicast` - a packet is forwarded to a defined group of devices. `unreachable` - the address is unreachable. Matches the destination address type: `unicast` - an IP address used for point-to-point transmission. `local` - the destination address is assigned to one of the router's interfaces. `anycast` - a packet sent to the nearest node in a group. `multicast` - a packet is forwarded to a defined group of devices. `unreachable` - the address is unreachable. Matches IPv6 next-header. Two types of header matching are possible controlled by the `mode` parameter: `contains` - soft matching, matches at least selected headers. `exact` - matches the exact set of selected headers. Matches the specified TCP flags: `ack` - acknowledging data. `cwr` - congestion window reduced. `ece` - ECN-echo flag (explicit congestion notification). `fin` - close connection. `psh` - push function. `rst` - reset connection. `syn` - new connection. `urg` - urgent data. Matches the hop limit field in the IPv6 header. Matches packets marked by the mangle facility with a particular connection mark. If `no-mark` is set, the rule will match any unmarked connection. Matches packets from related connections based on information from their connection tracking helpers. A relevant connection helper must be enabled under `/ip/firewall/service-port`. Matches packets only if a given amount of bytes has been transferred through the particular connection. 0 means infinity, for example `connection-bytes=2000000-0` means that the rule matches if more than 2MB has been transferred through the relevant connection. Allows capturing traffic based on the present speed of the connection. Matches packets marked by the mangle facility with a particular routing mark. Interface the packet has entered the router. Interface the packet is leaving the router. Set of interfaces defined in interface list. Works the same as `in-interface`. Set of interfaces defined in interface list. Works the same as `out-interface`. Actual interface the packet has entered the router if the incoming interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Actual interface the packet leaves the router if the outgoing interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Set of interfaces defined in interface list. Works the same as `in-bridge-port`. Set of interfaces defined in interface list. Works the same as `out-bridge-port`. Matches packets marked by the mangle facility with a particular packet mark. If `no-mark` is set, the rule will match any unmarked packet. List of source ports and ranges of source ports. Applicable only if the protocol is TCP or UDP. List of destination port numbers or port number ranges. Matches if any (source or destination) port matches the specified list of ports or port ranges. Applicable only if `protocol` is TCP or UDP. Matches ICMP type:code fields. Matches the source MAC address of the packet. Matches packets that contain the specified text. Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP, or MPLS EXP bit. Matches the packet's priority after a new priority has been set. Priority may be derived from VLAN, WMM, DSCP, MPLS EXP bit, or from the priority set by using the set-priority action. Matches the DSCP IP header field. Matches packets up to a limited rate (packet rate or bit rate). A rule with this matcher will match until this limit is reached. Parameters are written in the following format: `rate[/time],burst:mode`. - `rate` - packet or bit count per time interval to match. - `time` - specifies the time interval in which the packet or bit rate cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets or bits to match: this number gets recharged every 10ms so burst should be at least 1/100 of a rate per second. - `mode` - packet or bit mode. Matches packets until a given rate is exceeded. Rate is defined as packets per time interval. As opposed to the `limit` matcher, every flow has its own limit. Flow is defined by a mode parameter. Parameters are written in the following format: `rate[/time],burst,mode[/expire]`. - `rate` - packet count per time interval per-flow to match. - `time` - specifies the time interval in which the packet count rate per flow cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets per flow to match: this number gets recharged by one every time/rate, up to this number. - `mode` - specifies what unique fields define flow (src-address, dst-address, src-and-dst-address, dst-address-and-port, addresses-and-dst-port). - `expire` - specifies interval after which flow with no packets will be allowed to be deleted (optional). Creates a filter based on the packets' arrival time and date or, for locally generated packets, departure time and date. The matcher takes into account the time and timezone configured on the router. Matches packets randomly with a given probability. Matches every nth packet: `nth=2,1` will match every first packet of 2, hence, 50% of all the traffic matched by the rule. Matches the TCP MSS value of an IP packet. PCC matcher allows dividing traffic into equal streams with the ability to keep packets with a specific set of options in one particular stream. Matches packets of specified size or size range in bytes. Add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. Allows logging of packets even if the action is not `log`, useful for debugging the firewall. Adds the specified text at the beginning of every log message. Applicable if `action=log` or `log=yes` is configured. Matches the policy used by IPsec. Value is written in the following format: `direction, policy`. - `in` - valid in the PREROUTING, INPUT, and FORWARD chains. - `out` - valid in the POSTROUTING, OUTPUT, and FORWARD chains. - `ipsec` - matches if the packet is subject to IPsec processing. - `none` - matches packets that are not subject to IPsec processing. #### ipv6/firewall/mangle/reset-counters **Type:** Command #### ipv6/firewall/mangle/reset-counters-all **Type:** Command --- ## Nat(Firewall) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ipv6/firewall/nat **Package:** ipv6 **Type:** Directory Specifies to which chain the rule will be added. If the input does not match the name of an already defined chain, a new chain will be created. Action to take if a packet is matched by the rule: `accept` - accept the packet. A packet is not passed to the next firewall rule. `add-dst-to-address-list` - add the destination address to the address list specified by the `address-list` parameter. `add-src-to-address-list` - add the source address to the address list specified by the `address-list` parameter. `dst-nat` - perform destination NAT. `jump` - jump to the user-defined chain specified by the value of the `jump-target` parameter. `log` - add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. `masquerade` - masquerade the source address. `netmap` - create a static 1:1 NAT mapping. `passthrough` - if a packet is matched by the rule, increase the counter and go to the next rule (useful for statistics). `redirect` - redirect the packet to the router. `return` - passes control back to the chain from where the jump took place. `src-nat` - perform source NAT. Name of the target chain to jump to. Applicable only if `action=jump`. IPv6 address to translate to. Port or port range to translate to. Interprets the connection tracking analytics data for a particular packet: `established` - a packet that belongs to an existing connection. `invalid` - a packet that does not have a determined state in connection tracking (usually severe out-of-order packets, packets with wrong sequence/ack number, or in case of resource over usage on the router). An invalid packet will not participate in NAT, and will still contain the original source IP address when routed. You should drop all `connection-state=invalid` packets in the firewall filter forward and input chains. `new` - the packet has started a new connection or is otherwise associated with a connection that has not seen packets in both directions. `related` - a packet that is related to, but not part of an existing connection, such as ICMP errors or a packet that begins an FTP data connection. `untracked` - a packet that was set to bypass connection tracking in firewall RAW tables. Matches connections per address or address block after a given value is reached. You should use this together with `connection-state=new` and/or with `tcp-flags=syn` because the matcher is very resource-intensive. Matches the particular IP protocol specified by protocol name or number. Matches packets whose source is equal to the specified IP or falls into the specified IP range. Matches packets whose destination is equal to the specified IP or falls into the specified IP range. Matches the source address of a packet against a user-defined address list. Supports only one list. Matches the destination address of a packet against a user-defined address list. Supports only one list. Name of the address list to be used. Applicable if the action is `add-dst-to-address-list` or `add-src-to-address-list`. Time interval after which the address will be removed from the address list specified by the `address-list` parameter. Used in conjunction with `add-dst-to-address-list` or `add-src-to-address-list` actions. `none-dynamic` (`00:00:00`) will leave the address in the address list till reboot. `none-static` will leave the address in the address list forever and will be included in the configuration export/backup. Matches the source address type: `unicast` - an IP address used for point-to-point transmission. `local` - the address is assigned to one of the router's interfaces. `anycast` - a packet sent to the nearest node in a group. `multicast` - a packet is forwarded to a defined group of devices. `unreachable` - the address is unreachable. Matches the destination address type: `unicast` - an IP address used for point-to-point transmission. `local` - the destination address is assigned to one of the router's interfaces. `anycast` - a packet sent to the nearest node in a group. `multicast` - a packet is forwarded to a defined group of devices. `unreachable` - the address is unreachable. Matches IPv6 next-header. Two types of header matching are possible controlled by the `mode` parameter: `contains` - soft matching, matches at least selected headers. `exact` - matches the exact set of selected headers. Matches the specified TCP flags: `ack` - acknowledging data. `cwr` - congestion window reduced. `ece` - ECN-echo flag (explicit congestion notification). `fin` - close connection. `psh` - push function. `rst` - reset connection. `syn` - new connection. `urg` - urgent data. Matches the hop limit field in the IPv6 header. Matches packets marked by the mangle facility with a particular connection mark. If `no-mark` is set, the rule will match any unmarked connection. Matches packets from related connections based on information from their connection tracking helpers. A relevant connection helper must be enabled under `/ip/firewall/service-port`. Matches packets only if a given amount of bytes has been transferred through the particular connection. 0 means infinity, for example `connection-bytes=2000000-0` means that the rule matches if more than 2MB has been transferred through the relevant connection. Allows capturing traffic based on the present speed of the connection. Matches packets marked by the mangle facility with a particular routing mark. Interface the packet has entered the router. Interface the packet is leaving the router. Set of interfaces defined in interface list. Works the same as `in-interface`. Set of interfaces defined in interface list. Works the same as `out-interface`. Actual interface the packet has entered the router if the incoming interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Actual interface the packet leaves the router if the outgoing interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Set of interfaces defined in interface list. Works the same as `in-bridge-port`. Set of interfaces defined in interface list. Works the same as `out-bridge-port`. Matches packets marked by the mangle facility with a particular packet mark. If `no-mark` is set, the rule will match any unmarked packet. List of source ports and ranges of source ports. Applicable only if the protocol is TCP or UDP. List of destination port numbers or port number ranges. Matches if any (source or destination) port matches the specified list of ports or port ranges. Applicable only if `protocol` is TCP or UDP. Matches ICMP type:code fields. Matches the source MAC address of the packet. Matches packets that contain the specified text. Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP, or MPLS EXP bit. Matches the packet's priority after a new priority has been set. Priority may be derived from VLAN, WMM, DSCP, MPLS EXP bit, or from the priority set by using the set-priority action. Matches the DSCP IP header field. Matches packets up to a limited rate (packet rate or bit rate). A rule with this matcher will match until this limit is reached. Parameters are written in the following format: `rate[/time],burst:mode`. - `rate` - packet or bit count per time interval to match. - `time` - specifies the time interval in which the packet or bit rate cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets or bits to match: this number gets recharged every 10ms so burst should be at least 1/100 of a rate per second. - `mode` - packet or bit mode. Matches packets until a given rate is exceeded. Rate is defined as packets per time interval. As opposed to the `limit` matcher, every flow has its own limit. Flow is defined by a mode parameter. Parameters are written in the following format: `rate[/time],burst,mode[/expire]`. - `rate` - packet count per time interval per-flow to match. - `time` - specifies the time interval in which the packet count rate per flow cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets per flow to match: this number gets recharged by one every time/rate, up to this number. - `mode` - specifies what unique fields define flow (src-address, dst-address, src-and-dst-address, dst-address-and-port, addresses-and-dst-port). - `expire` - specifies interval after which flow with no packets will be allowed to be deleted (optional). Creates a filter based on the packets' arrival time and date or, for locally generated packets, departure time and date. The matcher takes into account the time and timezone configured on the router. Matches packets randomly with a given probability. Matches every nth packet: `nth=2,1` will match every first packet of 2, hence, 50% of all the traffic matched by the rule. Matches the TCP MSS value of an IP packet. PCC matcher allows dividing traffic into equal streams with the ability to keep packets with a specific set of options in one particular stream. Matches packets of specified size or size range in bytes. Add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. Allows logging of packets even if the action is not `log`, useful for debugging the firewall. Adds the specified text at the beginning of every log message. Applicable if `action=log` or `log=yes` is configured. Matches the policy used by IPsec. Value is written in the following format: `direction, policy`. - `in` - valid in the PREROUTING, INPUT, and FORWARD chains. - `out` - valid in the POSTROUTING, OUTPUT, and FORWARD chains. - `ipsec` - matches if the packet is subject to IPsec processing. - `none` - matches packets that are not subject to IPsec processing. #### ipv6/firewall/nat/reset-counters **Type:** Command #### ipv6/firewall/nat/reset-counters-all **Type:** Command --- ## Raw(Firewall) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ipv6/firewall/raw **Package:** ipv6 **Type:** Directory disabled invalid dynamic Specifies to which chain the rule will be added. If the input does not match the name of an already defined chain, a new chain will be created. Action to take if a packet is matched by the rule: `accept` - accept the packet. A packet is not passed to the next firewall rule. `add-dst-to-address-list` - add the destination address to the address list specified by the `address-list` parameter. `add-src-to-address-list` - add the source address to the address list specified by the `address-list` parameter. `drop` - drop the packet. `jump` - jump to the user-defined chain specified by the value of the `jump-target` parameter. `log` - add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. After a packet is matched it is passed to the next rule in the list, similar to `passthrough`. `notrack` - skip connection tracking for the packet. `passthrough` - if a packet is matched by the rule, increase the counter and go to the next rule (useful for statistics). `return` - passes control back to the chain from where the jump took place. Name of the target chain to jump to. Applicable only if `action=jump`. Matches HTTPS traffic based on TLS SNI hostname. Accepts GLOB syntax for wildcard matching. The matcher will not be able to match the hostname if the TLS handshake frame is fragmented into multiple TCP segments. Interface the packet has entered the router. Interface the packet is leaving the router. Set of interfaces defined in interface list. Works the same as `in-interface`. Set of interfaces defined in interface list. Works the same as `out-interface`. Actual interface the packet has entered the router if the incoming interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Actual interface the packet leaves the router if the outgoing interface is a bridge. Works only if `use-ip-firewall` is enabled in bridge settings. Set of interfaces defined in interface list. Works the same as `in-bridge-port`. Set of interfaces defined in interface list. Works the same as `out-bridge-port`. Matches packets marked by the mangle facility with a particular packet mark. If `no-mark` is set, the rule will match any unmarked packet. List of source ports and ranges of source ports. Applicable only if the protocol is TCP or UDP. List of destination port numbers or port number ranges. Matches if any (source or destination) port matches the specified list of ports or port ranges. Applicable only if `protocol` is TCP or UDP. Matches ICMP type:code fields. Matches the source MAC address of the packet. Matches packets that contain the specified text. Matches the priority of an ingress packet. Priority may be derived from VLAN, WMM, DSCP, or MPLS EXP bit. Matches the packet's priority after a new priority has been set. Priority may be derived from VLAN, WMM, DSCP, MPLS EXP bit, or from the priority set by using the set-priority action. Matches the DSCP IP header field. Matches packets up to a limited rate (packet rate or bit rate). A rule with this matcher will match until this limit is reached. Parameters are written in the following format: `rate[/time],burst:mode`. - `rate` - packet or bit count per time interval to match. - `time` - specifies the time interval in which the packet or bit rate cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets or bits to match: this number gets recharged every 10ms so burst should be at least 1/100 of a rate per second. - `mode` - packet or bit mode. Matches packets until a given rate is exceeded. Rate is defined as packets per time interval. As opposed to the `limit` matcher, every flow has its own limit. Flow is defined by a mode parameter. Parameters are written in the following format: `rate[/time],burst,mode[/expire]`. - `rate` - packet count per time interval per-flow to match. - `time` - specifies the time interval in which the packet count rate per flow cannot be exceeded (optional, 1s will be used if not specified). - `burst` - initial number of packets per flow to match: this number gets recharged by one every time/rate, up to this number. - `mode` - specifies what unique fields define flow (src-address, dst-address, src-and-dst-address, dst-address-and-port, addresses-and-dst-port). - `expire` - specifies interval after which flow with no packets will be allowed to be deleted (optional). Creates a filter based on the packets' arrival time and date or, for locally generated packets, departure time and date. The matcher takes into account the time and timezone configured on the router. Matches packets randomly with a given probability. Matches every nth packet: `nth=2,1` will match every first packet of 2, hence, 50% of all the traffic matched by the rule. Matches the TCP MSS value of an IP packet. PCC matcher allows dividing traffic into equal streams with the ability to keep packets with a specific set of options in one particular stream. Matches packets of specified size or size range in bytes. Add a message to the system log containing the following data: in-interface, out-interface, src-mac, protocol, src-ip:port->dst-ip:port, and length of the packet. Allows logging of packets even if the action is not `log`, useful for debugging the firewall. Adds the specified text at the beginning of every log message. Applicable if `action=log` or `log=yes` is configured. Matches the policy used by IPsec. Value is written in the following format: `direction, policy`. - `in` - valid in the PREROUTING, INPUT, and FORWARD chains. - `out` - valid in the POSTROUTING, OUTPUT, and FORWARD chains. - `ipsec` - matches if the packet is subject to IPsec processing. - `none` - matches packets that are not subject to IPsec processing. Matches the particular IP protocol specified by protocol name or number. Matches packets whose source is equal to the specified IP or falls into the specified IP range. Matches packets whose destination is equal to the specified IP or falls into the specified IP range. Matches the source address of a packet against a user-defined address list. Supports only one list. Matches the destination address of a packet against a user-defined address list. Supports only one list. Name of the address list to be used. Applicable if the action is `add-dst-to-address-list` or `add-src-to-address-list`. Time interval after which the address will be removed from the address list specified by the `address-list` parameter. Used in conjunction with `add-dst-to-address-list` or `add-src-to-address-list` actions. `none-dynamic` (`00:00:00`) will leave the address in the address list till reboot. `none-static` will leave the address in the address list forever and will be included in the configuration export/backup. Matches the source address type: `unicast` - an IP address used for point-to-point transmission. `local` - the address is assigned to one of the router's interfaces. `anycast` - a packet sent to the nearest node in a group. `multicast` - a packet is forwarded to a defined group of devices. `unreachable` - the address is unreachable. Matches the destination address type: `unicast` - an IP address used for point-to-point transmission. `local` - the destination address is assigned to one of the router's interfaces. `anycast` - a packet sent to the nearest node in a group. `multicast` - a packet is forwarded to a defined group of devices. `unreachable` - the address is unreachable. Matches IPv6 next-header. Two types of header matching are possible controlled by the `mode` parameter: `contains` - soft matching, matches at least selected headers. `exact` - matches the exact set of selected headers. Matches the specified TCP flags: `ack` - acknowledging data. `cwr` - congestion window reduced. `ece` - ECN-echo flag (explicit congestion notification). `fin` - close connection. `psh` - push function. `rst` - reset connection. `syn` - new connection. `urg` - urgent data. Matches the hop limit field in the IPv6 header. Total amount of bytes matched by the rule. Total amount of packets matched by the rule. #### ipv6/firewall/raw/reset-counters **Type:** Command #### ipv6/firewall/raw/reset-counters-all **Type:** Command --- ## Nd import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ipv6/nd **Package:** ipv6 **Type:** Directory IPv6 Neighbor Discovery (ND) protocol is configured. disabled invalid default Interface on which to run neighbor discovery. -all - run ND on all running interfaces. Minimum and maximum interval allowed between unsolicited multicast router advertisements from the interface. Minimum time between multicast router advertisements from the interface. The MTU option in router advertisements ensures that all nodes on a link use the same MTU value when the link MTU is not well known. - **unspecified** - do not send the MTU option. Time that RouterOS assumes a neighbor is reachable after receiving a reachability confirmation. Used by Neighbor Unreachability Detection (see Section 7.3 of [RFC 4861](https://tools.ietf.org/html/rfc4861)). Time between retransmitted Neighbor Solicitation messages. Used by address resolution and Neighbor Unreachability Detection (see Sections 7.2 and 7.3 of [RFC 4861](https://tools.ietf.org/html/rfc4861)). Set the RA lifetime. A lifetime of 0 indicates that this router is not a default router. See Section 6.2.1 of [RFC 4861](https://tools.ietf.org/html/rfc4861). Specify the router preference communicated to IPv6 hosts in router advertisements. The `ra-preference` value helps hosts select a default router to reach a remote destination. Default value placed in the Hop Count field of the IPv6 header for outgoing unicast packets. When set, include the outgoing interface's link-layer address in router advertisements. Redistribute DNS server information using RADVD. - `no` - do not advertise DNS servers. - `yes` - advertise DNS servers installed on the router. - `self` - advertise the interface link-local address as the DNS service provider. Indicates whether hosts should use stateful autoconfiguration (DHCPv6) to obtain addresses. See [RFC 3315](https://tools.ietf.org/html/rfc3315). Indicates whether hosts should use stateful autoconfiguration to obtain additional information, excluding addresses. See [RFC 3315](https://tools.ietf.org/html/rfc3315). Specify one or more IPv6 addresses that hosts receive for DNS server configuration. Specify one or more IPv6 prefixes within /32, /40, /48, /56, /64, or /96 subnets that hosts receive as NAT64 prefixes. --- ## Prefix import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ipv6/nd/prefix **Package:** ipv6 **Type:** Directory Prefix information sent in router advertisement (RA) messages used for stateless address autoconfiguration ([RFC 4862](https://tools.ietf.org/html/rfc4862)). By default, autoconfiguration applies only to hosts and not routers. disabled invalid dynamic Prefix used for stateless address autoconfiguration. If the option "none" is selected, RouterOS advertises only options and does not include a specific prefix. If set, RouterOS combines this prefix with the interface IPv4 address to produce a valid 6to4 prefix. RouterOS replaces the first 16 bits with 2002 and the next 32 bits with the interface's configured IPv4 address. It advertises the remaining 80 bits, including the SLA ID, as configured. Interface on which stateless autoconfiguration runs. When set, indicates that RouterOS can treat this prefix as on-link. When not set, RA messages do not make any statement about the prefix's on-link or off-link status. The prefix might still be used for address configuration while some addresses in the prefix remain off-link. When set, indicates that RouterOS can use this prefix for autonomous address configuration. Otherwise, RouterOS ignores the prefix information. Indicates that clients should use DHCPv6 Prefix Delegation according to [RFC 9762](https://datatracker.ietf.org/doc/rfc9762/). Length of time after the packet is sent that an address remains valid. The valid lifetime must be greater than or equal to the preferred lifetime. [`Read more >>`](../../../getting-started/networking-fundamentals/ipv6-neighbor-discovery.md#address-states) Time after the packet is sent when the generated address becomes deprecated. A deprecated address is used only for existing connections and remains usable until the valid lifetime expires. [`Read more >>`](../../../getting-started/networking-fundamentals/ipv6-neighbor-discovery.md#address-states) #### ipv6/nd/prefix/default **Package:** ipv6 **Type:** Settings Directory --- ## Proxy(Nd) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ipv6/nd/proxy **Package:** ipv6 **Type:** Directory An IPv6 Neighbor Discovery Proxy allows a router or host to respond to Neighbor Discovery ([RFC 4861](https://tools.ietf.org/html/rfc4861)) messages on behalf of another node. This enables communication across different network segments as if they were on the same link. In RouterOS, the proxy can be enabled for a single IPv6 address and works per interface. disabled IPv6 address the proxy takes ownership of. Interface on which the proxy operates for this IPv6 address. --- ## Settings(Nd) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### ipv6/nd/settings **Package:** ipv6 **Type:** Settings Directory The IPv6 ND menu has a sub-menu "Settings" which allows changing global neighbor discovery settings. Specify the distance that must be used when installing SLAAC default route. Lets you ignore specific received ND options such as DNS and MTU. If RA will contain such options, they simply will be ignored if selected on this list. --- ## Neighbor(Ipv6) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ipv6/neighbor **Package:** ipv6 **Type:** Directory List of all discovered nodes by the IPv6 [Neighbor Discovery](https://tools.ietf.org/html/rfc4861) protocol, or nodes added manually by configuration. The default maximum number of neighbor entries depends on installed RAM. Adjust it with `/ipv6/settings/set max-neighbor-entries=x`. See [IPv6 Settings](./settings.md) for details. disabled dynamic router IPv6 address of the neighbor. Interface name to which this neighbor is attached. MAC address of the device to add. Status of the cached entry: - **noarp** - the neighbor entry is valid. RouterOS does not validate this entry, but it can be removed when its lifetime expires. - **incomplete** - address resolution is in progress and the neighbor's link-layer address is not yet determined. - **reachable** - the neighbor was reachable recently (within tens of seconds). - **stale** - the neighbor is no longer known to be reachable. Will continue sending traffic to the neighbor before attempting reachability verification. - **delay** - the neighbor is no longer known to be reachable, and traffic has recently been sent to the neighbor. RouterOS delays probes briefly to allow the upper-layer protocol to confirm reachability. - **probe** - the neighbor is no longer known to be reachable and unicast Neighbor Solicitation probes are being sent to verify reachability. - **failed** - RouterOS could not resolve the neighbor's MAC address using the Neighbor Discovery protocol. Indicates the VRF associated with this neighbor entry. --- ## Pool(Ipv6) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ipv6/pool **Package:** ipv6 **Type:** Directory IP pools are used to define ipv6 prefixes that can be used by various RouterOS utilities, for example, DHCP server, Point-to-Point servers and more. Whenever possible, the same IPv6 prefix is given out to each client (OWNER/INFO pair). dynamic inactive Name of the pool. Name of another pool from which to acquire prefix dynamically. The option represents the prefix size that will be given out to the client. ### ipv6/pool/used **Package:** ipv6 **Type:** Directory Name of the pool the prefix is reserved from. IPv6 prefix that is assigned to the client from the pool. What reserved the prefix ("DHCP", etc.) Shows DUID related information received from the client (value in hex). Can contain also a raw timestamp in hex. --- ## Route(Ipv6) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ipv6/route **Package:** ipv6 **Type:** Directory dynamic disabled inactive active connect static rip bgp ospf is-is dhcp vpn modem slaac bgp-mpls-vpn hw-offloaded ecmp --- ## Settings(Ipv6) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## ipv6/settings **Package:** ipv6 **Type:** Settings Directory This menu allows you to configure various IPv6-related kernel and system-wide network parameters. These settings control how the operating system handles IP traffic and network communications. :::note Changing IPv6 settings does not dynamically remove an existing SLAAC configuration, a router reboot is required. ::: Disable or enable IPv6 system-wide. When disabled, prevents link-local address generation. Enable or disable packet forwarding between interfaces. Specify the IPv6 hash policy for [ECMP](../../user-guides/routing-and-networking-protocols/routing-decision.md#multipath-ecmp-routes) routing: - l3 - Layer-3 hashing of source IP, destination IP, flow label, and IP protocol. - l3-inner - Layer-3 hashing or inner layer-3 hashing if available. - l4 - Layer-4 hashing of source IP, destination IP, IP protocol, source port, and destination port. Accept or reject ICMP redirect messages. Enable on hosts and disable on routers. Control acceptance of router advertisement (RA) messages. When enabled, the router obtains addresses using [stateless address configuration](../../system-information-and-utilities/neighbor-discovery.md#statelessaddressautoconfiguration). Specify which interfaces to listen for incoming router advertisements (RAs). Disable automatic link-local address generation for non-VPN interfaces. Use this when you need manually configured link-local addresses. Set the interval at which the system checks stale IPv6 neighbor entries and probes them to verify reachability. Timeout duration after which stale IPv6 neighbor entries are purged. Set the minimum number of IPv6 neighbor entries for which the device must allocate memory. Set the expected maximum number of IPv6 neighbor entries the system should handle. Set the maximum number of IPv6 neighbor entries. As of RouterOS version 7.1, the default value depends on installed RAM: - 1024 for 64 MiB - 2048 for 128 MiB - 4096 for 256 MiB - 8192 for 512 MiB - 16384 for 1024 MiB or higher Setting a value higher than the default increases the risk of out-of-memory conditions. Enable [Fast Path](../../firewall-and-quality-of-service/packet-flow-in-routeros#fast-path) for IPv6 traffic. Fasttrack and fastpath values are cumulative since the feature was last enabled or since the system restarted. Indicates whether the IPv6 fast path feature is currently active. Total number of packets that have been processed through the IPv6 fast path. Total number of bytes that have been processed through the IPv6 fast path. Indicates whether the IPv6 fasttrack feature is currently active. Total number of packets that have been processed through IPv6 fasttrack. Total number of bytes that have been processed through IPv6 fasttrack. --- ## lcd import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # lcd **Conditions:** !smips **Syscap:** lcd **Type:** Settings Directory ## lcd/backlight **Conditions:** !smips **Type:** Command ## lcd/interface **Conditions:** !smips **Type:** Directory default inactive disabled displayed default-wireless ### lcd/interface/default-wireless **Conditions:** !smips **Type:** Command ### lcd/interface/display **Conditions:** !smips **Type:** Command ### lcd/interface/pages **Conditions:** !smips **Type:** Directory default ## lcd/pin **Conditions:** !smips **Type:** Settings Directory ## lcd/recalibrate **Conditions:** !smips **Type:** Command ## lcd/screen **Conditions:** !smips **Type:** Directory default disabled ## lcd/show **Conditions:** !smips **Type:** Command ## lcd/take-screenshot **Conditions:** !smips **Type:** Command --- ## log import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # log **Type:** Directory --- ## Fwd import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## mpls/forwarding-table **Conditions:** !smips **Type:** Directory --- ## Iface import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## mpls/interface **Conditions:** !smips **Type:** Directory Configuration of MPLS MTU (path MTU + MPLS tag size) is useful in cases when there is a large variety of possible MTUs along the path. Configuring MPLS MTU to a minimum value that can pass all the hops will ensure that the MPLS packet will not be silently dropped on the devices that do not support a big enough MTU. ```ros [admin@rack1_b35_CCR1036] /mpls/interface> print Flags: X - disabled; * - builtin 0 ;;; router-test interface=ether1 mpls-mtu=1580 input=yes 1 ;;; router-test interface=ether2 mpls-mtu=1580 input=yes 2 interface=all mpls-mtu=1500 ``` If interface is not matched by any entry in the list, then mpls MTU will be equal to interface's L2MTU. :::info Listed entries are ordered, and the first entry (iterating from the top to the bottom) that matches the interface will be used. ::: The order of the entries is important due to the possibility that different interface lists can contain the same interface and in addition, that interface can be referenced directly. Selection of the MPLS MTU happens in the following manner: - If the interface matches the entry from this table, then try to use the configured MPLS MTU value. - If the interface does not match any entry then consider MPLS MTU equal to L2MTU. - If the interface does not support L2MTU, then consider MPLS MTU equal to L3 MTU. On the MPLS ingress path, MTU is chosen by min(MPLS MTU - tagsize, l3mtu). This means that on interfaces that do not support L2MTU and the default L3 MTU is set to 1500, max path MTU will be 1500 - tag size (the interface will not be able to pass a full IP frame without fragmentation). In such scenarios, L3MTU must be increased by the max observed tag size. Read more on MTUs in the [MTU in RouterOS](../../hardware/mtu-in-routeros.md) article. Name of the interface or interface-list to match. The option represents how big packets can be carried over the interface with added MPLS labels Whether to allow MPLS input on the interface. --- ## Ldp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## mpls/ldp **Conditions:** !smips **Type:** Directory disabled inactive Unique label switching router's ID. Max path vector limit used for loop detection. Works in combination with the `loop-detect` property. Max hop limit used for loop detection. Works in combination with the `loop-detect` property. Defines whether to run LSP loop detection. Will not work correctly if not enabled on all LSRs. Should be used only on non-TTL networks such as ATMs. Whether to distribute explicit-null label bindings. Defines whether to map label for the default route. Specifies LDP session connection origin addresses and also advertises these addresses as transport addresses to LDP neighbors. Name of the VRF table this instance will operate on. Determines supported address families by the instance. Determines which address family connection is preferred. Value is also set in dual-stack element (if used). ### mpls/ldp/accept-filter **Conditions:** !smips **Type:** Directory List of label bindings that should be accepted from LDP neighbors. disabled Prefix to match. Neighbor to which this filter applies. Whether to accept label bindings from the neighbors for the specified prefix. If parameter is unset then matching prefix is not accepted. ### mpls/ldp/advertise-filter **Conditions:** !smips **Type:** Directory disabled Prefix to match. Neighbor to which this filter applies. Whether to advertise label bindings to the neighbors for the specified prefix. If parameter is unset then matching prefix is not advertised. ### mpls/ldp/interface **Conditions:** !smips **Type:** Directory disabled Name of the interface or interface list where LDP will be listening. The interval between hello packets that the router sends out on the specified interface/s. The default value is 5s. Specifies the interval after which a neighbor discovered on the interface is declared as not reachable. The default value is 15s. Used transport addresses if they differ from LDP Instance settings. Defines whether to discover neighbors dynamically or use only statically configured in LDP neighbors menu. Determines interface address family. Only AFIs that are configured as supported by the instance are taken into account. If the value is not explicitly specified then it is considered to be equal to the instance-supported AFIs. ### mpls/ldp/local-mapping **Conditions:** !smips **Type:** Directory This sub-menu shows labels bound to the routes locally in the router. In this menu, static mappings can also be configured if there is no intention to use LDP dynamically. disabled Whether binding is active and can be selected as a candidate for forwarding. Whether the entry was dynamically added. egress Whether the destination is reachable through the gateway. Whether the destination is locally reachable on the router. vpls Name of the VRF table this mapping belongs to. Destination prefix the label is assigned to. Label number assigned to destination. IP address and label space of the peer to which this entry was advertised. ### mpls/ldp/neighbor **Conditions:** !smips **Type:** Directory List of discovered and statically configured LDP neighbors. disabled dynamic inactive Indicates whether the peer is operational. Indicates that active role has been selected and the router is trying to establish the session. Indicates whether the peer is in a passive role and currently is waiting for the session to be initialized. Indicates whether session is in throttled state. Session is throttled after initialization failure, max throttle time 120s. Whether targeted hellos are being sent to the neighbor. Whether neighbor is used by LDP signaled VPLS tunnel. Indicates whether the peer is in a passive role. Downstream On Demand label distribution. Remote transport address. Specifies whether to try to send targeted hellos, used for targeted (not directly connected) LDP sessions. LSR-ID and label space of the neighbor. Selected local transport address. List of discovered addresses on the neighbor. Downstream On Demand label distribution. Used transport AFI. ### mpls/ldp/remote-mapping **Conditions:** !smips **Type:** Directory The Sub-menu shows label bindings for routes received from other routers. Static mapping can be configured if there is no intention to use LDP dynamically. This table is used to build the Forwarding Table disabled Whether binding is active and can be selected as a candidate for forwarding. Whether entry was dynamically added. vpls Name of the VRF table this mapping belongs to. Destination prefix the label is assigned to. Label number assigned to destination. --- ## Mangle(Mpls) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## mpls/mangle **Type:** Directory disabled ### mpls/mangle/reset-counters **Type:** Command ### mpls/mangle/reset-counters-all **Type:** Command --- ## Rsvp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## mpls/traffic-eng **Conditions:** !smips **Type:** Directory ### mpls/traffic-eng/flow **Conditions:** !smips **Type:** Directory ### mpls/traffic-eng/interface **Conditions:** !smips **Type:** Directory ### mpls/traffic-eng/path **Conditions:** !smips **Type:** Directory ### mpls/traffic-eng/tunnel **Conditions:** !smips **Type:** Directory Ingress address of the tunnel. If not set, the least IP address is picked. Remote end of the TE tunnel. Primary label switching paths defined in the `/mpls/traffic-eng/path` menu. List of label switching paths used by the TE tunnel if the primary path fails. Paths are defined in the `/mpls/traffic-eng/path` menu. Interval after which the tunnel will try to use the primary path. Defines the actual bandwidth limitation of the TE tunnel. Limit is configured in percent of the specified tunnel `bandwidth`. Auto bandwidth adjustment range. Specifies the percentage of additional bandwidth to reserve. Interval in which the actual amount of data is measured, from which average bandwidth is calculated. Interval during which the tunnel keeps track of the highest average rate. The parameter is used to decide whether this session can preempt another session. 0 sets the highest priority. Used to decide whether this session can be preempted by another session. 0 sets the highest priority. If enabled, the sender node will receive information about the actual route that the LSP tunnel traverses. Record Route is analogous to a path vector, and hence can be used for loop detection. Use the interface only if `resource-class` matches all of the specified bits. Use the interface if `resource-class` matches any of specified bits. Do not use the interface if `resource-class` matches any of the specified bits. Interval after which the tunnel will re-optimize the current path. If the current path is not the best path then after optimization the best path will be used. #### mpls/traffic-eng/tunnel/reoptimize **Conditions:** !smips **Type:** Command --- ## Settings(Mpls) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## mpls/settings **Conditions:** !smips **Type:** Settings Directory Range of Label numbers used for dynamic allocation. The first 16 labels are reserved for special purposes (as defined in RFC). If you intend to configure labels statically then adjust the dynamic default range not to include numbers that will be used in a static configuration. Whether to copy TTL values from IP header to MPLS header. If this option is set to **no** then hops inside the MPLS cloud will be invisible to traceroutes. Enable/disable MPLS fast-path support. --- ## openflow import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # openflow **Package:** openflow **Type:** Directory ## openflow/flow **Package:** openflow **Type:** Directory ## openflow/group **Package:** openflow **Type:** Directory ## openflow/meter **Package:** openflow **Type:** Directory ## openflow/port **Package:** openflow **Type:** Directory --- ## partitions import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # partitions **Conditions:** !i386, !smips, !mmips **Syscap:** partitions **Type:** Directory active running ## partitions/activate **Conditions:** !i386, !smips, !mmips **Type:** Command ## partitions/copy-to **Conditions:** !i386, !smips, !mmips **Type:** Command ## partitions/repartition **Conditions:** !i386, !smips, !mmips **Type:** Command ## partitions/restore-config-from **Conditions:** !i386, !smips, !mmips **Type:** Command ## partitions/save-config-to **Conditions:** !i386, !smips, !mmips **Type:** Command --- ## password import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # password **Type:** Command --- ## port import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # port **Type:** Directory inactive ## port/remote-access **Type:** Directory disabled inactive active busy logging-active --- ## ppp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # ppp **Package:** ppp **Type:** Directory ## ppp/aaa **Package:** ppp **Type:** Settings Directory ## ppp/active **Package:** ppp **Type:** Directory radius ## ppp/l2tp-secret **Package:** ppp **Type:** Directory ## ppp/profile **Package:** ppp **Type:** Directory default ## ppp/secret **Package:** ppp **Type:** Directory disabled --- ## Interface(Queue) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## queue/interface **Type:** Directory --- ## Monitor import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## queue/monitor **Type:** Command --- ## Simple import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## queue/simple **Type:** Directory disabled invalid dynamic ### queue/simple/reset-counters **Type:** Command ### queue/simple/reset-counters-all **Type:** Command --- ## Tree import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## queue/tree **Type:** Directory disabled invalid ### queue/tree/reset-counters **Type:** Command ### queue/tree/reset-counters-all **Type:** Command --- ## Type import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## queue/type **Type:** Directory default --- ## quit import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # quit **Type:** Command --- ## radius(Cli-reference) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # radius **Type:** Directory disabled ## radius/incoming **Type:** Settings Directory ### radius/incoming/monitor **Type:** Command ### radius/incoming/reset-counters **Type:** Command ## radius/monitor **Type:** Command ## radius/reset-counters **Type:** Command --- ## redo import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # redo **Type:** Command --- ## Bfd import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/bfd **Conditions:** BFD_AUTHENTICATION **Type:** Directory ### routing/bfd/authentication **Conditions:** BFD_AUTHENTICATION **Type:** Directory disabled inactive transmit ### routing/bfd/configuration **Conditions:** BFD_AUTHENTICATION **Type:** Directory disabled inactive The Virtual Routing and Forwarding instance to which this configuration applies. list of interfaces where BFD configuration should be active. This config entry will only apply to BFD sessions established with these specific remote neighbors. Firewall address list name. BFD configuration will apply if remote IP address is contained within specified list. Desired transmit interval that the local router would like to use when sending BFD packets to the neighbor. Minimum receive interval that the local router requires between received BFD packets. This value is multiplied by the negotiated transmission interval to determine the **Hold Time**; if no packets within the Hold time are received - the neighbor is declared down. `Hold Time = negotiated interval × multiplier` if = **yes**: BFD sessions matching criteria will be prohibited. ### routing/bfd/session **Type:** Directory up inactive real-time frequency at which the device currently sends BFD control packets. --- ## Bgp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/bgp **Conditions:** !smips **Type:** Directory Name of the routing table, to install routes in. Overrides the instance parameter. Name of the VRF BGP connections operate on. By default uses the "main" routing table. List of template names that will be used to inherit parameter values from. Useful feature, to easily configure groups with overlapping configuration options. A 32-bit BGP autonomous system number. The value accepts AS-Plain or AS-Dot formats. Override the instance ASN and configure BGP confederation using the following format: _`confederation_as/as`_. For example, if your AS is 34 and your confederation AS is 43, set `as=43/34`. Affect outgoing **NEXT\_HOP** attribute selection. Next-hops set in filters always take precedence and are not changed on route reflection except when set in a filter. default - select the next-hop as described in [`RFC 4271`](https://tools.ietf.org/html/rfc4271) force-self - use the local address of the interface that connects to the peer as the next-hop propagate - propagate received next-hop; if the route has a BGP **NEXT\_HOP** attribute, use it as the next-hop; otherwise, fall back to the default case Enable when the remote peer is more than one hop away.This option affects outgoing next-hop selection as described in [`RFC 4271`](https://tools.ietf.org/html/rfc4271) (for eBGP only, excluding iBGP peers local to the confederation). It also affects:Whether to accept connections from peers not in the same network (the remote address of the connection is used for this check)Whether to accept incoming routes with a NEXT\_HOP attribute not in the same network as the address used to establish the connectionThe target scope of routes installed from this peer; routes from multi-hop or iBGP peers resolve their next-hops through IGP routes by default Specifies the BGP Hold Time value to be used when negotiating with peers.According to the BGP specification, if the router does not receive successive **KEEPALIVE** and/or **UPDATE** and/or **NOTIFICATION** messages within the period specified in the Hold Time field of the **OPEN** message, then the BGP connection to the peer will be closed.The minimal `hold-time` value of both peers will be used (note that the special value 0 or 'infinity' is lower than any other value)* infinity \- never expire the connection and never send keepalive messages. The interval between keepalive messages, if not set then by default keepalive is 1/3 of the `hold-time`. List of address families this peer can exchange routing information. The remote peer must support BGP capabilities optional parameter (they usually do) to negotiate any other address families than IP. VPLS NLRI length format type. Used for compatibility with Cisco VPLS. \[\[Read more>>\]\]. If set, then the BGP **AS-PATH** attribute is removed before sending out route updates if the attribute contains only private AS numbers.The removal process happens before routing filters are applied and before the local, AS number is prepended to the AS path. If set, then all instances of the remote peer's AS number in the BGP **AS-PATH** attribute are replaced with the local AS number before sending a route update to that peer. Happens before routing filters and prepend. Whether to use the BFD protocol for faster connection state detection. Filename to save BGP protocol-specific packet content (Exported PDU) into pcap format. This method allows much simpler peer-specific packet capturing for debugging purposes. Enable sending of additional paths for specified address families (BGP Addpath). Configure output multicore processing. Read more in [Routing Protocol Multi-core Support](../../user-guides/routing-and-networking-protocols/routing-protocol-multi-core-support.md) article. **alone** - input and output of each session is processed in its own process, the most likely best option when there are a lot of cores and a lot of peers **afi, instance, vrf, remote-as** - try to run input/output of new session in process with similar parameters **main** - run input/output in the main process (could potentially increase performance on single-core even possibly on multicore devices with small amount of cores) **input** - run output in the same process as input (can be set only for output affinity) Enable redistribution of specified route types. Name of the routing select chain to be used for prefix selection. If not specified, then default selection is used. Name of the routing filter chain to be used on the output prefixes. If the chain is not specified, then BGP by default accepts everything. Name of the address list used to send local networks. The network is sent only if a matching IGP route exists in the routing table and its **ORIGIN** attribute is set to IGP, other distribution methods have **ORIGIN** attribute set to INCOMPLETE. Specifies default route (0.0.0.0/0) distribution method. 'if-installed' option can be used to distribute default route only if corresponding IGP route present in the routing table. How many times to prepend local ASN. Disable client-to-client route reflection in Route Reflector setups. The early cut is the mechanism, to guess (based on default RFC behavior) what would happen with the sent NLRI when received by the remote peer. If the algorithm determines that the NLRI is going to be dropped, a peer will not even try to send it. However such behavior may not be desired in specific scenarios, then this option should be used to disable the early cut feature. Early cut works with eBGP sessions. Store in memory sent prefix attributes, required for `dump-saved-advertisements` command to work. By default, sent-out prefixes are not stored to preserve the router's memory. An option should be enabled only for debugging purposes when necessary to see currently advertised prefixes. Accept received additional paths (BGP Addpath) for specified address families. Configure input multi-core processing. Read more in [Routing Protocol Multi-core Support](../../user-guides/routing-and-networking-protocols/routing-protocol-multi-core-support.md) article. - **alone** - input and output of each session are processed in its own process, most likely the best option when there are a lot of cores and a lot of peers. - **afi, instance, vrf, remote-as** - try to run input/output of new session in process with similar parameters. - **main** - run input/output in the main process (could potentially increase performance on single-core even possibly on multi-core devices with a small amount of cores). Name of the routing filter chain to be used on input prefixes. This happens after NLRIs are processed. If the chain is not specified, then BGP by default accepts everything. Name of the filter chain that will filter incoming IPv4/IPv6 NLRIs directly before they are  stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session restart. Indicates how many times to allow your own AS number in AS-PATH, before discarding a prefix. Name of the ipv4/6 address-list. A quick way to filter incoming updates with specific NLRIs. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session restart. A quick way to filter incoming updates with specific communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific extended communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific large communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific extended communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific large communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific "unknown" attributes. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. Try to limit the amount of received IPv4 routes to the specified number. This number does not represent the exact number of routes going to be installed in the routing table by the peer. [BGP session "clear"](#routingbgpsessionclear) command must be used to reset the flag if the limit is reached. Try to limit the amount of received IPv6 routes to the specified number. This number does not represent the exact number of routes going to be installed in the routing table by the peer. BGP session "clear" command must be used to reset the flag if the limit is reached. ### routing/bgp/advertisements **Conditions:** !smips **Type:** Directory ### routing/bgp/connection **Conditions:** !smips **Type:** Directory A list of all connection-specific parameters can be seen in the table below. In addition to connection-specific parameters, template-specific parameters are also directly exposed in this menu, for easier configuration in simple scenarios (when templates are not necessary). dynamic disabled inactive Remote address used to connect and/or listen to. Remote AS number. If not specified BGP will determine remote AS automatically from the OPEN message. Acceptable minimum Time To Live, the hop limit for this TCP connection. For example, if 'ttl=255' then only single-hop neighbors will be able to establish the connection. This property only affects EBGP peers. Name of the num-list containing remote AS numbers that will be allowed to connect. Useful for dynamic peer configuration. Time To Live (hop limit) that will be recorded in sent TCP packets. BGP role. In most scenarios, set to iBGP or eBGP. For more information on BGP roles, see the corresponding [RFC 9234](https://tools.ietf.org/html/rfc9234). Key used to authenticate the connection with TCP MD5 signature as described in [RFC 2385](https://tools.ietf.org/html/rfc2385). Leave empty to disable authentication. Whether to allow the router to initiate the connection. Enable listening for incoming connections. If `remote.address` is a host address and listening is enabled, close the listening socket after the first successful accept. If `remote.address` is a subnet and listening is enabled, the listening socket remains open after the first successful accept with a hard-coded limit of 256 open connections. Name of the routing table, to install routes in. Overrides the instance parameter. Name of the VRF BGP connections operate on. By default uses the "main" routing table. List of template names that will be used to inherit parameter values from. Useful feature, to easily configure groups with overlapping configuration options. A 32-bit BGP autonomous system number. The value accepts AS-Plain or AS-Dot formats. Override the instance ASN and configure BGP confederation using the following format: _`confederation_as/as`_. For example, if your AS is 34 and your confederation AS is 43, set `as=43/34`. Affect outgoing **NEXT\_HOP** attribute selection. Next-hops set in filters always take precedence and are not changed on route reflection except when set in a filter. default - select the next-hop as described in [`RFC 4271`](https://tools.ietf.org/html/rfc4271) force-self - use the local address of the interface that connects to the peer as the next-hop propagate - propagate received next-hop; if the route has a BGP **NEXT\_HOP** attribute, use it as the next-hop; otherwise, fall back to the default case Enable when the remote peer is more than one hop away.This option affects outgoing next-hop selection as described in [`RFC 4271`](https://tools.ietf.org/html/rfc4271) (for eBGP only, excluding iBGP peers local to the confederation). It also affects:Whether to accept connections from peers not in the same network (the remote address of the connection is used for this check)Whether to accept incoming routes with a NEXT\_HOP attribute not in the same network as the address used to establish the connectionThe target scope of routes installed from this peer; routes from multi-hop or iBGP peers resolve their next-hops through IGP routes by default Specifies the BGP Hold Time value to be used when negotiating with peers.According to the BGP specification, if the router does not receive successive **KEEPALIVE** and/or **UPDATE** and/or **NOTIFICATION** messages within the period specified in the Hold Time field of the **OPEN** message, then the BGP connection to the peer will be closed.The minimal `hold-time` value of both peers will be used (note that the special value 0 or 'infinity' is lower than any other value)* infinity \- never expire the connection and never send keepalive messages. The interval between keepalive messages, if not set then by default keepalive is 1/3 of the `hold-time`. List of address families this peer can exchange routing information. The remote peer must support BGP capabilities optional parameter (they usually do) to negotiate any other address families than IP. VPLS NLRI length format type. Used for compatibility with Cisco VPLS. \[\[Read more>>\]\]. If set, then the BGP **AS-PATH** attribute is removed before sending out route updates if the attribute contains only private AS numbers.The removal process happens before routing filters are applied and before the local, AS number is prepended to the AS path. If set, then all instances of the remote peer's AS number in the BGP **AS-PATH** attribute are replaced with the local AS number before sending a route update to that peer. Happens before routing filters and prepend. Whether to use the BFD protocol for faster connection state detection. Filename to save BGP protocol-specific packet content (Exported PDU) into pcap format. This method allows much simpler peer-specific packet capturing for debugging purposes. Enable sending of additional paths for specified address families (BGP Addpath). Configure output multicore processing. Read more in [Routing Protocol Multi-core Support](../../user-guides/routing-and-networking-protocols/routing-protocol-multi-core-support.md) article. **alone** - input and output of each session is processed in its own process, the most likely best option when there are a lot of cores and a lot of peers **afi, instance, vrf, remote-as** - try to run input/output of new session in process with similar parameters **main** - run input/output in the main process (could potentially increase performance on single-core even possibly on multicore devices with small amount of cores) **input** - run output in the same process as input (can be set only for output affinity) Enable redistribution of specified route types. Name of the routing select chain to be used for prefix selection. If not specified, then default selection is used. Name of the routing filter chain to be used on the output prefixes. If the chain is not specified, then BGP by default accepts everything. Name of the address list used to send local networks. The network is sent only if a matching IGP route exists in the routing table and its **ORIGIN** attribute is set to IGP, other distribution methods have **ORIGIN** attribute set to INCOMPLETE. Specifies default route (0.0.0.0/0) distribution method. 'if-installed' option can be used to distribute default route only if corresponding IGP route present in the routing table. How many times to prepend local ASN. Disable client-to-client route reflection in Route Reflector setups. The early cut is the mechanism, to guess (based on default RFC behavior) what would happen with the sent NLRI when received by the remote peer. If the algorithm determines that the NLRI is going to be dropped, a peer will not even try to send it. However such behavior may not be desired in specific scenarios, then this option should be used to disable the early cut feature. Early cut works with eBGP sessions. Store in memory sent prefix attributes, required for `dump-saved-advertisements` command to work. By default, sent-out prefixes are not stored to preserve the router's memory. An option should be enabled only for debugging purposes when necessary to see currently advertised prefixes. Accept received additional paths (BGP Addpath) for specified address families. Configure input multi-core processing. Read more in [Routing Protocol Multi-core Support](../../user-guides/routing-and-networking-protocols/routing-protocol-multi-core-support.md) article. - **alone** - input and output of each session are processed in its own process, most likely the best option when there are a lot of cores and a lot of peers. - **afi, instance, vrf, remote-as** - try to run input/output of new session in process with similar parameters. - **main** - run input/output in the main process (could potentially increase performance on single-core even possibly on multi-core devices with a small amount of cores). Name of the routing filter chain to be used on input prefixes. This happens after NLRIs are processed. If the chain is not specified, then BGP by default accepts everything. Name of the filter chain that will filter incoming IPv4/IPv6 NLRIs directly before they are  stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session restart. Indicates how many times to allow your own AS number in AS-PATH, before discarding a prefix. Name of the ipv4/6 address-list. A quick way to filter incoming updates with specific NLRIs. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session restart. A quick way to filter incoming updates with specific communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific extended communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific large communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific extended communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific large communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific "unknown" attributes. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. Try to limit the amount of received IPv4 routes to the specified number. This number does not represent the exact number of routes going to be installed in the routing table by the peer. [BGP session "clear"](#routingbgpsessionclear) command must be used to reset the flag if the limit is reached. Try to limit the amount of received IPv6 routes to the specified number. This number does not represent the exact number of routes going to be installed in the routing table by the peer. BGP session "clear" command must be used to reset the flag if the limit is reached. ### routing/bgp/evpn **Conditions:** !smips **Type:** Directory See EVPN documentation. disabled BGP instance this EVPN is assigned to. Name of the VRF table that this EVPN instance will use. Specifies the value that gets attached to route so that receiving routers can distinguish advertisements that may otherwise look the same. Used to distinguish between tenants using overlapping IP ranges. Also can be used to simplify convergence and redundancy within Virtual Network. RDs from MLAG pairs should be unique, too. Range of Virtual Network Identifiers. List of route targets that will be used to import EVPN routes. List of route targets that will be added to EVPN routes when exporting. ### routing/bgp/instance **Conditions:** !smips **Type:** Directory disabled inactive Name of the routing table, to install routes in. Name of the VRF BGP connections operate on. By default always uses the "main" routing table. BGP Router ID to be used. Use the ID from the `/routing/router-id` configuration by specifying the reference name, or set the ID directly by specifying IP.Equal router-ids are also used to group peers into one instance. 32-bit BGP autonomous system number. Enter the value in AS-Plain or AS-Dot formats. Configure BGP confederation using the following format: _`confederation_as/as`_. For example, if your AS is 34 and your confederation AS is 43, set `as=43/34`. For route reflector instances, specify the cluster ID of the route reflector cluster. This attribute identifies routing updates from other route reflectors in the cluster to avoid routing information loops. Typically, only one route reflector exists per cluster; in this case, do not configure 'cluster-id' and BGP router ID is used instead. Ignore the **AS_PATH** attribute in the BGP route selection algorithm. Applies to input. Install the specified number of ECMP routes received by add-path or selected by [best path selection](../../user-guides/routing-and-networking-protocols/unicast/bgp/understanding-bgp.md#best-path-selection). ### routing/bgp/session **Conditions:** !smips **Type:** Directory List of BGP already established, not yet connected or disconnected sessions. established Remote peer's advertised/supported capabilities. Remote peer's advertised/supported address families. Number of BGP messages received from remote peer. Total number of bytes received from remote peer. List of address families that received end-of-rib from remote peer. Content of last sent notification message. Shows which routing process the session is tied to. Content of last received notification message. Indicates if the session is iBGP. Indicates if the session is eBGP. Indicates if received prefix count exceeds configured prefix limit by `input.limit-process-routes-ipv4` and/or `input.limit-process-routes-ipv6`. Indicates whether session is administratively stopped. Uptime of established session. #### routing/bgp/session/clear **Conditions:** !smips **Type:** Command Clear the session flags. For example, to be able to re-establish a session after the prefix limit is reached "limit-exceeded" flag must be cleared. It can be done by specifying `flag` parameter, which is able to take the following values: * input-last-notification   * limit-exceeded   * output-last-notification   * refused-cap-opt   * stopped A flag to be cleared from BGP session. #### routing/bgp/session/dump-saved-advertisements **Conditions:** !smips **Type:** Command Dump saved advertisements from specified BGP session in the \*.pcap file. The filename where to store the PCAP data. #### routing/bgp/session/refresh **Conditions:** !smips **Type:** Command Send route refresh to a specified BGP session. Is used to trigger re-sending all the routes from the remote peer. Specifies for which address family to send route refresh. #### routing/bgp/session/resend **Conditions:** !smips **Type:** Command Resend prefixes to a specified BGP session. The command takes two arguments: Specifies for which address families to resend prefixes. The name of the pcap file where to dump resent messages, can be used for debugging purposes. #### routing/bgp/session/stop **Conditions:** !smips **Type:** Command ### routing/bgp/template **Conditions:** !smips **Type:** Directory default disabled inactive Name of the routing table, to install routes in. Overrides the instance parameter. Name of the VRF BGP connections operate on. By default uses the "main" routing table. List of template names that will be used to inherit parameter values from. Useful feature, to easily configure groups with overlapping configuration options. A 32-bit BGP autonomous system number. The value accepts AS-Plain or AS-Dot formats. Override the instance ASN and configure BGP confederation using the following format: _`confederation_as/as`_. For example, if your AS is 34 and your confederation AS is 43, set `as=43/34`. Affect outgoing **NEXT\_HOP** attribute selection. Next-hops set in filters always take precedence and are not changed on route reflection except when set in a filter. default - select the next-hop as described in [`RFC 4271`](https://tools.ietf.org/html/rfc4271) force-self - use the local address of the interface that connects to the peer as the next-hop propagate - propagate received next-hop; if the route has a BGP **NEXT\_HOP** attribute, use it as the next-hop; otherwise, fall back to the default case Enable when the remote peer is more than one hop away.This option affects outgoing next-hop selection as described in [`RFC 4271`](https://tools.ietf.org/html/rfc4271) (for eBGP only, excluding iBGP peers local to the confederation). It also affects:Whether to accept connections from peers not in the same network (the remote address of the connection is used for this check)Whether to accept incoming routes with a NEXT\_HOP attribute not in the same network as the address used to establish the connectionThe target scope of routes installed from this peer; routes from multi-hop or iBGP peers resolve their next-hops through IGP routes by default Specifies the BGP Hold Time value to be used when negotiating with peers.According to the BGP specification, if the router does not receive successive **KEEPALIVE** and/or **UPDATE** and/or **NOTIFICATION** messages within the period specified in the Hold Time field of the **OPEN** message, then the BGP connection to the peer will be closed.The minimal `hold-time` value of both peers will be used (note that the special value 0 or 'infinity' is lower than any other value)* infinity \- never expire the connection and never send keepalive messages. The interval between keepalive messages, if not set then by default keepalive is 1/3 of the `hold-time`. List of address families this peer can exchange routing information. The remote peer must support BGP capabilities optional parameter (they usually do) to negotiate any other address families than IP. VPLS NLRI length format type. Used for compatibility with Cisco VPLS. \[\[Read more>>\]\]. If set, then the BGP **AS-PATH** attribute is removed before sending out route updates if the attribute contains only private AS numbers.The removal process happens before routing filters are applied and before the local, AS number is prepended to the AS path. If set, then all instances of the remote peer's AS number in the BGP **AS-PATH** attribute are replaced with the local AS number before sending a route update to that peer. Happens before routing filters and prepend. Whether to use the BFD protocol for faster connection state detection. Filename to save BGP protocol-specific packet content (Exported PDU) into pcap format. This method allows much simpler peer-specific packet capturing for debugging purposes. Enable sending of additional paths for specified address families (BGP Addpath). Configure output multicore processing. Read more in [Routing Protocol Multi-core Support](../../user-guides/routing-and-networking-protocols/routing-protocol-multi-core-support.md) article. **alone** - input and output of each session is processed in its own process, the most likely best option when there are a lot of cores and a lot of peers **afi, instance, vrf, remote-as** - try to run input/output of new session in process with similar parameters **main** - run input/output in the main process (could potentially increase performance on single-core even possibly on multicore devices with small amount of cores) **input** - run output in the same process as input (can be set only for output affinity) Enable redistribution of specified route types. Name of the routing select chain to be used for prefix selection. If not specified, then default selection is used. Name of the routing filter chain to be used on the output prefixes. If the chain is not specified, then BGP by default accepts everything. Name of the address list used to send local networks. The network is sent only if a matching IGP route exists in the routing table and its **ORIGIN** attribute is set to IGP, other distribution methods have **ORIGIN** attribute set to INCOMPLETE. Specifies default route (0.0.0.0/0) distribution method. 'if-installed' option can be used to distribute default route only if corresponding IGP route present in the routing table. How many times to prepend local ASN. Disable client-to-client route reflection in Route Reflector setups. The early cut is the mechanism, to guess (based on default RFC behavior) what would happen with the sent NLRI when received by the remote peer. If the algorithm determines that the NLRI is going to be dropped, a peer will not even try to send it. However such behavior may not be desired in specific scenarios, then this option should be used to disable the early cut feature. Early cut works with eBGP sessions. Store in memory sent prefix attributes, required for `dump-saved-advertisements` command to work. By default, sent-out prefixes are not stored to preserve the router's memory. An option should be enabled only for debugging purposes when necessary to see currently advertised prefixes. Accept received additional paths (BGP Addpath) for specified address families. Configure input multi-core processing. Read more in [Routing Protocol Multi-core Support](../../user-guides/routing-and-networking-protocols/routing-protocol-multi-core-support.md) article. - **alone** - input and output of each session are processed in its own process, most likely the best option when there are a lot of cores and a lot of peers. - **afi, instance, vrf, remote-as** - try to run input/output of new session in process with similar parameters. - **main** - run input/output in the main process (could potentially increase performance on single-core even possibly on multi-core devices with a small amount of cores). Name of the routing filter chain to be used on input prefixes. This happens after NLRIs are processed. If the chain is not specified, then BGP by default accepts everything. Name of the filter chain that will filter incoming IPv4/IPv6 NLRIs directly before they are  stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session restart. Indicates how many times to allow your own AS number in AS-PATH, before discarding a prefix. Name of the ipv4/6 address-list. A quick way to filter incoming updates with specific NLRIs. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session restart. A quick way to filter incoming updates with specific communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific extended communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific large communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific extended communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific large communities. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. A quick way to filter incoming updates with specific "unknown" attributes. It allows filtering incoming messages directly before they are even parsed and stored in memory, that way significantly reducing memory usage. Regular input filter chain can only reject prefixes which means that it will still eat memory and will be visible in /routing route table as "not active, filtered". Changes to be applied required session refresh. Try to limit the amount of received IPv4 routes to the specified number. This number does not represent the exact number of routes going to be installed in the routing table by the peer. [BGP session "clear"](#routingbgpsessionclear) command must be used to reset the flag if the limit is reached. Try to limit the amount of received IPv6 routes to the specified number. This number does not represent the exact number of routes going to be installed in the routing table by the peer. BGP session "clear" command must be used to reset the flag if the limit is reached. ### routing/bgp/vpls **Conditions:** !smips **Type:** Directory This menu lists all the configured BGP-based VPLS instances. These instances allow the router to advertise VPLS BGP NLRI and indicate that the router belongs to a specific customer VPLS network. MP-BGP-based autodiscovery and signaling (RFC 4761). Cisco VPLS BGP-based auto-discovery (draft-ietf-l2vpn-signaling-08). Support for multiple import/export route target extended communities for BGP-based VPLS (both, RFC 4761 and draft-ietf-l2vpn-signaling-08). disabled inactive Specifies the value that gets attached to VPLS NLRI so that receiving routers can distinguish advertisements that may otherwise look the same. This implies that a unique route-distinguisher for every VPLS must be used. It is not necessary to use the same route distinguisher for some VPLS on all routers forming that VPLS as distinguisher is not used for determining if some BGP NLRI is related to a particular VPLS (Route Target attribute is used for this), but it is mandatory to have different distinguishers for different VPLSes. Accepts 3 types of formats. [Read more>>](../../user-guides/routing-and-networking-protocols/route-distinguisher-and-route-target.md) Unique site identifier. Each site must have a unique site-id. A parameter must be set for RFC 4761 style VPLS signaling. Unique identifier. A parameter must be set for cisco-style VPLS signaling. In most cases this should not be used, any modern software supports RFC 4761 style signaling (see site-id parameter). Parameter is a merge of l2-router-id and RD, for example: 10.155.155.1&6550:123 The setting is used to determine if BGP NLRI is related to a particular VPLS, by comparing route targets received from BGP NLRI. The setting is used to tag BGP NLRI with one or more route targets which on the remote side is used by `import-route-targets`. Pseudowire type (RFC 4447 Section 5.2). By default, `raw-ethernet` is used. L2MTU value advertised to a remote peer (RFC 4447 Section 5.2). Enables or disables Control Word usage (RFC 4623 Section 4). Default values for regular and Cisco-style VPLS tunnels differ. Cisco-style by default has Control Word usage disabled. Read more in the [VPLS Control Word](../../user-guides/routing-and-networking-protocols/mpls/vpls/control-word.md) article. [Bridge](../interface/bridge.md) the VPLS interface belongs to. Cost of the [bridge port](../interface/bridge.md#path-cost). When set to `none`, [bridge horizon](../interface/bridge.md#horizon) is not used. Port VLAN ID (pvid) assigned to a dynamically bridged interface. Applies only when [bridge `vlan-filtering`](../interface/bridge.md#vlan-filtering) is set to `yes`. ### routing/bgp/vpn **Conditions:** !smips **Type:** Directory L3VPN VPNv4/VPNv6 instance configuration disabled inactive Name of the instance this VPN is assigned to. Specifies the value that gets attached to route so that receiving routers can distinguish advertisements that may otherwise look the same. Used to distinguish between tenants using overlapping IP ranges. Also can be used to simplify convergence and redundancy within Virtual Network. RDs from MLAG pairs should be unique, too. Name of the VRF table that this VPN instance will use. List of route targets that will be used to import VPNv4 routes. The accepted RT format is similar to the one for Route Distinguishers. List of route targets added when exporting VPNv4 routes. The accepted RT format is similar to the one for Route Distinguishers. The name of the `routing/filter/select-chain` that is used to select prefixes to be exported. The name of the `routing/filter/chain` that is used to filter prefixes before exporting. Enable redistribution of specified route types from a VRF to VPNv4. --- ## Discourse import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/discourse **Type:** Command --- ## Fantasy import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/fantasy **Type:** Directory Fantasy menu is a fancy way to generate large amount of routes for testing purposes. Main benefits of this approach compared to a script are the generation speed and simplicity. It is easy to remove all fantasy generated routes just by disabling the fantasy rule. Fantasy uses a random generator from hashed route sequence number, seed and other parameters. disabled invalid Prefix from which route will be generated. Prefix length for generated route (can be specified as integer range). For example `dst-address=192.168.0.0/16` and `prefix-length=24` will generate /24 routes from `192.168.0.0/16` subnet. Scope to be set; can be set as range. Target scope to be set; can be set as range. Random generator seed. Route sequence number offset. --- ## Filter(Routing) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/filter **Type:** Directory ### routing/filter/chain **Type:** Directory Dynamic list of filter rule chains that can be referenced in BGP/OSPF or other routing protocol configuration. inactive dynamic ### routing/filter/community-ext-list **Type:** Directory disabled Reference name. List of extended communities expressed as a **raw** integer value or in the typed format: `type:value`, where type can be: - `rt` - route-target - `soo` - site of origin. The value depends on the type. Regexp matcher to match communities. The community set with only the regexp parameter cannot be used to append/delete communities. ### routing/filter/community-large-list **Type:** Directory disabled Reference name. List of large communities expressed in the following format: `admin:value1:value2`, where each section can be an integer [0..4294967295]. Regexp matcher to match communities. The community set with only the regexp parameter cannot be used to append/delete communities. ### routing/filter/community-list **Type:** Directory disabled Reference name. List of communities expressed either as a **well-known** name or in the following format: `as:number`, where each section can be integer [0..65535]. Accepted **well-known** names: - `accept-own` - `graceful-shutdown` - `no-advertise` - `no-llgr` - `route-filter-6` - `accept-own-nh` - `internet` - `no-export` - `no-peer` - `route-filter-xlate-4` - `blackhole` - `llgr-stale` - `local-as` - `route-filter-4` - `route-filter-xlate-6` Regexp matcher to match communities. The community set with only the regexp parameter cannot be used to append/delete communities. ### routing/filter/filter-wizard **Type:** Command returns true if provided chain did not reject name of the routing table the route was imported from address family of the route protocol type from which the route was imported returns true if prefix is locally originated, e.g BGP network matches blackhole routes RPKI validation status of the prefix matches BGP Origin attribute regexp that matches BGP AS-Path attribute, see documentation for more details set a value of the BGP Local-Pref attribute set gateway check set a value of the BGP Communities attribute Enable RPKI verification in the current chain from specified RPKI group ### routing/filter/num-list **Type:** Directory disabled ### routing/filter/rule **Type:** Directory disabled inactive ### routing/filter/select-rule **Type:** Directory disabled invalid ### routing/filter/sync **Type:** Command ### routing/filter/test-as-path-regexp **Type:** Command --- ## Gmp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/gmp **Type:** Directory disabled Name of the interface, multiple interfaces and interface lists are supported. The multicast group address to be used by the interface, multiple group addresses are supported. When `exclude` is set, the interface expects to reject multicast data from the configured `sources`. When this option is not used, the interfaces will emit source specific join for the configured `sources`. The source address list used by the interface, multiple source addresses are supported. This setting has an effect when IGMPv3 or MLDv2 protocols are active. --- ## NAME DYNAMIC-ID SELECT-D SELE import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/id **Type:** Directory Global Router ID election configuration. The Router ID can be configured explicitly or elected from one of the router's IP addresses. For each VRF table, RouterOS adds a dynamic ID instance that elects the Router ID from one of the IP addresses in that VRF: ```text [admin@rack1_b33_CCR1036] /routing/id> print Flags: D - DYNAMIC, I - INACTIVE Columns: NAME, DYNAMIC-ID, SELECT-DYNAMIC-ID, SELECT-FROM-VRF # NAME DYNAMIC-ID SELECT-D SELE 0 D main 111.111.111.2 only-vrf main ``` disabled dynamic If there was a problem getting a valid ID, then the item can become inactive. Router ID to set explicitly. If the Router ID is not set, RouterOS can elect it from one of the configured IP addresses. See `select-dynamic-id` and `select-from-vrf`. Select which IP addresses RouterOS uses for Router ID election: - `any` - any address found on the router can be elected as the Router ID. - `lowest` - select the lowest IP address. - `only-static` - pick only statically configured addresses. - `only-active` - select an ID only from active IP addresses. - `only-loopback` - select an ID only from loopback addresses (loopback address is any non-point-to-point /32 address). - `only-vrf` - select an ID only from the selected VRF. Works with `select-from-vrf`. VRF from which to select IP addresses for the ID election. Currently selected ID. --- ## Igmp Proxy import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/igmp-proxy **Type:** Settings Directory Specifies the action on IGMP Leave message. If quick-leave is on, then an IGMP Leave message is sent upstream as soon as a leave message is received from the first client on the downstream interface. Use `yes` only in case there is only one subscriber behind the proxy. How often to send out IGMP Query messages over downstream interfaces. How long to wait for responses to an IGMP Query message. ### routing/igmp-proxy/interface **Type:** Directory Configure what interfaces will participate as IGMP proxy interfaces on the router. If an interface is not configured as an IGMP proxy interface, then all IGMP traffic received on it will be ignored. It is possible to get detailed status information for each interface using the `print status` command. ```ros [admin@MikroTik] /routing/igmp-proxy/interface/print status Flags: X - disabled, I - inactive, D - dynamic; U - upstream 0 U interface=ether2 threshold=1 alternative-subnets="" upstream=yes source-ip-address=192.168.10.10 rx-bytes=3018487500 rx-packets=2012325 tx-bytes=0 tx-packets=0 1 interface=ether3 threshold=1 alternative-subnets="" upstream=no querier=yes source-ip-address=192.168.20.10 rx-bytes=0 rx-packets=0 tx-bytes=2973486000 tx-packets=1982324 2 interface=ether4 threshold=1 alternative-subnets="" upstream=no querier=yes source-ip-address=192.168.30.10 rx-bytes=0 rx-packets=0 tx-bytes=152019000 tx-packets=101346 ``` disabled inactive dynamic upstream Name of the interface. Minimal TTL. Packets received with a lower TTL value are ignored By default, only packets from directly attached subnets are accepted. This parameter can be used to specify a list of alternative valid packet source subnets, both for data and IGMP packets. Has an effect only on the upstream interface. Should be used when the source of multicast data often is in a different IP network. The interface is called "upstream" if it's in the direction of the root of the multicast tree. An IGMP forwarding router must have exactly one upstream interface configured. The upstream interface is used to send out IGMP membership requests. Whether the interface is acting as an IGMP querier. The detected source IP for the interface. The total amount of received multicast traffic on the interface. The total amount of received multicast packets on the interface. The total amount of transmitted multicast traffic on the interface. The total amount of transmitted multicast packets on the interface. ### routing/igmp-proxy/mfc **Type:** Directory Multicast forwarding cache (MFC) status. RouterOS supports static multicast forwarding rules for IGMP proxy. If a static rule is added, all dynamic rules for that group will be ignored. These rules will take effect only if IGMP-proxy interfaces are configured (upstream and downstream interfaces should be set) otherwise these rules won't be active. disabled active dynamic The multicast group address this rule applies to. The multicast data originator address. The interface that is receiving stream data. The received stream will be sent out to the listed interfaces only. The packet stream is going out of the router through this interface. The total amount of received multicast traffic. The total amount of received multicast packets. The total amount of received multicast packets that arrived on a wrong interface, for example, a multicast stream that is received on a downstream interface instead of an upstream interface. --- ## Isis import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/isis **Type:** Directory ### routing/isis/instance **Type:** Directory disabled inactive ### routing/isis/interface **Type:** Directory dynamic ### routing/isis/interface-template **Type:** Directory disabled inactive ### routing/isis/lsp **Type:** Directory inactive dynamic ### routing/isis/neighbor **Type:** Directory dynamic --- ## Nexthop import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/nexthop **Type:** Directory unresolved reachable ### routing/nexthop/dump-dot **Type:** Command --- ## Ospf import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/ospf **Type:** Directory ### routing/ospf/area **Type:** Directory disabled inactive dynamic transit-capable The name of the area Name of the OSPF instance this area belongs to. OSPF area identifier. If the router has networks in more than one area, then an area with `area-id=0.0.0.0` (the backbone) must always be present. The backbone always contains all area border routers. The backbone is responsible for distributing routing information between non-backbone areas. The backbone must be contiguous, i.e. there must be no disconnected segments. However, area border routers do not need to be physically connected to the backbone - connection to it may be simulated using a virtual link. The area type. Read more on the area types in the [OSPF user guides](../../user-guides/routing-and-networking-protocols/unicast/ospf/index.md#understanding-ospf-areas). Flag parameter, if set then the area will not flood summary LSAs in the stub area. Default cost of injected LSAs into the area. If the value is not set, then stub area type-3 default LSA will not be originated. The parameter indicates which ABR will be used as a translator from `type-7` to `type-5` LSA. Applicable only if area type is NSSA. - yes - the router will be always used as a translator. - no - the router will never be used as a translator. - candidate - OSPF elects one of the candidate routers to be a translator. #### routing/ospf/area/range **Type:** Directory disabled inactive advertise The OSPF area associated with this range. The network prefix of this range. Whether to create a summary LSA and advertise it to the adjacent areas. The cost of the summary LSA this range will create. Default - use the largest cost of all routes used (i.e. routes that fall within this range). ### routing/ospf/instance **Type:** Directory disabled inactive OSPF version this instance will be running (v2 for IPv4, v3 for IPv6). The VRF table this OSPF instance operates on. OSPF Router ID. Can be set explicitly as an IP address, or as the name of the router-id instance. Name of the routing filter select chain, used for output selection. Output operates only with **external** routes. Specifies the default route (`0.0.0.0/0`) distribution method. Name of the [routing filter](../../user-guides/routing-and-networking-protocols/route-selection-and-filtering.md#route-filtering) chain used for incoming prefixes. The area used for MPLS traffic engineering. TE Opaque LSAs are generated in this area. No more than one OSPF instance can have `mpls-te-area` configured. MPLS-related parameter. Identifies the OSPF domain of the instance. This value is attached to OSPF routes redistributed in BGP as VPNv4 routes as a BGP extended community attribute and used when BGP VPNv4 routes are redistributed back to OSPF to determine whether to generate an `inter-area` or `AS-external` LSA for that route. By default Null domain-id is used, as described in [RFC 4577](https://tools.ietf.org/html/rfc4577). If set, then used in route redistribution (as route-tag in all external LSAs generated by this router), and in route calculation (all external LSAs having this route tag are ignored). Needed for interoperability with older Cisco systems. By default not set. Forces use or ignoring of the DN bit. Useful in some CE-PE scenarios to inject `intra-area` routes into VRF. If a parameter is unset, then the DN bit is used according to RFC. Enable redistribution of specific route types. ### routing/ospf/interface **Type:** Directory dynamic disabled The OSPF network type on this interface. Note that if interface configuration does not exist, the default network type is 'ptp' on PtP interfaces and 'broadcast' on all other interfaces. - `broadcast` - Network type suitable for Ethernet and other multicast capable link layers. Elects designated router. - `nbma` - Non-Broadcast Multiple Access. Protocol packets are sent to each neighbor's unicast address. Requires manual configuration of neighbors. Elects designated router. - `ptp` - Suitable for networks that consist only of two nodes. Does not elect a designated router. - `ptmp` - Point-to-Multipoint. Easier to configure than NBMA because it requires no manual configuration of a neighbor. Does not elect a designated router. This is the most robust network type and as such suitable for wireless networks, if 'broadcast' mode does not work well enough for them - `ptp-unnumbered` - Works the same as ptp, except that the remote neighbor does not have an associated IP address to a specific PTP interface. For example, in case IP unnumbered is used on Cisco devices. - `virtual-link` - Interface for virtual link. A non-backbone area the two routers have in common over which the virtual link will be established. Virtual links can not be established through stub areas. Specifies the **router-id** of the neighbor which should be connected over the virtual link. ### routing/ospf/interface-template **Type:** Directory The interface template defines common network and interface matches and what parameters to assign to a matched interface. disabled inactive The OSPF area to which the matching interface will be associated. Matcher. Interfaces to match. Accepts specific interface names or the name of the interface list. Matcher. The network prefix associated with the area. OSPF will be enabled on all interfaces that have at least one address falling within this range. Note that the network prefix of the address is used for this check (i.e. not the local address). For point-to-point interfaces, this means the address of the remote endpoint. Name of the address list containing networks that should be advertised to the v3 interface. The OSPF network type on this interface. Note that if interface configuration does not exist, the default network type is 'ptp' on PtP interfaces and 'broadcast' on all other interfaces. - `broadcast` - Network type suitable for Ethernet and other multicast capable link layers. Elects designated router. - `nbma` - Non-Broadcast Multiple Access. Protocol packets are sent to each neighbor's unicast address. Requires manual configuration of neighbors. Elects designated router. - `ptp` - Suitable for networks that consist only of two nodes. Does not elect a designated router. - `ptmp` - Point-to-Multipoint. Easier to configure than NBMA because it requires no manual configuration of a neighbor. Does not elect a designated router. This is the most robust network type and as such suitable for wireless networks, if 'broadcast' mode does not work well enough for them - `ptp-unnumbered` - Works the same as ptp, except that the remote neighbor does not have an associated IP address to a specific PTP interface. For example, in case IP unnumbered is used on Cisco devices. Time interval after which the lost link state advertisement will be resent. When a router sends a link state advertisement (LSA) to its neighbor, the LSA is kept until the acknowledgment is received. If the acknowledgment was not received in time (see transmit-delay), the router will try to retransmit the LSA. Link-state transmit delay is the estimated time it takes to transmit a link-state update packet on the interface. The interval between **HELLO** packets that the router sends out on this interface. The smaller this interval is, the faster topological changes will be detected; the tradeoff is more OSPF protocol traffic. This value must be the same for all the routers on a specific network, otherwise, adjacency between them will not form. Specifies the interval after which a neighbor is declared dead. This interval is advertised in hello packets. This value must be the same for all routers on a specific network, otherwise, adjacency between them will not form. Router's priority. Used to determine the designated router in a broadcast network. The router with the highest priority value takes precedence. Priority value 0 means the router is not eligible to become a designated or backup designated router at all. Default value is 128, keep this in mind if you had strict priorities set for DR/BDR election. Interface cost expressed as link state metric. If enabled, then the router does not send or receive OSPF traffic on the matching interfaces. Specifies authentication method for OSPF protocol messages. - `simple` - plain text authentication. - `md5` - keyed Message Digest 5 authentication. - `sha*` - HMAC-SHA authentication RFC5709. If the parameter is unset, then authentication is not used. The authentication key to be used, should match on all the neighbors of the network segment. The key id is used to calculate a message digest (used when MD5 or SHA authentication is enabled). The value should match all OSPF routers from the same region. ### routing/ospf/lsa **Type:** Directory Whether the LSA originated from the router itself. flushing wraparound dynamic The area this LSA belongs to. An originator of the LSA record. LSA record ID A number of times the LSA for a link has been updated. How long ago (in seconds) the last update occurred. ### routing/ospf/neighbor **Type:** Directory List of currently active OSPF neighbors. virtual dynamic Name of the interface this neighbor was discovered. An IP address of the OSPF neighbor router. Neighbor router's **RouterID** An IP address of the Designated Router. An IP address of the Backup Designated Router. - `Down` - No Hello packets have been received from a neighbor. - `Attempt` - Applies only to NBMA clouds. The state indicates that no recent information was received from a neighbor. - `Init` - Hello packet received from the neighbor, but bidirectional communication is not established (Its own RouterID is not listed in the Hello packet). - `2-way` - This state indicates that bi-directional communication is established. DR and BDR elections occur during this state. Routers build adjacencies based on whether the router is DR or BDR, and the link is point-to-point or a virtual link. - `ExStart` - Routers try to establish the initial sequence number that is used for the packet information exchange. The router with a higher ID becomes the master and starts the exchange. - `Exchange` - Routers exchange database description (DD) packets. - `Loading` - In this state, actual link state information is exchanged. Link State Request packets are sent to neighbors to request any new LSAs that were found during the Exchange state. - `Full` - Adjacency is complete, and neighbor routers are fully adjacent. LSA information is synchronized between adjacent routers. Routers achieve the full state with their DR and BDR only. An exception is P2P links. Elapsed time since adjacency was formed. ### routing/ospf/static-neighbor **Type:** Directory Static configuration of the OSPF neighbors. Required for non-broadcast multi-access networks. disabled inactive Name of the area the neighbor belongs to. The unicast IP address and an interface that can be used to reach the IP of the neighbor. For example, `address=1.2.3.4%ether1` indicates that a neighbor with IP `1.2.3.4` is reachable on the `ether1` interface. How often to send hello messages to the neighbors that are in a `down` state (i.e., there is no traffic from them). --- ## Pimsm import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/pimsm **Conditions:** !smips **Type:** Directory ### routing/pimsm/bsr **Conditions:** !smips **Type:** Directory dynamic #### routing/pimsm/bsr/candidate **Conditions:** !smips **Type:** Directory disabled inactive #### routing/pimsm/bsr/rp-candidate **Conditions:** !smips **Type:** Directory disabled inactive #### routing/pimsm/bsr/rp-set **Conditions:** !smips **Type:** Directory ### routing/pimsm/igmp-interface-template **Conditions:** !smips **Type:** Directory ### routing/pimsm/instance **Conditions:** !smips **Type:** Directory The instance menu defines the main PIM-SM settings. The instance is then used for all other PIM-related configurations like interface-template, static RP, and Bootstrap Router. disabled inactive Name of the VRF for control connections. Name of the instance. Specifies address family for PIM. Whether to switch to Shortest Path Tree (SPT) if multicast data bandwidth threshold is reached. The router will not proceed from protocol phase one (register encapsulation) to native multicast traffic flow if this option is disabled. It is recommended to enable this option. Time interval in which to account for multicast data bandwidth, used in conjunction with `switch-to-spt-bytes` to determine if the switching threshold is reached. Multicast data bandwidth threshold. Switching to Shortest Path Tree (SPT) happens if this threshold is reached in the specified time interval. If a value of 0 is configured, switching will happen immediately. Currently not implemented. Currently not implemented. The hash mask allows changing how many groups to map to one of the matching RPs. Changes the selection priority for static RP. When disabled, the bootstrap RP set has a higher priority. When enabled, static RP has a higher priority. Currently not implemented. ### routing/pimsm/interface **Conditions:** !smips **Type:** Directory The interface menu shows all interfaces that are currently participating in PIM and their statuses. This menu contains dynamic and read-only entries that get created by defined interface templates. dynamic designated-router join-tracking ### routing/pimsm/interface-template **Conditions:** !smips **Type:** Directory The interface template menu defines which interfaces will participate in PIM and what per-interface configuration will be used. disabled inactive Name of the PIM instance this interface template belongs to. List of interfaces that will participate in PIM. Periodic interval for Hello messages. Randomized interval for the initial Hello message on interface startup or detecting a new neighbor. The Designated Router (DR) priority. A single Designated Router is elected on each network. The priority is used only if all neighbors have advertised a priority option. The numerically largest priority is preferred. In case of a tie or if priority is not used - the numerically largest IP address is preferred. Sets the value for a prune pending timer. It is used by upstream routers to figure out how long they should wait for a Join override message before pruning an interface that has join suppression enabled. Sets the maximum time period over which to randomize when scheduling a delayed override Join message on a network that has join suppression enabled. Sets the value of a Tracking (T) bit in the LAN Prune Delay option in the Hello message. When enabled, a router advertises its willingness to disable Join suppression. It is possible for upstream routers to explicitly track the join membership of individual downstream routers if Join suppression is disabled. Unless all PIM routers on a link negotiate this capability, explicit tracking and the disabling of the Join suppression mechanism are not possible. ### routing/pimsm/neighbor **Conditions:** !smips **Type:** Directory The neighbor menu shows all detected neighbors that are running PIM and their statuses. This menu contains dynamic and read-only entries. designated-router join-tracking Name of the PIM instance this neighbor is detected on. Shows the neighbor's IP address and local interface the neighbor is detected on. Indicates the neighbor's priority value. Shows the remaining time after the neighbor is removed from the list if no new Hello message is received. The hold time equals neighbor's `hello-period * 3.5`. Shows whether the neighbor is elected as Designated Router (DR). Indicates the neighbor's value of the propagation delay in the LAN Prune Delay option in the Hello message. Indicates the neighbor's value of the override interval in the LAN Prune Delay option in the Hello message. Indicates the neighbor's value of a Tracking (T) bit in the LAN Prune Delay option in the Hello message. ### routing/pimsm/static-rp **Conditions:** !smips **Type:** Directory The static-rp menu allows manually defining the multicast group to RP mappings. Such a mechanism is not robust to failures but does at least provide a basic interoperability mechanism. disabled inactive The name of the PIM instance this static RP belongs to. The multicast group that belongs to a specific RP. The IP address of the static RP. ### routing/pimsm/uib-g **Conditions:** !smips **Type:** Directory The upstream information base menus show the any-source multicast (\*,G) and source-specific multicast (S,G) groups and their statuses. These menus contain only read-only entries. rp-local Name of the PIM instance the multicast group is created on. The multicast group address. The address of the Rendezvous Point for this group. The Reverse Path Forwarding (RPF) indicates the router address and outgoing interface that a Join message for that group is directed to. Indicates whether the multicast router itself is the RP. ### routing/pimsm/uib-sg **Conditions:** !smips **Type:** Directory keepalive The Shortest Path Tree (SPT) bit indicates whether forwarding is taking place on the (S,G) Shortest Path Tree or on the (\*,G) tree. A router can have an (S,G) state and still be forwarding on a (\*,G) state during the interval when the source-specific tree is being constructed. When the SPT bit is false, only the (\*,G) forwarding state is used to forward packets from S to G. When the SPT bit is true, both (\*,G) and (S,G) forwarding states are used. Name of the PIM instance the multicast group is created on. The multicast group address. The source IP address of the multicast group. The Reverse Path Forwarding (RPF) indicates the router address and outgoing interface that a Join message for that group is directed to. --- ## Rip import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/rip **Type:** Directory ### routing/rip/instance **Type:** Directory The maximum metric of a RIP route is 15. A metric higher than 15 is considered 'infinity' and routes with such a metric are considered unreachable. Thus RIP cannot be used on networks with more than 15 hops between any two routers, and using redistribute metrics larger than 1 further reduces this maximum hop count. disabled Name of the instance. Name of the VRF to be used for connections. Whether to originate default route. Specifies the time interval after which the route is considered invalid. Routing table name where routes will be installed. ### routing/rip/interface **Type:** Directory ### routing/rip/interface-template **Type:** Directory disabled Name of the key-chain which contains the MD5 key. Should be set only when MD5 authentication is needed. Password for plain-text authentication. Should be set only when plain-text authentication is needed. ### routing/rip/keys **Type:** Directory MD5 authentication key chains. disabled Key identifier. This number is included in MD5 authenticated RIP messages, and determines which key to use to check authentication for a specific message. Authentication key. Maximal length 16 characters The key is valid from this date and time. The key is valid until this date and time. ### routing/rip/neighbor **Type:** Directory This submenu is used to define neighboring routers to exchange routing information with. Normally there is no need to add the neighbors, if multicasting is working properly within the network. If there are problems with exchanging routing information, neighbor routers can be added to the list. It will force the router to exchange the routing information with the neighbor using regular unicast packets. dynamic Time from last update. ### routing/rip/static-neighbor **Type:** Directory disabled --- ## Route(Routing) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/route **Type:** Directory A read-only table that lists routes from all the address families as well as all filtered routes with all possible route attributes. Default example output of the table with various route types: ```ros [admin@MikroTik] /routing/route> print Flags: A - ACTIVE; c, s, a, l, y - COPY; H - HW-OFFLOADED Columns: DST-ADDRESS, GATEWAY, AFI, DISTANCE, SCOPE, TARGET-SCOPE, IMMEDIATE-GW DST-ADDRESS GATEWAY AFI D SCOPE TA IMMEDIATE-GW lH 10.0.0.0/8 ip 0 ;;; defconf As 10.0.0.0/8 10.155.130.1 ip 1 30 10 10.155.130.1%ether1 lH 10.155.130.0/25 ip 0 Ac 10.155.130.0/25 ether1 ip 0 10 ether1 aH 10.155.130.12/32 ip 0 lH 111.13.0.0/24 ip 0 Ac 111.13.0.0/24 ether2 ip 0 10 ether2 aH 111.13.0.1/32 ip 0 Ac 111.111.111.2/32 loopback@vrfTest ip 0 10 loopback Ac 2111:4::/64 ether2 ipv6 0 10 ether2 Ac fe80::%ether1/64 ether1 ipv6 0 10 ether1 Ac fe80::%ether2/64 ether2 ipv6 0 10 ether2 Ac fe80::%ether3/64 ether3 ipv6 0 10 ether3 Ac fe80::%ether4/64 ether4 ipv6 0 10 ether4 Ac 3333::2/128 loopback@vrfTest ipv6 0 10 loopback Ac fe80::%loopback/64 loopback@vrfTest ipv6 0 10 loopback Ay 111.111.111.2/32&65530:100 loopback@vrfTest vpnv4 0 10 5 loopback Ay 3333::2/128&65530:100 loopback@vrfTest vpnv6 0 10 5 loopback A H ether1 link 0 A H ether2 link 0 A H ether3 link 0 A H ether4 link 0 A H loopback link 0 ``` Detailed example output with some BGP, OSPF, and other routes: ```ros [admin@MikroTik] /routing/route> print detail Flags: X - disabled, F - filtered, U - unreachable, A - active; c - connect, s - static, r - rip, b - bgp, o - ospf, d - dhcp, v - vpn, m - modem, a - ldp-address, l - ldp-mapping, y - copy; H - hw-offloaded; + - ecmp, B - blackhole o afi=ip4 contribution=best-candidate dst-address=0.0.0.0/0 routing-table=main gateway=10.155.101.1%ether1 immediate-gw=10.155.101.1%ether1 distance=110 scope=20 target-scope=10 belongs-to="OSPF route" ospf.metric=2 .tag=111 .type=ext-type-1 debug.fwp-ptr=0x203425A0 Ad + afi=ip4 contribution=active dst-address=0.0.0.0/0 routing-table=main pref-src="" gateway=10.155.101.1 immediate-gw=10.155.101.1%ether1 distance=1 scope=30 target-scope=10 vrf-interface=ether1 belongs-to="DHCP route" debug.fwp-ptr=0x20342060 As + afi=ip4 contribution=active dst-address=0.0.0.0/0 routing-table=main pref-src="" gateway=10.155.101.1 immediate-gw=10.155.101.1%ether1 distance=1 scope=30 target-scope=10 belongs-to="Static route" debug.fwp-ptr=0x20342060 Fb afi=ip4 contribution=filtered dst-address=1.0.0.0/24 routing-table=main gateway=10.155.101.1 immediate-gw=10.155.101.1%ether1 distance=20 scope=40 target-scope=10 belongs-to="BGP IP routes from 10.155.101.217" rpki=valid bgp.peer-cache-id=*B000002 .aggregator="13335:172.68.180.1" .as-path="65530,100,9002,13335" .atomic-aggregate=yes .origin=igp debug.fwp-ptr=0x20342960 ``` disabled A flag indicates whether the route was filtered by routing filters and excluded from being used as the best route. A flag indicates whether the route next-hop is unreachable. A flag indicates whether the route is elected as Active and eligible to be added to the FIB. connect static rip A flag indicates whether this route was added by the [BGP](../../user-guides/routing-and-networking-protocols/unicast/bgp/index.md) protocol. bgp-net ospf isis A flag indicates whether the route was added by the DHCP service. A flag indicates whether the route was added by one of the VPN protocols (PPPoE, L2TP, SSTP, etc.) A flag indicates whether the route is added by the LTE or 3g modems. A flag indicates whether the route entry is an LDP address. A flag indicates whether the route entry is the LDP mapping. slaac A flag indicates a copy of the route to be redistributed as the L3VPN route. VPNv4/6 related attributes are attached to this route. evpn Indicates whether the route is eligible to be hardware offloaded on supported hardware. A flag indicates whether the route is added as an [Equal-Cost Multi-Path](../../user-guides/routing-and-networking-protocols/routing-decision.md#multipath-ecmp-routes) route in the FIB A flag indicates whether it is a blackhole route. Address family this route belongs to. Shows the route status contributing to the election process, e.g "filtered, active, candidate" Routing table this route belongs to. Configured gateway, for the actually resolved gateway, see `immediate-gw` parameter. Shows actual (resolved) gateway and interface that will be used for packet forwarding. Displayed in format `[ip%interface]`. Currently used check-gateway option. Scope used in the next-hop lookup process. [Read more>>](../../user-guides/routing-and-networking-protocols/routing-decision.md#nexthop-lookup) Target scope used in next-hop lookup process. [Read more>>](../../user-guides/routing-and-networking-protocols/routing-decision.md#nexthop-lookup). Internal use only parameter which allows identifying to which VRF route should be added. Used by services that add routes dynamically, for example, DHCP client. Shown for debugging purposes. Descriptive info showing from where the route was received. Local IP address of the connected network. Current status of the prefix from the [RPKI](../../user-guides/routing-and-networking-protocols/unicast/rpki.md) validation process. [BGP](../../user-guides/routing-and-networking-protocols/unicast/bgp/index.md) session that installed the route. See `/routing/bgp/session` menu. Value of the **`AS_PATH`** BGP attribute. Value of the **`COMMUNITIES`** BGP attribute. Value of the **`EXTENDED_COMMUNITIES`** BGP attribute. Value of the **`LARGE_COMMUNITIES`** BGP attribute. Hex blob of unknown [BGP](../../user-guides/routing-and-networking-protocols/unicast/bgp/index.md) attributes. Value of the **`LOCAL_PREF`** BGP attribute. Value of the **`IGP_METRIC`** BGP attribute Value of the **`MED`** BGP attribute. Mapped MPLS ingress label. Mapped MPLS egress label. LDP mapped MPLS label. ### routing/route/rule **Type:** Directory disabled inactive --- ## Rpki import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/rpki **Type:** Directory disabled Group assigned to the database. RTR server address. RTR server port. VRF table used to bind the connection. When multiple RTR sources exist, a higher number indicates higher preference. If preference is not configured, RouterOS prefers the lowest remote IP within the group. If remote IPs are equal, RouterOS prefers the lowest remote port. Interval in seconds to poll the validator for the newest data. Interval in seconds to retry after a failed data poll from the validator. Interval in seconds for which polled data remains valid when no valid update is received from the validator. ### routing/rpki/rpki-check **Type:** Command ### routing/rpki/rpki-query **Type:** Command ### routing/rpki/session **Type:** Directory --- ## Rule import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/rule **Type:** Directory disabled inactive default Source address to match. Destination address to match. Match a specific routing mark. Incoming interface to match. Action to take on the matching packet: - drop - silently drop the packet. - lookup - perform a lookup in routing tables. - lookup-only-in-table - perform lookup only in the specified routing table (see the `table` parameter). - unreachable - generate an ICMP unreachable message and send it to the source. - mangle - perform actions by firewall mangle rules. Name of the routing table to use for lookup. Hide routes from the routing table with the specified prefix length from packets processed by this routing rule. This is equivalent to the Linux IP rule `suppress_prefixlength`. For example, set the value to 0 to suppress the default route in the routing decision. Name of the chain used by routing decision rules. By default, `user` is used when the chain is not specified. If the chain name matches a built-in routing decision name, user-created rules are added after that decision. For example, if `chain=mangle`, user-created rules in this chain are located immediately after the `mangle` decision. --- ## Settings(Routing) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/settings **Type:** Settings Directory When enabled, all routing-related processes combine into a single routing process to reduce RAM usage. When disabled, routing-related processes run separately and can improve performance and stability in some setups. By default, single-process is enabled only for devices with 64 MB of RAM or less. Reboot is required for this change to take effect. Name of the chain used to process all dynamically added routes. Name of the chain used to process `connected` routes. Defines the order of routing decision rules. By default, `user` is the chain where user-defined `/routing/rule` entries are added. You can add custom chains anywhere in the list. --- ## Stats import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/stats **Conditions:** !smips **Type:** Directory ### routing/stats/memory **Type:** Directory ### routing/stats/origin **Type:** Directory synthetic terminal stopping abandoned hold attrs-updated attrs-merge ### routing/stats/pcap **Conditions:** !smips **Type:** Directory ### routing/stats/process **Type:** Directory This menu allows you to monitor debugging information of all the routing processes. ```ros [admin@rack1_b35_CCR1036] /routing/stats/process> print interval=1 Columns: TASKS, PRIVATE-MEM-BLOCKS, SHARED-MEM-BLOCKS, PSS, RSS, VMS, RETIRED, ID, PID, RPID, PROCESS-TIME, KERNEL-TIME, CUR-BUSY, MAX-BUSY, CUR-CALC, MAX-CALC # TASKS PRIVATE- SHARED-ME PSS RSS VMS RETIRED ID PID RPID PROCESS KERNEL-TIME CUR-BUSY MAX-BUSY CUR-CALC MAX-CALC 0 routing tables 768.0KiB 1792.0KiB 2399.0KiB 6.4MiB 22.1MiB 34 main 317 0 2s260ms 1s940ms 10ms 170ms 20ms 1s210ms rib 1 fib 0 0 2263.0KiB 6.2MiB 22.3MiB fib 351 1 250ms 1s720ms 1s210ms 1s210ms 2 ospf 256.0KiB 256.0KiB 2559.0KiB 6.6MiB 22.3MiB ospf 384 1 4s710ms 5s210ms 20ms 20ms 3 pimsm 256.0KiB 0 2252.0KiB 5.8MiB 22.3MiB pim 386 1 200ms 450ms 10ms 10ms 4 fantasy 0 0 2031.0KiB 5.1MiB 22.3MiB fantasy 388 1 270ms 390ms 10ms 10ms 5 configuration and reporting 0 512.0KiB 2351.0KiB 6.4MiB 22.3MiB static 389 1 310ms 430ms 10ms 10ms 6 ldp 256.0KiB 256.0KiB 2455.0KiB 6.4MiB 22.3MiB mpls 387 1 340ms 350ms 40ms 40ms Copy 7 rip 256.0KiB 0 2230.0KiB 5.7MiB 22.3MiB rip 377 1 230ms 380ms 10ms 10ms 8 routing policy configuration 512.0KiB 512.0KiB 2355.0KiB 5.6MiB 22.3MiB policy 358 1 240ms 390ms 10ms 10ms 9 BGP service 512.0KiB 0 2592.0KiB 6.3MiB 22.3MiB bgp 364 1 360ms 600ms 10ms 10ms 10 BFD service 256.0KiB 0 2206.0KiB 5.7MiB 22.3MiB 12 371 1 230ms 370ms 10ms 10ms 11 BGP Input 111.11.0.1 512.0KiB 512.0KiB 2560.0KiB 6.4MiB 22.3MiB 1 22 679 1 140ms 350ms 10ms 10ms BGP Output 111.11.0.1 12 Global memory 256.0KiB global 0 0 ``` abandoned #### routing/stats/process/kill **Type:** Command ### routing/stats/step **Type:** Directory running --- ## Table import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## routing/table **Type:** Directory dynamic disabled invalid used Name of the routing table. Flag indicating whether routes in this table will be installed in the [FIB](../../user-guides/routing-and-networking-protocols/routing-decision.md#forwarding-information-base). --- ## safe-mode import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # safe-mode **Type:** Settings Directory indicates if safe mode is enabled user name of the current safe mode session indicates if safe mode is enabled for the current session safe mode session owner --- ## snmp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # snmp **Type:** Settings Directory ## snmp/community **Type:** Directory default disabled ## snmp/send-trap **Type:** Command --- ## special-login import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # special-login **Type:** Directory disabled --- ## Backup import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/backup **Type:** Directory ### system/backup/cloud **Type:** Directory #### system/backup/cloud/download-file **Type:** Command #### system/backup/cloud/remove-file **Type:** Command #### system/backup/cloud/upload-file **Type:** Command ### system/backup/load **Type:** Command ### system/backup/save **Type:** Command --- ## Check Disk import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/check-disk **Conditions:** i386 **Type:** Command --- ## Check Installation import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/check-installation **Type:** Command This command ensures the integrity of the RouterOS system by verifying the readability and correct placement of files. Its primary purpose is to confirm the health and status of your NAND/Flash storage. --- ## Clock import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/clock **Type:** Settings Directory ### system/clock/manual **Type:** Settings Directory --- ## Console(Console) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/console **Type:** Directory --- ## Screen import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### system/console/screen **Conditions:** i386 **Type:** Settings Directory --- ## Dashboard import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### system/dashboard/settings **Type:** Settings Directory ### system/dashboard/show **Type:** Command --- ## Default Configuration import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/default-configuration **Type:** Settings Directory ### system/default-configuration/caps-mode-script **Type:** Settings Directory ### system/default-configuration/custom-script **Type:** Settings Directory ### system/default-configuration/script **Type:** Settings Directory ### system/default-configuration/wps-sync-mode-script **Syscap:** wpssync **Type:** Settings Directory --- ## Device Mode import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/device-mode **Type:** Settings Directory ### system/device-mode/update **Type:** Command --- ## Gps import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/gps **Conditions:** mmips **Package:** gps **Type:** Settings Directory ### system/gps/monitor **Package:** gps **Type:** Command --- ## Hardware import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- --- ## Health import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/health **Conditions:** !i386 **Syscap:** health **Type:** Directory ### system/health/settings **Conditions:** !i386, tile **Syscap:** health-settings **Type:** Settings Directory #### system/health/settings/detect-fans **Conditions:** !i386 **Type:** Command --- ## History import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/history **Type:** Directory --- ## Identity import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/identity **Type:** Settings Directory --- ## Leds import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/leds **Type:** Directory RSSI threshold ### system/leds/settings **Type:** Settings Directory --- ## License import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/license **Type:** Settings Directory ### system/license/generate-new-id **Syscap:** chr **Type:** Command ### system/license/output **Syscap:** nochr **Type:** Command ### system/license/renew **Syscap:** chr **Type:** Command --- ## Logging import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/logging **Type:** Directory ### system/logging/action **Type:** Directory #### system/logging/action/clear **Type:** Command --- ## Note import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/note **Type:** Settings Directory --- ## Ntp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/ntp **Type:** Directory ### system/ntp/client **Type:** Settings Directory #### system/ntp/client/reset-freq-drift **Type:** Command #### system/ntp/client/servers **Type:** Directory ### system/ntp/key **Type:** Directory ### system/ntp/monitor-peers **Type:** Command ### system/ntp/server **Type:** Settings Directory --- ## Local Update import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### system/package/local-update **Type:** Directory Instead of connecting directly to MikroTik servers, you can upload package files to one of your local RouterOS devices and use it as a local package server. Whether to download available packages from the local package server. IP address of the local package server. Name of the package. Version of the package. Current status of the package. Download completion percentage. #### system/package/local-update/download **Type:** Command Download specific compatible (matching device architecture) packages that are available on the local package server. Downloaded packages are saved in the root directory. #### system/package/local-update/download-all **Type:** Command Download all compatible (matching device architecture) packages that are available on the local package server. Downloaded packages are saved in the root directory. Whether to include beta packages when downloading all compatible packages. Whether to automatically reboot the device after all packages finish downloading. #### system/package/local-update/mirror **Type:** Settings Directory You can mirror packages (for all architectures) from your main local package server by using this menu. Downloaded packages are saved into the `packs` folder in the root directory. Whether to enable periodic check and download of packages from the local package server. IP address of the primary local package server. IP address of the secondary local package server. Time interval at which the device checks the local package server for new package availability. If a new package is located, the package download begins. Only downloads the packages that are not already present on the device. Username for accessing the local package server. Password for accessing the local package server. Software ID of the device. ##### system/package/local-update/mirror/force-check **Type:** Command #### system/package/local-update/refresh **Type:** Command Refresh and check the list of available compatible (matching device architecture) packages on the local package server. #### system/package/local-update/update-package-source **Type:** Directory The server from which to get the package is defined in this list. IP address of the local package server. Username for accessing the local package server. Password for accessing the local package server. --- ## Package import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/package **Type:** Directory Commands executed in this menu will take place only on the restart of the router. Until then, you can freely schedule or revert the set actions. Name of the package. Version of the package. Date and time the package was built. Scheduled action for the package after the next reboot. The bundle package this package belongs to. Size of the package in bytes. ### system/package/apply-changes **Type:** Command Apply scheduled changes and reboot the device. Upgrade only the RouterOS main package, omitting packages that are missing or not uploaded. ### system/package/disable **Type:** Command Schedule the package to be disabled after the next reboot. No features provided by the package will be accessible. ### system/package/downgrade **Type:** Command Prompt for a reboot. During the reboot process, the router will try to downgrade RouterOS to the oldest version possible by checking the packages that are uploaded to the router. ### system/package/enable **Type:** Command ### system/package/uninstall **Type:** Command Schedule the package to be removed from the router. That will take place during the reboot. ### system/package/unschedule **Type:** Command ### system/package/update **Type:** Settings Directory Manage the `check-for-updates` channel and perform RouterOS upgrades. Upgrade [channel](#channel) to use when checking for new versions. Protocol for connecting to the MikroTik download server. Use `http` only if your network blocks HTTPS. HTTPS is recommended. Whether and how to validate the server SSL certificate. Always use `yes` to ensure a secure connection. IP version preference for connecting to the MikroTik download server. Currently installed RouterOS version. Latest available RouterOS version in the selected [channel](#channel). Current status of the update process (for example, `New version is available`). #### system/package/update/cancel **Type:** Command #### system/package/update/check-for-updates **Type:** Command Whether to fetch the changelog along with the update check. Changelog text for the latest available version. #### system/package/update/download **Type:** Command Download only the RouterOS main package, omitting packages that are missing or not uploaded. #### system/package/update/install **Type:** Command Install only the RouterOS main package, omitting packages that are missing or not uploaded. --- ## Ptp import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/ptp **Conditions:** !smips **Syscap:** ptp **Type:** Directory ### system/ptp/monitor **Conditions:** !smips **Type:** Command ### system/ptp/port **Conditions:** !smips **Type:** Directory ### system/ptp/status **Conditions:** !smips **Type:** Directory --- ## Reboot import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/reboot **Type:** Command --- ## Regulatory import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/regulatory **Type:** Settings Directory --- ## Reset Configuration import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/reset-configuration **Type:** Command .rsc file --- ## Resource import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/resource **Conditions:** !powerpc, !smips **Type:** Settings Directory ### system/resource/cpu **Type:** Directory ### system/resource/hardware **Conditions:** !powerpc, !smips, i386 **Type:** Directory #### system/resource/hardware/authorize **Conditions:** !powerpc, !smips **Type:** Command #### system/resource/hardware/usb-power-reset **Conditions:** !powerpc, !smips, i386 **Type:** Command #### system/resource/hardware/usb-settings **Conditions:** !powerpc, !smips **Type:** Settings Directory ### system/resource/irq **Type:** Directory #### system/resource/irq/rps **Syscap:** rps **Type:** Directory ### system/resource/monitor **Type:** Command --- ## Routerboard import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/routerboard **Conditions:** !i386, !i386, !mipsel, !powerpc **Type:** Settings Directory ### system/routerboard/mode-button **Conditions:** !i386 **Type:** Settings Directory ### system/routerboard/reset-button **Conditions:** !i386 **Type:** Settings Directory ### system/routerboard/settings **Conditions:** !i386, !i386 **Type:** Settings Directory #### system/routerboard/settings/keep-frequency **Conditions:** !i386, mipsel **Type:** Command ### system/routerboard/upgrade **Conditions:** !i386 **Type:** Command ### system/routerboard/usb **Conditions:** !i386, !i386, !mipsel, !powerpc **Type:** Settings Directory #### system/routerboard/usb/power-reset **Conditions:** !i386, !i386, !mipsel, !powerpc **Type:** Command ### system/routerboard/wps-button **Conditions:** !i386 **Type:** Settings Directory --- ## Rtrace import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/rtrace **Type:** Settings Directory ### system/rtrace/start **Type:** Command ### system/rtrace/stop **Type:** Command --- ## Scheduler import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/scheduler **Type:** Directory --- ## Job import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### system/script/job **Type:** Directory --- ## Script import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/script **Type:** Directory ### system/script/environment **Type:** Directory --- ## Serial Interface import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### system/serial-interface/read **Type:** Command name of the port from port list timeout for serial terminal access (capture mode) maximum bytes read from the serial terminal (capture mode) read from the serial terminal until provided character sequence (capture mode) do not interpret output as a console value (in capture mode) ### system/serial-interface/serial-terminal **Type:** Command name of the port from port list port channel that will be used (0 by default) non-interactively write provided value to the serial terminal ### system/serial-interface/start **Type:** Command name of the port from port list port channel that will be used (0 by default) ### system/serial-interface/stop **Type:** Command name of the port from port list port channel that will be used (0 by default) ### system/serial-interface/write **Type:** Command name of the port from port list non-interactively write provided value to the serial terminal --- ## Shell import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- --- ## Shutdown import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/shutdown **Type:** Command --- ## Ssh Exec import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/ssh-exec **Package:** security **Type:** Command write output to file instead of 'output' variable --- ## Ssh(System) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/ssh **Package:** security **Type:** Command this output method does not accept password input, use key authentication --- ## Sup Output import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/sup-output **Type:** Command --- ## Swos(System) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/swos **Conditions:** !i386, !mmips, !powerpc, !tile, !smips **Syscap:** swos **Type:** Settings Directory ### system/swos/load-config **Conditions:** !i386, !mmips, !powerpc, !tile, !smips **Type:** Command ### system/swos/password **Conditions:** !i386, !mmips, !powerpc, !tile, !smips **Type:** Command ### system/swos/reset-config **Conditions:** !i386, !mmips, !powerpc, !tile, !smips **Type:** Command ### system/swos/save-config **Conditions:** !i386, !mmips, !powerpc, !tile, !smips **Type:** Command ### system/swos/upgrade **Conditions:** !i386, !mmips, !powerpc, !tile, !smips **Type:** Command --- ## Telnet import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/telnet **Type:** Command --- ## Ups import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/ups **Package:** ups **Type:** Directory ### system/ups/beep **Package:** ups **Type:** Command ### system/ups/monitor **Package:** ups **Type:** Command ### system/ups/rtc **Package:** ups **Type:** Command ### system/ups/self-test **Package:** ups **Type:** Command --- ## Watchdog import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## system/watchdog **Type:** Settings Directory --- ## task import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # task **Type:** Directory terminated current autosave ## task/add **Type:** Command command that should be executed in the background switch to background view immediately append output to file default filename for output autosave interval for when filename is set maximum buffer lines add a timestamp to the saved file don't page header to output maximum save file size ## task/next **Type:** Command ## task/terminate **Type:** Command --- ## Apptraffic import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### tool/apptraffic/stats **Conditions:** !mmips, !powerpc, !smips, !mipsel **Type:** Directory #### tool/apptraffic/stats/categories **Conditions:** !mmips, !powerpc, !smips, !mipsel **Type:** Directory #### tool/apptraffic/stats/clear **Conditions:** !mmips, !powerpc, !smips, !mipsel **Type:** Command --- ## Bandwidth Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/bandwidth-server **Type:** Settings Directory Beginning of UDP port range Maximal simultaneous test count ### tool/bandwidth-server/session **Type:** Directory --- ## Bandwidth Test import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/bandwidth-test **Type:** Command --- ## Calea(Tool) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/calea **Package:** calea **Type:** Directory --- ## Ddns import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### tool/ddns/dns-update **Package:** advanced-tools **Type:** Command --- ## E Mail import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/e-mail **Type:** Settings Directory TLS certificate validation ### tool/e-mail/send **Type:** Command TLS certificate validation --- ## Fetch import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/fetch **Conditions:** arm64 **Type:** Command where to output data, works for all protocols POST or PUT request body data add http header fields https certificate validation source address for HTTP, HTTPS only encode payload and add corresponding Content-Encoding header; for HTTP POST and PUT only ftp transfer type ftp and tftp transfer direction depracated, use 'output' argument seconds, default 10 default 0, i.e. no redirects percent-encodes every character in path except for alphanumeric and the following characters: -._~/?^=: --- ## Flood Ping import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/flood-ping **Conditions:** !smips **Package:** advanced-tools **Type:** Command --- ## Graphing import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/graphing **Type:** Settings Directory How often to refresh HTML pages (in seconds) --- ## Ifaces import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- #### tool/graphing/ifaces/interface **Type:** Directory disabled --- ## Queues import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- #### tool/graphing/queues/queue **Type:** Directory disabled --- ## Resource(Graphing) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ### tool/graphing/resource **Type:** Directory disabled --- ## Ip Scan import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/ip-scan **Conditions:** !smips **Package:** advanced-tools **Type:** Command dhcp --- ## Mac Scan import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/mac-scan **Conditions:** !smips **Package:** advanced-tools **Type:** Command --- ## Mac Server import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/mac-server **Type:** Settings Directory ### tool/mac-server/mac-winbox **Type:** Settings Directory ### tool/mac-server/ping **Type:** Settings Directory ### tool/mac-server/sessions **Type:** Directory --- ## Mac Telnet import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/mac-telnet **Type:** Command --- ## Netwatch import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/netwatch **Package:** advanced-tools **Type:** Directory disabled The name of the Netwatch probe. The IP address or domain name of the server to be probed. See [address flags](../../cli-reference/#address-flags) Type of the probe (default value: **"simple"**) : - simple - simplified ICMP probe, with fewer options than "ICMP" type, used for backward compatibility with the older Netwatch version - icmp - (ping-style) series of ICMP request-response with statistics - tcp-conn - test TCP connection (3-way handshake) to a server specified by IP and port - http-get - do an HTTP Get request and test for a range of correct replies - https-get - do an HTTPS Get request and test for a range of correct replies - dns - do a specified DNS query for the domain name Source IP address which the Netwatch will try to use in order to reach the host. If the address is not configured on the router or was lost, then the host will be considered as "down". See [address flags](../../cli-reference/#address-flags) The time interval between probe tests. (default value: **10s**) Max time limit to wait for a response. (default value: **3s**) Time to wait before starting the probe. (default value: **3s**) (on add, enable, or system startup in cases when "startup-delay" value is smaller then "start-delay" value) Time to wait until starting the Netwatch probe after system startup. (default value: **5m**) Specifies if "Up" script should be run if the probe state change goes from Unknown to "Up", used to help against false positives after enabling the probe, or after a reboot. "no" means that the change from "Unknown" to "Up" will not be ignored. (default value: **no**) Specifies if "Down" script should be run if the probe state change goes from Unknown to "Down". "no" means that the change from "Unknown" to "Down" will not be ignored. (default value: **no**) **Warning**: Should be used with care, as the first "Down" status won't be executed, and Down script will only be run if the probe goes from "Up" to "Down" state. Script to execute on the event of probe state change from "Down" to "Up". Script to execute on the event of probe state change from "Up" to "Down". Script to execute at the end of every probe test. The time between ICMP-request packet sends. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **50ms**) Total count of ICMP packets to send out within a single test. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **10**) Total size of the IP ICMP packet. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **50**) Manually sets the time to live value for the ICMP packet. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **255**) If the ICMP "time exceeded" message should be considered a valid response. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **no**) Netwatch will not wait for all the packets to be processed to change probe status if it is already known that the host will be considered "Down". This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **no**) Netwatch will not wait for all the packets to be processed to change probe status if it is already known that the host will be considered "Down". This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **no**) Fail threshold for rtt-max. (a value above thr-max is a probe fail) This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **1s**) Fail threshold for rtt-avg. (round trip time-avg) This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **100ms**) Fail threshold for rtt-stdev. (standard deviation of round trip time) This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **250ms**) Fail threshold for rtt-jitter. (jitter ( = max - min) of round trip time) This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **1s**) Fail threshold for loss-percent. (number of lost packets in percent) This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **85%**) Fail threshold for loss-count. (number of lost packets) This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. (default value: **4294967295(max)**) TCP port. This parameter is specific to the [**TCP-conn**](../../diagnostics-monitoring-and-troubleshooting/netwatch#tcp-conn-probe) and [**HTTP/S-GET**](../../diagnostics-monitoring-and-troubleshooting/netwatch#http-get-probe) probe types. (default value: **80** (TCP-conn, HTTP-GET) and **443** (HTTPS-GET)) Fail threshold for tcp-connect-time, the configuration uses microseconds, if the time unit is not specified (s/m/h), log and status pages display the same value in milliseconds. This parameter is specific to the [**TCP-conn**](../../diagnostics-monitoring-and-troubleshooting/netwatch#tcp-conn-probe) probe type.(default value: **1s**) Fail threshold for http-resp-time. This parameter is specific to the [**HTTP/S-GET**](../../diagnostics-monitoring-and-troubleshooting/netwatch#http-get-probe) probe types. (default value: **10s**) Range of HTTP response status codes that are accepted as an "Up" state for the probe. See [mozilla-http-status](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) or [RFC7231](https://datatracker.ietf.org/doc/html/rfc7231#section-6). This parameter is specific to the [**HTTP/S-GET**](../../diagnostics-monitoring-and-troubleshooting/netwatch#http-get-probe) probe types. (default value: **100-299**) Certificate from the local store that should be used for host verification. This parameter is specific to the [**HTTPS-GET**](../../diagnostics-monitoring-and-troubleshooting/netwatch#https-get-probe) probe type. Enables trust chain validation from the local certificate store. This parameter is specific to the [**HTTPS-GET**](../../diagnostics-monitoring-and-troubleshooting/netwatch#https-get-probe) probe type. (default value: **no**) Record type that will be used for DNS probe. This parameter is specific to the [**DNS**](../../diagnostics-monitoring-and-troubleshooting/netwatch#dns-probe) probe type. (default value: **A**) The DNS server that the probe should send its requests to; if not specified, it will use the value from `/ip/dns`. This parameter is specific to the [**DNS**](../../diagnostics-monitoring-and-troubleshooting/netwatch#dns-probe) probe type. See [address flags](../../cli-reference/#address-flags) Current status of the probe. Last time the status change happened. Total number of completed probe tests. Total number of failed probe tests. Amount of ICMP packets sent out during last probe test. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. Amount of ICMP response packets received during last probe test. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. Amount of lost ICMP response packets during last probe test. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. Percent of lost ICMP response packets during last probe test. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. Mean value of round trip time. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. Minimal round trip time. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. Maximum round trip time. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. Jitter ( = max - min) of round trip time. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. Standard deviation of round trip time. This parameter is specific to the [**ICMP**](../../diagnostics-monitoring-and-troubleshooting/netwatch#icmp-probe) probe type. Time taken to establish a TCP connection. This parameter is specific to the [**TCP-conn**](../../diagnostics-monitoring-and-troubleshooting/netwatch#tcp-conn-probe) probe type. HTTP response status code (200 OK, 404 Not Found, etc.). See [mozilla-http-status](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) or [RFC7231](https://datatracker.ietf.org/doc/html/rfc7231#section-6). This parameter is specific to the [**HTTP/S-GET**](../../diagnostics-monitoring-and-troubleshooting/netwatch#http-get-probe) probe types. Time taken by the HTTP/S server to send a response after receiving a request, typically measured in milliseconds. This parameter is specific to the [**HTTP/S-GET**](../../diagnostics-monitoring-and-troubleshooting/netwatch#http-get-probe) probe types. IPv4 IP address - the result of A record-type probe. This parameter is specific to the [**DNS**](../../diagnostics-monitoring-and-troubleshooting/netwatch#dns-probe) probe type. IPv6 IP address - the result of AAAA record-type probe. This parameter is specific to the [**DNS**](../../diagnostics-monitoring-and-troubleshooting/netwatch#dns-probe) probe type. Name servers - the result of NS record-type probe. This parameter is specific to the [**DNS**](../../diagnostics-monitoring-and-troubleshooting/netwatch#dns-probe) probe type. Mail servers along with their priorities - the result of MX record-type probe. This parameter is specific to the [**DNS**](../../diagnostics-monitoring-and-troubleshooting/netwatch#dns-probe) probe type. --- ## Ping Speed import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/ping-speed **Conditions:** !smips **Package:** advanced-tools **Type:** Command --- ## Ping import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/ping **Type:** Command See [Ping](../../diagnostics-monitoring-and-troubleshooting/ping) for the full documentation. IP address or DNS name of the target host. See [address flags](../../cli-reference/#address-flags) Time interval between ICMP echo requests Size of the ICMP data payload in bytes Time to Live value for the ICMP packet DSCP value to set in the IP header for QoS marking Set the Don't Fragment flag in the IP header Source IP address to use for the ICMP echo request Use ARP requests instead of ICMP echo to discover hosts Number of ICMP echo requests to send Interface to send the ping through VRF table to use for routing the ping request Sequence number of the ping response IP or MAC address of the responding host Size of the received ICMP packet in bytes Time to Live value from the received packet Round-trip time of the ping probe Status of the ping response Total number of ICMP echo requests sent Total number of ICMP echo replies received Percentage of lost packets Minimum measured round-trip time Average measured round-trip time Maximum measured round-trip time --- ## Profile import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/profile **Type:** Command --- ## Romon import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/romon **Type:** Settings Directory ### tool/romon/discover **Type:** Command active ### tool/romon/ping **Type:** Command ### tool/romon/port **Type:** Directory default disabled dynamic ### tool/romon/ssh **Syscap:** security **Type:** Command --- ## Sms import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/sms **Conditions:** !smips **Type:** Settings Directory Memory for reading, writing, sending and receiving operations (``, `` and `` in ETSI TS 127 005), will be used in further +CPMS commands (setting effective when using AT commands only) Poll new SMS every 5s. It's recommended to enable polling only when there are problems with receiving new SMS otherwise. Useful when modem automatically stores sent SMS ### tool/sms/inbox **Conditions:** !smips **Type:** Directory ### tool/sms/send **Conditions:** !smips **Type:** Command --- ## Sniffer import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/sniffer **Type:** Settings Directory ### tool/sniffer/connection **Type:** Directory active ### tool/sniffer/host **Type:** Directory ### tool/sniffer/packet **Type:** Directory ### tool/sniffer/protocol **Type:** Directory ### tool/sniffer/quick **Type:** Command ### tool/sniffer/save **Type:** Command ### tool/sniffer/start **Type:** Command ### tool/sniffer/stop **Type:** Command --- ## Snmp Get import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/snmp-get **Type:** Command --- ## Snmp Walk import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/snmp-walk **Type:** Command --- ## Speed Test import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/speed-test **Type:** Command --- ## Torch import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/torch **Type:** Command --- ## Traceroute import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/traceroute **Type:** Command --- ## Traffic Generator import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/traffic-generator **Type:** Settings Directory ### tool/traffic-generator/inject **Type:** Command ### tool/traffic-generator/inject-pcap **Type:** Command ### tool/traffic-generator/packet-template **Type:** Directory ### tool/traffic-generator/port **Type:** Directory disabled invalid dynamic ### tool/traffic-generator/quick **Type:** Command ### tool/traffic-generator/raw-packet-template **Type:** Directory dynamic ### tool/traffic-generator/start **Type:** Command ### tool/traffic-generator/stats **Type:** Directory #### tool/traffic-generator/stats/latency-distribution **Type:** Directory #### tool/traffic-generator/stats/port **Type:** Directory #### tool/traffic-generator/stats/raw **Type:** Directory #### tool/traffic-generator/stats/stream **Type:** Directory ### tool/traffic-generator/stop **Type:** Command ### tool/traffic-generator/stream **Type:** Directory disabled invalid --- ## Traffic Monitor import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/traffic-monitor **Type:** Directory disabled invalid --- ## Wol import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- ## tool/wol **Package:** advanced-tools **Type:** Command See [Wake on LAN](../../system-information-and-utilities/wake-on-lan) for the full documentation. Interface through which the Magic Packet will be sent MAC address of the target computer --- ## tr069-client import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # tr069-client **Package:** tr069-client **Type:** Settings Directory ## tr069-client/reset-tr069-config **Package:** tr069-client **Type:** Command --- ## undo import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # undo **Type:** Command --- ## user-manager import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # user-manager **Package:** userman-5 **Type:** Settings Directory ## user-manager/advanced **Package:** userman-5 **Type:** Settings Directory ## user-manager/attribute **Package:** userman-5 **Type:** Directory ## user-manager/database **Package:** userman-5 **Type:** Settings Directory ### user-manager/database/load **Package:** userman-5 **Type:** Command ### user-manager/database/migrate-legacy-db **Package:** userman-5 **Type:** Command ### user-manager/database/optimize-db **Package:** userman-5 **Type:** Command ### user-manager/database/save **Package:** userman-5 **Type:** Command ## user-manager/generate-report **Package:** userman-5 **Type:** Command ## user-manager/limitation **Package:** userman-5 **Type:** Directory ## user-manager/monitor **Package:** userman-5 **Type:** Command ## user-manager/payment **Package:** userman-5 **Type:** Directory ## user-manager/profile **Package:** userman-5 **Type:** Directory ## user-manager/profile-limitation **Package:** userman-5 **Type:** Directory ## user-manager/router **Package:** userman-5 **Type:** Directory ### user-manager/router/monitor **Package:** userman-5 **Type:** Command ### user-manager/router/reset-counters **Package:** userman-5 **Type:** Command ## user-manager/session **Package:** userman-5 **Type:** Directory ### user-manager/session/close-session **Package:** userman-5 **Type:** Command ## user-manager/user **Package:** userman-5 **Type:** Directory ## user-manager/user-profile **Package:** userman-5 **Type:** Directory ### user-manager/user-profile/activate-user-profile **Package:** userman-5 **Type:** Command ### user-manager/user/add-batch-users **Package:** userman-5 **Type:** Command ### user-manager/user/generate-voucher **Package:** userman-5 **Type:** Command ### user-manager/user/group **Package:** userman-5 **Type:** Directory ### user-manager/user/monitor **Package:** userman-5 **Type:** Command --- ## user(Cli-reference) import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # user **Type:** Directory expired disabled period after which inactivity policy is applied specify action taken after inactivity timeout ## user/aaa **Type:** Settings Directory ## user/active **Type:** Directory radius by-romon ## user/expire-password **Type:** Command ## user/group **Type:** Directory ## user/settings **Type:** Settings Directory ## user/ssh-keys **Package:** security **Type:** Directory only for adding new keys ### user/ssh-keys/import **Package:** security **Type:** Command ### user/ssh-keys/private **Package:** security **Type:** Directory #### user/ssh-keys/private/import **Package:** security **Type:** Command --- ## zerotier import {ArgTableRow} from '@site/src/components/common'; import {ArgTable} from '@site/src/components/common'; ----------- # zerotier **Package:** zerotier **Type:** Directory ## zerotier/controller **Package:** zerotier **Type:** Directory ### zerotier/controller/member **Package:** zerotier **Type:** Directory ## zerotier/interface **Package:** zerotier **Type:** Directory ## zerotier/peer **Package:** zerotier **Type:** Directory ### zerotier/peer/hint **Package:** zerotier **Type:** Directory --- ## List of available Apps | App | Description | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | HA-otbr-matter | Home automation software with Matter and Thread support optimized for hAP be Media | | adventurelog | AdventureLog is a travel blog and photo journal web application | | babybuddy | A buddy for babies! Helps caregivers track sleep, feedings, diaper changes, and tummy time to learn about and predict baby's needs without (as much) guess work | | backrest | Web-based backup solution with support for local and cloud storage backends | | birdnet-go | Realtime BirdNET soundscape analyzer | | caddy | Caddy 2 is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go. | | calibre-web | A clean interface for browsing, reading and downloading eBooks using an existing Calibre database | | chr | Cloud Hosted Router - RouterOS Virtual Machine | | cinny | Matrix client focusing primarily on simple, elegant and secure interface | | cloudflared | Client for Cloudflare Tunnel, a daemon that exposes private services through the Cloudflare edge. | | code-server | Code-server is VS Code running on a remote server, accessible through the browser. | | conduit | Conduit is a simple, fast and reliable chat server powered by Matrix | | convertx | ConvertX is a self-hosted online file converter | | copyparty | Turn almost any device into a file server with resumable uploads/downloads using any web browser | | cryptpad | CryptPad is a collaborative office suite that is end-to-end encrypted and open-source. | | diagrams-net | diagrams.net (formerly draw.io) is free self-hosted diagram software. | | docker-with-dockge | Fancy, easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager. | | docker-with-komodo | Komodo is a web app to provide structure for managing your servers, builds, deployments, and automated procedures. | | docker-with-portainer | Portainer Community Edition (CE) is a lightweight platform that effortlessly delivers containerized applications. | | docmost | Modern wiki and documentation platform built for teams | | elasticsearch | Open source, distributed search and analytics engine built for speed, scale, and AI applications | | element | Matrix client focused on usability, accessibility, and broad compatibility | | excalidraw | Virtual whiteboard for sketching hand-drawn like diagrams | | filegator | Free, open-source, self-hosted web application for managing files and folders. | | firefox | Free and open-source web browser developed by the Mozilla Foundation | | forgejo | Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job. | | fossil | Simple, high-reliability, distributed SCM (Software Configuration Management) system | | frigate | An open source NVR built around real-time AI object detection. All processing is performed locally on your own hardware, and your camera feeds never leave your home. | | gitea | Self-hosted Git service with web interface | | gitlab | Git source code repository host | | goaway | Lightweight DNS server with web interface for ad blocking and DNS filtering | | grafana | Open source analytics and interactive visualization web application | | hedgedoc | Collaborative markdown editor with real-time collaboration | | home-assistant | Home automation software | | immich | Immich is a high performance self-hosted photo and video backup solution | | influxdb | InfluxDB is the time series data platform designed to handle high write and query workloads | | jackett | API Support for your favorite torrent trackers | | jellyfin | Free and open-source media server | | jupyter-notebook | Web-based interactive development environment for notebooks, code, and data | | kimai | Kimai is a free & open source timetracker designed for freelancers, agencies and companies | | librenms | Autodiscovering PHP/MySQL-based network monitoring system | | librespeed | Free and Open Source Speed Test. No Flash, No Java, No Websocket, No Bullshit. | | lidarr | Lidarr is a music collection manager for Usenet and BitTorrent users. | | livebook | Automate code & data workflows with interactive Elixir notebooks | | lorawan-stack | An open source LoRaWAN network stack suitable for large, global and geo-distributed public and private networks as well as smaller networks | | mediamanager | MediaManager is modern software to manage your TV and movie library. It is designed to be a replacement for Sonarr, Radarr, Overseerr, Unpackerr and Jellyseerr. It supports TVDB and TMDB for metadata, supports OIDC and OAuth 2.0 for authentication and supports Prowlarr and Jackett. | | memos | A modern, open-source, self-hosted knowledge management and note-taking platform designed for privacy-conscious users and organizations. | | metube | Web GUI for youtube-dl (using the yt-dlp fork) with playlist support. Allows you to download videos from YouTube and dozens of other sites. | | mikrodash | The Ultimate MikroTik RouterOS Dashboard. | | minio | High-performance object storage server compatible with Amazon S3 | | mosquitto | Eclipse Mosquitto MQTT message broker | | myip | IP information tool that provides detailed information about your IP address and network | | n8n | Workflow automation tool for connecting apps and services | | netbox | Solution for modeling and documenting modern networks | | nextcloud | Self-hosted productivity platform which provides private and secure functions for file sharing, collaborative work, and more | | nextcloud-whiteboard | The official whiteboard app for Nextcloud. Create and share whiteboards with real-time collaboration. | | nocodb | No-code platform that turns any database into a collaborative workspace | | nodered | Low-code programming for event-driven applications | | ntfy | Ntfy lets you send push notifications to your phone or desktop via scripts from any computer, using simple HTTP PUT or POST requests | | nzbget | Nzbget is a usenet downloader for downloading from information given in nzb files | | odoo | Odoo is a suite of open source business apps that cover all your company needs: CRM, eCommerce, accounting, inventory, point of sale, project management, etc. | | onlyoffice-docs | ONLYOFFICE Document Server is an online office suite comprising viewers and editors for texts, spreadsheets and presentations, fully compatible with Office Open XML formats: .docx, .xlsx, .pptx and enabling collaborative editing in real time. | | openwebrx | a simple web-based software defined radio receiver | | openwebui-ollama | User-friendly WebUI for LLMs (formerly Ollama WebUI) bundled with Ollama | | otbr | OpenThread Border Router optimized for use with hAP be Media | | paperless-ngx | Paperless-ngx is a community-supported open-source document management system that transforms your physical documents into a searchable online archive so you can keep, well, less paper. | | partdb | Part-DB is a web-based tool for organizing parts and components used in electronic circuits | | pihole | Network-wide Ad Blocking | | plex | Plex organizes video, music and photos from personal media libraries and streams them to smart TVs, streaming boxes and mobile devices | | pmacct-netflow | Pmacct based netflow collector with db and sample grafana dashboard visualization | | prowlarr | Prowlarr is an indexer manager/proxy built on the popular arr .net/reactjs base stack to integrate with your various PVR apps. Prowlarr supports both Torrent Trackers and Usenet Indexers. It integrates seamlessly with Sonarr, Radarr, Lidarr, and Readarr offering complete management of your indexers with no per app Indexer setup required (we do it all). | | rabbitmq | Open source multi-protocol messaging broker with AMQP and MQTT support | | radarr | Radarr is a movie collection manager for Usenet and BitTorrent users | | redlib | Private front-end for Reddit written in Rust | | restic-server | REST server for Restic backup client with support for remote backups | | roundcube | Web-based IMAP email client with modern interface | | rustfs | High-performance object storage server compatible with Amazon S3 | | searxng | Privacy-respecting, hackable metasearch engine | | smokeping | SmokePing is a deluxe latency measurement tool. It can measure, store and display latency, latency distribution and packet loss. | | snipeit | Open source asset management | | solr | Open-source enterprise-search platform | | sonarr | Sonarr is a personal video recorder tailored for Usenet and BitTorrent users | | sonatype-nexus | Single source of truth for all your internal and third-party binaries, components, packages, and AI models | | speedketchup | Run periodic internet speed test, store, display results with builtin web server | | stalwart | The open-source powerhouse combining modern email and collaboration features with unmatched security, speed, and scalability. | | syncthing | Continuous file synchronization program. It synchronizes files between two or more computers | | technitium | Technitium DNS Server is an open source authoritative as well as recursive DNS server that can be used for self hosting a DNS server for privacy & security. | | transmission | BitTorrent Client | | trip | Minimalist POI map tracker and trip planner | | upsnap | A simple wake on lan web app written with SvelteKit, Go and PocketBase | | uptime-kuma | A self-hosted monitoring tool | | urbackup-client | UrBackup client for backing up data to UrBackup server | | urbackup-server | Client/Server network backup system with web interface for management | | vaultwarden | An alternative server implementation of the Bitwarden Client API, written in Rust and compatible with official Bitwarden clients | | victoria-logs | Fast, cost-effective, and easy-to-use log database by VictoriaMetrics. A simple, powerful solution | | victoria-metrics | A fast, cost-effective, scalable TSDB in one easy-to-deploy binary. | | viseron | Self-hosted, local only NVR and AI Computer Vision software. With features such as object detection, motion detection, face recognition and more, it gives you the power to keep an eye on your home, office or any other place you want to monitor. | | wallabag | Self-hosted read-it-later application | | warracker | Web application for tracking warranties and product information | | wbo | WBO is an online collaborative whiteboard that is simple, easy to use and open-source | | webtop | Alpine-based container containing XFCE desktop environment via any modern web browser. | | wordpress | Content management system for websites and blogs | | zabbix | Enterprise-Class Open Source Network Monitoring | | zulip | Zulip is an organized team chat app for distributed teams of all sizes. | --- ## Apps #### Summary **Sub-menu:** `/app` **Packages required:** `container` The App menu provides a catalog of applications that can be deployed in a couple of clicks. Each app can consist of one or multiple pre-configured containers and the necessary RouterOS configuration such as firewall rules and address translation will be applied automatically. This catalog is prepared and maintained by MikroTik, but the container images get sourced from multiple registries such as Docker Hub, GCR and Quay. The configuration parameters, however, can be edited before enabling an app, and the applied yaml file can always be viewed. #### Requirements The App system inherits the same requirements as the Container package: - **Architecture Support:** arm64 and x86 architectures. - **Container Package:** Must be installed. - **Device Mode:** Container mode must be enabled (requires physical access and device reset). - **External Storage:** Highly recommended for optimal performance. - **Memory Requirements:** Adequate RAM for container operations (16MB SPI flash devices may require external storage for images). - **Architecture Limitations:** Devices with EN7562CT CPU (like hEX Refresh) are not supported. #### Security Considerations As with the underlying Container system, the App menu inherits security implications: - Physical access is required to initially enable container support. - Once enabled, containers can be managed remotely. - Compromised devices can use containers to install malicious software. - Device security is equivalent to the security of running containers. - Third-party container images may introduce security vulnerabilities. ## Properties | Property | Type | Default | Description | | :-- | :-- | :-- | :-- | | **auto-update** | *yes* | *no* | *no* | Enables or disables automatic updating when a new container image version is available. | | **check-certificate** | *yes* | *no* | *yes* | Verifies the registry certificate before pulling the container image. | | **container-command-lines** | *string* | *(empty)* | Specifies the command-line argument(s) to pass to the application when starting the container. | | **devices** | *string* | *(empty)* | Specifies additional hardware devices to pass through to the container application. | | **environment** | *string* | *(empty)* | Defines environment variables to be available to the running application. Specify as a list of key-value pair(s). | | **extra-mounts** | *string* | *(empty)* | Specifies additional mount points to attach to the container. | | **firewall-redirects** | *string* | *(empty)* | Configures port redirection from the host device to the container. | | **network** | *default* | *lan* | *internal* | *default* | Specifies which network the container will use: **internal** (behind NAT), **lan** (on the LAN network), or **default** (varies per application; can be internal or lan). | | **network-outgoing-access** | *yes* | *no* | *yes* | Allows network outgoing access for the specific container app, when set to `no`, a mangle drop rule is created. | | **pvid** | *integer* | *1* | Sets the Port VLAN ID (PVID) for the container's virtual Ethernet interface in the bridge. | | **required-hw-devices** | *string* | *(empty)* | Hardware devices that must be present on the host for the container to start. This property is configurable only after adding the YAML configuration. **Compose format:**`[host-hw-device]:[device-in-app]` | | **required-mounts** | *string* | *(empty)* | Mount directories required for the container to start. This property is configurable only after adding the YAML configuration. **Compose format:**`[dir-on-host]:[dir-in-app]` | | **use-https** | *yes* | *no* | *yes* | Uses HTTPS for the application URL. This option will not work on devices that do not support cloud services. | | **yaml** | *string* | *(empty)* | Provides the YAML composition for the application. See the documentation for configuration examples. | ## Read-only Properties | Property | Type | Default | Description | | :-- | :-- | :-- | :-- | | **app-size** | | | The total size of the application. | | **app-store-url** | *string* | | The URL of the app store from which the application was installed. | | **cpu-usage** | | | The current CPU usage percentage by the application. | | **custom** | *yes* | *no* | | Indicates whether the application is a custom application created by the user. | | **data-size** | | | The size of the data stored by the application. | | **default-credential** | *string* | | The default credentials required for the application. | | **default-network** | *lan* | *internal* | | The default network used by the application. Valid values are `lan` or `internal`. | | **description** | *string* | | The application description as defined in the `descr` parameter of the YAML configuration. | | **from-app-store** | *yes* | *no* | | Indicates whether the application was installed from a custom app store. | | **interface** | *string* | | The VETH interface used by the application. | | **ip-address** | *IP* | | The IP address assigned to the VETH interface. | | **memory-current** | | | The amount of memory currently used by the application. | | **name** | *string* | | The application name as defined in the `name` parameter of the YAML configuration. | | **project-page** | *string* | | The application project page URL as defined in the `page` parameter of the YAML configuration. | | **running** | | | Indicates whether the application is currently running. | | **status** | *acquire veth* | *configuring container(s)* | *downloading/extracting* | *starting* | | The current status of the application. Possible values indicate the application is acquiring a VETH interface, configuring containers, downloading/extracting, or starting. | | **ui-url** | *string* | | The generated URL for the application's web interface, if available. | | **variables-to-be-used-in-environment** | | | A list of all variables present in the application environment. | #### Setup Wizard The App menu includes a setup wizard (button "Setup" in the GUI, or command `/app/setup`). This wizard automates all the networking, storage, and registry setup that would otherwise require multiple manual steps. ##### Step 1: Storage Selection Select a storage disk for application installation. The system automatically detects available formatted disks drives (such as nvme1, usb1, disk1, and similar devices). If no suitable disk appears in the list, you must first format the disk using either the ext4 or btrfs file system, then mount it through the `/disk` menu. **Requirements:** - A minimum of 100 MB/s sequential read/write speed is recommended. - A minimum of 10,000 random IOPS (Input/Output Operations Per Second) is recommended. - Use the `/disk/test` command to verify storage performance before proceeding. - External storage devices are highly recommended for optimal performance. ##### Step 2: Bridge Configuration Select the LAN bridge interface for container networking. This configuration enables automatic port forwarding and application autodiscovery on the local network. The setup wizard automatically configures the following: - Virtual ethernet (veth) interface creation - Addition of the veth interface to the configured bridge - NAT rules for outbound connectivity ##### Step 3: IP Configuration Define the router's IP address to enable application access. The system automatically detects the primary IP address; however, manual configuration is supported for complex network setups. The specified IP address serves the following purposes: - Generating application UI URLs. - Creating automatic port forwarding rules. - Providing WebFig integration links. ##### Completion Once you complete the setup wizard, the App system is ready for immediate use. You can enable applications directly through the interface. The system automatically handles all underlying container configuration. #### Configuration App configuration is accessible through `/app/settings` and provides a simplified setup compared to manual Container configuration ## Properties | Property | Type | Default | Description | | :-- | :-- | :-- | :-- | | **app-store-urls** | *string* | *(empty)* | URL to a custom app store. The URL must point to a YAML array where each application is an element within the array. | | **auto-update** | *yes* | *no* | *no* | Global setting that enables automatic updates for all installed applications packages. | | **disk** | *string* | *(empty)* | Global setting that specifies which disk will be used for storage operations. | | **download-path** | *string* | *(empty)* | Manually specifies the directory path where all downloaded content will be stored. | | **lan-bridge** | *string* | *(empty)* | Manually specifies the bridge interface that represents the local area network. | | **media-path** | *string* | *(empty)* | Manually specifies the directory path where all media files will be stored. | | **registry-mirrors** | *string* | *(empty)* | Specifies one or more registry mirror URLs addresses for container image retrieval. | | **router-ip** | *IP* | *(empty)* | Manually specifies the IP address at which the current RouterOS device can be reached. | | **show-in-webfig** | *yes* | *no* | *yes* | Controls whether links to enabled applications are displayed on the WebFig login page. | ### Auto-Configured Settings Certain parameters are initially configured automatically based on network detection. These values can always be manually overridden if required. | Property | Type | Default | Description | | :-- | :-- | :-- | :-- | | **assumed-router-ip** | *IP* | *(detected)* | Automatically detected network IP address of the RouterOS device. | | **assumed-lan-bridge** | *string* | *(detected)* | Automatically detected bridge interface used for LAN connectivity. | | **assumed-media-path** | *string* | *disk/media* | Default media storage path, typically located on the system disk. | | **assumed-download-path** | *string* | *disk/media/downloads* | Default download directory path, typically located within the media storage area. | #### Application Management Applications are managed through the `/app` interface, providing status monitoring and lifecycle control similar to the underlying `/container` system: ``` /app> print Flags: X - DISABLED, R - RUNNING Columns: NAME, UI-URL, MEMORY-CURRENT, APP-SIZE, DATA-SIZE, CATEGORY, DESCRIPTION ``` ##### Status Indicators and Metadata - **Flags:** - X (DISABLED) - Can indicate two states: not downloaded/installed (APP-SIZE and DATA-SIZE will be empty), or downloaded but disabled (APP-SIZE and DATA-SIZE show storage usage). - R (RUNNING) - Application actively running and accessible. - **UI-URL:** Direct web interface access URL when application is running. - **MEMORY-CURRENT:** Real-time memory consumption in MiB (only when running). - **APP-SIZE:** Container image storage consumption in MiB (shows space used when downloaded). - **DATA-SIZE:** Application persistent data size in KiB/MiB (shows configuration and user data). - **CATEGORY:** Application functional classification. - **DESCRIPTION:** Application functionality description. ##### Application Lifecycle Management ### Deployment Process Unlike manual Container deployment which requires multiple configuration steps (veth interface, bridge setup, environment variable, mount, and firewall rules), App deployment automates the entire process: 1. **Selection:** Choose an application from the catalog via CLI or WebFig. 2. **Download:** Automatic container image download and extraction. 3. **Network Setup:** Automatic veth interface and bridge configuration. 4. **Port Forwarding:** Automatic firewall rule creation for web access. 5. **Startup:** Container initialization with pre-configured settings. 6. **Access:** UI-URL becomes available for immediate web interface access. #### Cleanup Command The cleanup command provides complete application removal, including all associated data. This operation is destructive and irreversible: ``` /app> cleanup pihole App data will be lost, continue? [y/N]: ``` **Cleanup Process:** 1. Stops the running container. 2. Removes all application data and configuration files. 3. Deletes the container image from storage. 4. Resets the application to an uninstalled state (empty APP-SIZE and DATA-SIZE). 5. Removes network configuration specific to the application. :::warning All user data, configuration settings, and application state will be permanently lost. The application will return to its original catalog state and require complete reconfiguration if cleaned-up. ::: #### User-Addable Apps Starting with RouterOS v7.22, you can create your own custom apps using a compose YAML file. This lets experienced users build solutions that fit their specific network needs. How it works: - You write a compose YAML file that defines your app's structure and behavior - RouterOS processes this file to build a working application package - Your custom app can work with RouterOS features and APIs Why use it: - Build exactly what you need for your network - No need to wait for official app releases - Great for automation, custom routing, or specialized services - Declarative setup makes management easier ## Creating a Custom App with YAML You can create a custom container application using a YAML configuration file. This example demonstrates how to set up an Alpine Linux container that runs an iperf3 server for network performance testing. ### YAML Configuration Example ```routeros name: alpine-iperf descr: Alpine Linux container running iperf3 server page: https://iperf.fr/ category: network default-credential: none services: iperf: image: docker.io/alpine:latest ports: - 5201:5201:tcp - 5201:5201:udp command: /bin/sh -c "apk add --no-cache iperf3 && iperf3 -s" ``` ### Configuration Field Reference | Field | Description | |---|---| | `name` | Unique identifier for your custom app | | `descr` | Human-readable description of what the app does | | `page` | URL to the project's official documentation or website | | `category` | Classification group (e.g., network, system, utilities) | | `default-credential` | Authentication requirement (none, or specify username/password) | | `services` | Container service definitions | | `image` | Docker image to use for the container | | `ports` | Port mappings in format `host:container:protocol` | | `command` | Startup command executed inside the container | ### How This Example Works 1. **Base Image**: Uses the official Alpine Linux image from Docker Hub 2. **Package Installation**: Installs iperf3 network performance testing tool 3. **Server Mode**: Runs iperf3 in server mode (`-s` flag) to accept client connections 4. **Port Exposure**: Maps TCP and UDP port 5201 (iperf3's default port) to the host This configuration creates a container that acts as a network throughput testing server, allowing you to measure bandwidth between clients and this container. ## Adding a Custom App There are two ways to create a custom app: by importing a .yml file or by creating a blank app and editing its YAML directly. In this example, we'll add the alpine-iperf app we created using the compose file. For ease of use, we'll place it in the LAN bridge so that devices on our network can access it easily without requiring NAT. ### Method 1: Create a Blank App and Edit YAML First, create the app and assign it to the LAN network: ```routeros /app/add network=lan ``` By default, the app will be named "app". Next, add the YAML configuration. In the Terminal, run: ```routeros /app/edit app yaml ``` This opens a text editor where you can paste your YAML. After pasting, press Control+O to save your changes. Finally, enable the app to start it running. ### Method 2: Import from a File Alternatively, save your compose text to a file and upload it to the device. Then, set the file as the app's YAML using the following command: ```routeros /app/add yaml=[/file/get alpine-iperf.yml contents] ``` This method is useful when you have a pre-configured YAML file ready to import. #### Tips and Best Practices - **Storage:** For optimal performance and greater capacity, consider using external storage devices such as USB drive, SATA drive, or NVMe SSD. - **Memory:** Keep track of your application's memory consumption by running the `/app/print` command in the terminal. - **Updates:** Only update your system when required and deemed necessary. While automatic updates can provide security patches and new features, it's important to assess whether an update is needed for your specific use case before enabling or applying it. - **Networking:** The application automatically manages port forwarding and generates the necessary URL for external access. - **Data Persistence:** Your application data is stored in the designated storage path and will remain intact even after the application restarts or the system reboots. --- ## Container(Containers) import DocCardList from '@theme/DocCardList'; This section covers RouterOS container support, including container configuration, virtual Ethernet interfaces, storage, and application examples. Use it to run supported containerized services on RouterOS devices. **Sub-menu:** `/container` **Packages required:** `container` A container is MikroTik's implementation of Linux containers, allowing users to run containerized environments within RouterOS. The container feature works in the latest MikroTik RouterOS v7.x version. Containers are compatible with images from Docker Hub, GCR, Quay, or other providers, as well as those built on other devices, using the same formats supported by these providers. While RouterOS uses different syntax compared to Docker, it still achieves similar functionality. ## Disclaimer :::danger You need physical access to your RouterOS device to enable support for the container feature; it is disabled by default; - once the container feature is enabled, containers can be added/configured/started/stopped/removed remotely! - if your RouterOS device is compromised, containers can be used to easily install malicious software in your RouterOS device and over the network; - your RouterOS device is as secure as anything you run in a container; - if you run a container, there is no security guarantee of any kind; - running a 3rd party container image on your RouterOS device could open a security hole/attack vector/attack surface; - an expert with knowledge of how to build exploits will be able to jailbreak/elevate to root; ::: ### Security risks - When a security expert publishes his exploit research - anyone can apply such an exploit. - Someone can build a container image that can use the exploit AND provide a Linux root shell. - By using a root shell someone may leave a permanent backdoor/vulnerability in your RouterOS system even after the container image is removed and the container feature is disabled. - If a vulnerability is injected into the primary or secondary RouterBOOT (or vendor pre-loader), then even Netinstall may not be able to fix it. ## Requirements Container package is compatible with **arm, arm64** and **x86** architectures. Use of remote-image (similar to docker pull) functionality requires a lot of free space in main memory, 16MB SPI flash boards may use pre-built images on USB or other disk media. :::danger - An external disk supporting at least 100MB/s sequential read/write speed and 10K random iops is recommended. When using slower disks, container extraction times may become longer. - The Container package needs to be installed - For devices with EN7562CT CPU like the hEX Refresh, only [arm32v5](https://hub.docker.com/u/arm32v5) container images are supported, meaning a limited number of containers can be run. ::: **Sub-menu:** `/container` ## Properties | Property | Description | | :-- | :-- | | **auto-restart-interval**(string; Default: ) | Specify an interval at which Container will be restarted on Container failure. Example: 10s | | **cmd** (string; Default: ) | The main purpose of a CMD is to provide defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction as well. | | **comment** (*string*; Default: ) | Short description | | **dns** (string; Default: ) | If the container needs different DNS, it can be configured here | | **domain-name** (string; Default: ) | | | **entrypoint** (*string; Default*:) | An ENTRYPOINT allows you to specify an executable to run when starting the container. Example: `/bin/sh` | | **envlist** (*string; Default*: ) | List of environmental variables (configured under *`/container/envs`* ) to be used with the container | | **file** (*string; Default:* ) | A container \*tar.gz tarball if the container is imported from a file | | **hostname** (*string; Default:* ) | Assigning a hostname to a container helps in identifying and managing the container more easily | | **interface** (*string; Default:* ) | veth interface to be used with the container | | **logging** (*string; Default:* ) | if set to yes, all container-generated output will be shown in the RouterOS log | | **start-on-boot** (*string; Default:* ) | if set to yes, the container will be started automatically on device start-up. | | **mountlists** (*string; Default:* ) | mounts from /container/mounts/ sub-menu to be used with this container | | **mount** (*string; Default:* ) | specify a directory to be used as a mount | | **remote-image** (*string; Default:* ) | the container image name to be installed if an external registry is used (configured under `/container/config/set` registry-url=...) | | **root-dir** (*string; Default:* ) | used to save container store outside main memory | | **stop-signal** (*string; Default*: 15) | defines which Linux signal is sent to terminate the container if it is still running after 10 seconds. Different signals may allow graceful shutdown, immediate termination, or trigger application-specific actions | | **workdir** (*string*; Default: ) | the working directory for cmd entrypoint | | **devices**(*string*; Default: ) | passes through a physical device to the container | | **cpu-list**(*string*; Default: ) | specifies which CPU cores the container is allowed to run on | | **user**(*string*; Default: ) | sets the user and group the container process runs as before execution. | | **memory-high**(*int*; Default: ) | RAM usage limit in bytes for a specific container | | **memory-max** (*int*; Default: ) | max RAM usage limit in bytes per container (The container process will be terminated if the memory-max value is smaller than the container memory-current) starting 7.23, this parameter cannot be set lower than 1MB, to avoid a situation where the container is terminated too early in the startup process | :::warning By default the container uses the same DNS as configured in the `/ip/dns` sub-menu. If no DNS is configured here and the container's `dns` parameter is not specified, the container will not start! ::: ### Menu specific commands | Property | Description | | :-- | :-- | | **update** | Updates the container image. Automatically pulls from container repository and extracts it, replacing the original image. | | **kill** | Kills the specified running container. | | **restart** | Restarts the specified running container. | | **repull** | Re-pulls/extracts the container image. | | **shell** | Enters the container shell of a running container. | | **run** | Starts the container and enters its shell. Useful if container shuts down after running. | ## Container configuration **Sub-menu:** `/container/config` | Property | Description | | :-- | :-- | | **registry-url** | external registry url from where the container will be downloaded (default: `https://lscr.io/`) | | **tmpdir** | container extraction directory | | **memory-high** | RAM usage limit in bytes 1 - unlimited | | **username** | Specifies the username for authentication (starting from ROS 7.8) | | **password** *[sensitive](../getting-started/configuration-management/list-of-menus-with-sensitive-parameters.md)* | Specifies the password for authentication (starting from ROS 7.8) | ## Examples ### Running Pi-hole #### Prerequisites 1. RouterOS device with RouterOS v7.4beta or later and **installed Container package -** [How to install packages](../getting-started/installation-and-upgrade/packages.md) 2. Physical access to a device to enable container mode - will be explained down below 3. Attached HDD, SSD or USB drive for storage - formatted with a filesystem supported by RouterOS - [How to format/manage disks](../hardware/disks/index.md) #### Steps to run Pi-hole 1. Enable Container mode and follow the instructions the command gives you (read more about [Device-mode](../system-information-and-utilities/device-mode.md). You will need to confirm the device-mode with a press of the [reset button](../getting-started/configuration-management/routeros-configuration-reset.md), or a cold reboot (if using Containers on x86): ```routeros /system/device-mode/update container=yes ``` :::danger [Device-mode](../system-information-and-utilities/device-mode.md) limits container use by default, before granting container mode access - make sure your device is fully secured. ::: 2. Create a new veth interface and assign an IP address in a range that is unique in your network: ```routeros /interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1 ``` :::info The following configuration is equivalent to "bridge" networking mode in other Container engines such as Docker. It is possible to create a "host" equivalent configuration as well. **Important:** One veth interface can be used for many Containers. You can create multiple veth interfaces to create [isolated](./index.md#isolated-containers) networks for different Containers. ::: 3. Create a new [bridge](../bridging-and-switching/index.md) that is going to be used for your Containers and assign the same IP address that was used for the veth interface's gateway: ```routeros /interface/bridge/add name=containers /ip/address/add address=172.17.0.1/24 interface=containers ``` 4. Add the veth interface to your newly created bridge: ```routeros /interface/bridge/port/add bridge=containers interface=veth1 ``` 5. Create a NAT for outgoing traffic: ```routeros /ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24 ``` 6. Create environment variables for the Container: ```routeros /container/envs/add list=ENV_PIHOLE key=TZ value="Europe/Riga" /container/envs/add list=ENV_PIHOLE key=FTLCONF_webserver_api_password value="mysecurepassword" /container/envs/add list=ENV_PIHOLE key=DNSMASQ_USER value="root" ``` 7. Create mounted volumes for the Container: ```routeros /container/mounts/add list=MOUNT_PIHOLE_PIHOLE src=disk1/volumes/pihole/pihole dst=/etc/pihole /container/mounts/add list=MOUNT_PIHOLE_DNSMASQD src=disk1/volumes/pihole/dnsmasq.d dst=/etc/dnsmasq.d ``` :::warning `src=` points to RouterOS location (could also be `src=disk1/etc_pihole` if, for example, you decide to put configuration files on external USB media), `dst=` points to defined location (consult containers manual/wiki/github for information on where to point). If `src` directory does not exist on first time use then it will be populated with whatever container has in `dst` location. ::: :::warning It is highly recommended to place any Container volume on an attached disk to your RouterOS device. Avoid placing Container volumes on the built-in storage. ::: 8. Configure to use a specific Container repository, for example, to use Docker.io: ```routeros /container/config/set registry-url=https://registry-1.docker.io tmpdir=disk1/tmp ``` 9. Add a Container: ```routeros /container/add remote-image=pihole/pihole interface=veth1 root-dir=disk1/images/pihole mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole ``` :::tip If you wish to see container output in `/log/print` , then add `logging=yes` when creating a Container, root-dir should point to an external drive. It's not recommended to use internal storage for Containers. **Important:** There are multiple ways you can get a Container image, check the [Adding a Container image](./index.md#adding-a-container-image) section if you need an alternative way of adding a Container image. **Important:** Adding a Container will start downloading or extracting it, the Container itself will not be started after it has been added, you need to start it manually for the first time after it has been downloaded/extracted. ::: 10. Check the status of your Container and wait until downloading/extracting has been finished and the `status=stopped` : ```routeros /container/print ``` 11. Start the Container: ```routeros /container/start pihole ``` 12. Create a port forwarding for your Container: ```ros /ip/firewall/nat add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=80 protocol=tcp to-addresses=172.17.0.2 to-ports=80 ``` 13. You should be able to access the Pi-hole web panel by navigating to `http://192.168.88.1/admin/` in your web browser. 14. To start using Pi-hole on your devices, change their DNS configuration to use `192.168.88.1` as your DNS server. ### Adding a Container image There are multiple ways you can get a Container image running on your RouterOS device. Check the examples below. #### Option A: Get an image from an external library Set registry-url (for downloading containers from the Docker registry) and set extract directory (tmpdir) to the attached USB media: ```ros /container/config/set registry-url=https://registry-1.docker.io tmpdir=disk1/tmp ``` pull an image: ```ros /container/add remote-image=pihole/pihole interface=veth1 root-dir=disk1/images/pihole mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole ``` The image will be automatically pulled and extracted to root-dir. Status can be checked by using ```ros /container/print ``` #### Option B: Import image from PC You can use your PC running either Docker or Podman to download your required container image and save it to an archive. We recommend using [Podman](https://podman.io/docs/installation) since it is easier to build and download containers for specific architectures using Podman. 1. Download your required image based on the architecture of your RouterOS device. ```routeros #For ARM64 podman pull --arch=arm64 docker.io/pihole/pihole #For ARM podman pull --arch=arm docker.io/pihole/pihole #For AMD64 podman pull --arch=amd64 docker.io/pihole/pihole ``` 2. Save the container image to an archive. ```routeros podman save pihole > pihole.tar ``` 3. Upload the archive to your RouterOS device, for example: ```routeros rsync -av pihole.tar admin@192.168.88.1:/data/disk1/ ``` :::tip You can also use Winbox to upload files! ::: 4. Create a Container on your RouterOS device using the uploaded container image archive file. ```routeros /container/add file=disk1/pihole.tar interface=veth1 root-dir=disk1/pihole mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole ``` #### Option C: Build an image on PC You can build your own Containers and use them on your RouterOS device. While you can build Containers using Docker, we recommend using [Podman](https://podman.io/docs/installation) since it is easier to build Containers for a specific architecture using Podman. 1. Get source files for your required Container image, for example by using git. ```routeros git clone https://github.com/pi-hole/docker-pi-hole.git cd docker-pi-hole ``` 2. Build the Container image by specifying the Dockerfile or Containerfile and the target architecture. ```routeros #For ARM64 podman build --platform linux/arm64 --tag pihole -f ./src/Dockerfile #For ARM podman build --platform linux/arm --tag pihole -f ./src/Dockerfile #For AMD64 podman build --platform linux/amd64 --tag pihole -f ./src/Dockerfile ``` 3. Save the container image to an archive. ```routeros podman save pihole > pihole.tar ``` 4. Upload the archive to your RouterOS device, for example. ```routeros rsync -av pihole.tar admin@192.168.88.1:/data/disk1/ ``` :::tip You can also use Winbox to upload files! ::: 5. Create a Container on your RouterOS device using the uploaded container image archive file. ```routeros /container/add file=disk1/pihole.tar interface=veth1 root-dir=disk1/pihole mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole ``` ##### Alternative: Using Docker to build Container images To use Dockerfile and make your own docker package - docker needs to be installed as well as buildx or another builder toolkit. After installation check if extra architectures are available: ```bash docker buildx ls ``` should return: ```bash NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS default * docker default default running linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6 ``` If not - install extra architectures: ```bash docker run --privileged --rm tonistiigi/binfmt --install all ``` Pull or create your project with Dockerfile included and build, extract image (adjust --platform if needed): ```bash git clone https://github.com/pi-hole/docker-pi-hole.git cd docker-pi-hole docker buildx build --no-cache --platform arm64 --output=type=docker -t pihole . docker save pihole > pihole.tar ``` Upload *pihole.tar* to your RouterOS device. Images and objects on the Linux system can be `pruned` Create a container from the tar image ```ros /container/add file=pihole.tar interface=veth1 mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole ``` ### Networking examples #### Bridge with NAT In this networking setup, all Containers use the same veth interface and communicate with each other without any Firewall restrictions, but you need to forward ports in order to allow access to a Container's port. For example, a database Container needs to communicate with a web application Container; the web application needs the port `80` to be exposed to the world, but the database Container does not need any ports to be exposed to the world. - The network configuration: ```routeros /interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1 /interface/bridge/add name=containers /ip/address/add address=172.17.0.1/24 interface=containers /interface/bridge/port/add bridge=containers interface=veth1 /ip/firewall/nat add chain=srcnat action=masquerade src-address=172.17.0.0/24 add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=80 protocol=tcp to-addresses=172.17.0.2 to-ports=80 ``` - The database Container configuration: ```routeros /container/envs/add list=ENV_POSTGRES key=POSTGRES_DB value="webapp" /container/envs/add list=ENV_POSTGRES key=POSTGRES_PASSWORD value="" /container/envs/add list=ENV_POSTGRES key=POSTGRES_USER value="webapp" /container/envs/add list=ENV_POSTGRES key=PGDATA value="/var/lib/postgresql/data/pgdata" /container/envs/add list=ENV_POSTGRES key=POSTGRES_INITDB_ARGS value="--encoding='UTF8' --lc-collate='C' --lc-ctype='C'" /container/mounts/add list=MOUNT_POSTGRES src=disk1/volumes/postgres/data dst=/var/lib/postgresql/data /container/add remote-image=postgres:15 interface=veth1 root-dir=disk1/images/postgres mountlists=MOUNT_POSTGRES envlist=ENV_POSTGRES name=postgres start-on-boot=yes logging=yes ``` - The webapp Container configuration: ```routeros /container/add remote-image=dpage/pgadmin4 interface=veth1 root-dir=disk1/images/pgadmin name=pgadmin start-on-boot=yes logging=yes ``` In this example, the `pgadmin` port 80 is accessible to everyone, but the `postgres` port 5432 is not accessible to everyone; it can only be accessed through either `pgadmin` as `127.0.0.1` or through the RouterOS device running the Container as `172.17.0.2`. #### Isolated Containers In this networking setup, you have multiple Containers and you want to make sure that some of them can communicate without Firewall restrictions, but some need to be isolated from other Containers. For example, you might want to create two database Containers and isolate them. - The network configuration. ```routeros /interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1 /interface/veth/add name=veth2 address=172.18.0.2/24 gateway=172.18.0.1 /interface/bridge/add name=containers1 /interface/bridge/add name=containers2 /ip/address/add address=172.17.0.1/24 interface=containers1 /ip/address/add address=172.18.0.1/24 interface=containers2 /interface/bridge/port/add bridge=containers1 interface=veth1 /interface/bridge/port/add bridge=containers2 interface=veth2 /ip/firewall/nat add chain=srcnat action=masquerade src-address=172.17.0.0/24 add chain=srcnat action=masquerade src-address=172.18.0.0/24 add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=81 protocol=tcp to-addresses=172.17.0.2 to-ports=80 add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=82 protocol=tcp to-addresses=172.18.0.2 to-ports=80 ``` - The first and second database container configurations. ```routeros /container/envs/add list=ENV_POSTGRES1 key=POSTGRES_DB value="webapp1" /container/envs/add list=ENV_POSTGRES1 key=POSTGRES_PASSWORD value="" /container/envs/add list=ENV_POSTGRES1 key=POSTGRES_USER value="webapp1" /container/envs/add list=ENV_POSTGRES1 key=PGDATA value="/var/lib/postgresql/data/pgdata" /container/envs/add list=ENV_POSTGRES1 key=POSTGRES_INITDB_ARGS value="--encoding='UTF8' --lc-collate='C' --lc-ctype='C'" /container/mounts/add list=MOUNT_POSTGRES1 src=disk1/volumes/postgres1/data dst=/var/lib/postgresql/data /container/add remote-image=postgres:15 interface=veth1 root-dir=disk1/images/postgres1 mountlists=MOUNT_POSTGRES1 envlist=ENV_POSTGRES1 name=postgres1 start-on-boot=yes logging=yes ``` ```routeros /container/envs/add list=ENV_POSTGRES2 key=POSTGRES_DB value="webapp2" /container/envs/add list=ENV_POSTGRES2 key=POSTGRES_PASSWORD value="" /container/envs/add list=ENV_POSTGRES2 key=POSTGRES_USER value="webapp2" /container/envs/add list=ENV_POSTGRES2 key=PGDATA value="/var/lib/postgresql/data/pgdata" /container/envs/add list=ENV_POSTGRES2 key=POSTGRES_INITDB_ARGS value="--encoding='UTF8' --lc-collate='C' --lc-ctype='C'" /container/mounts/add list=MOUNT_POSTGRES2 src=disk1/volumes/postgres2/data dst=/var/lib/postgresql/data /container/add remote-image=postgres:15 interface=veth2 root-dir=disk1/images/postgres2 mountlists=MOUNT_POSTGRES2 envlist=ENV_POSTGRES2 name=postgres2 start-on-boot=yes logging=yes ``` - The first and second webapp container configurations. ```routeros /container/add remote-image=dpage/pgadmin4 interface=veth1 root-dir=disk1/images/pgadmin1 name=pgadmin1 start-on-boot=yes logging=yes ``` ```routeros /container/add remote-image=dpage/pgadmin4 interface=veth2 root-dir=disk1/images/pgadmin2 name=pgadmin2 start-on-boot=yes logging=yes ``` In this example, `pgadmin1` is able to reach `postgres1`, but is not able to reach `postgres2`. Similarly, `pgadmin2` is able to reach `postgres2`, but is not able to reach `postgres1`. #### Container in Layer2 network In this networking setup, your Container is directly attached to a Layer2 network with other physical network devices. This networking setup is equivalent to "host" networking mode on other Container engines such as Docker. :::danger In this networking setup, all the ports on your Container are exposed. This is considered insecure, but does slightly improve the Container's networking performance. ::: - The networking configuration. ```routeros /interface/veth/add name=veth1 address=192.168.88.2/24 gateway=192.168.88.1 /interface/bridge/port/add bridge=bridge interface=veth1 ``` - In case your RouterOS device has services running on the same port, you need to disable them. ```routeros /ip/service/disable [find where name=www] ``` - The webapp configuration. ```routeros /container/add remote-image=dpage/pgadmin4 interface=veth1 root-dir=disk1/images/pgadmin name=pgadmin start-on-boot=yes logging=yes ``` In this example, `pgadmin` Container does not need port forwarding, but all other ports that the Container is using are now accessible to others on the same Layer2 network. This type of setup should only be used when your application requires that the Container has an IP address in the same Layer2 network such as applications that use broadcast traffic for service discovery (in most cases such requirements can still be bypassed by using NAT). ### IPv4 and IPv6 for Container In this networking setup your Container will be able to communicate over IPv4 and IPv6. The solution is based on the [Bridge with NAT](./index.md#bridge-with-nat) networking setup. - The network configuration. ```routeros /ip/address add address=172.17.0.1/24 interface=containers /ip/firewall/nat add action=masquerade chain=srcnat src-address=172.17.0.0/24 add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=80 protocol=tcp to-addresses=172.17.0.2 to-ports=80 /ipv6/address add address=fd8d:5ad2:24:2::1 interface=containers /ipv6/firewall/nat add action=masquerade chain=srcnat src-address=fd8d:5ad2:24:2::/64 add action=dst-nat chain=dstnat dst-address=fd8d:5ad2:24:2::1 dst-port=80 protocol=tcp to-addresses=fd8d:5ad2:24:2::2 to-ports=80 /interface/veth add address=172.17.0.2/24,fd8d:5ad2:24:2::2/64 gateway=172.17.0.1 gateway6=fd8d:5ad2:24:2::1 name=veth1 /interface/bridge/port/add bridge=containers interface=veth1 ``` - The webapp container configuration. ```routeros /container/add remote-image=nginx interface=veth1 root-dir=disk1/images/nginx name=nginx start-on-boot=yes logging=yes ``` ## Healthcheck Starting RouterOS 7.23 healthcheck support has been implemented in RouterOS. Healthcheck is a mechanisms that helps verify that the application within the container is running correctly. Healthchecks rely on standard exit codes. The command used for the healthcheck should return 0 when the application is healthy and a non-zero exit code when it is unhealthy. In most cases, on containers running a web interface, a simple HTTP GET request to localhost is enough to verify if the application is responding properly. | Property | Description | | :-- | :-- | | **healthcheck-cmd** (*string*; *Default*:)| command used for healthcheck | | **healthcheck-interval** (*time*; *Default*: 00:00:30)| time interval in format HH:MM:SS | | **healthcheck-retries** (*int*; *Default*: 3)| in the case of a failed check - number of retries before container application is considered unhealthy| | **healthcheck-start-interval** (*time*; *Default*: 00:00:05)| time between healthchecks in the start period | | **healthcheck-start-period** (*time*; *Default*: 00:00:00) | provides time for the container to start. any failures within the start period will not be added to the retries counter| | **healthcheck-status** (*string*)| current health status of container. displays the current status of the application within the container as well as the output from the probe| | **healthcheck-timeout** (*time*; *Default*: 00:00:30)| if healthcheck probing takes longer than the specified period, the check will count as a fail | ### Healthcheck example For this example we will be setting up a HomeAssistant container and set up a simple healthcheck on it. For a guide on setting up a HomeAssistant container, please refer to our [HomeAssistant setup guide](./user-guides/container-homeassistant.md) To set up the E-mail tool. Please refer to our [E-mail documentation page](../system-information-and-utilities/e-mail.md) 1. Check your container name ```ros [admin@ROSE] > container print Flags: S - STOPPED, R - RUNNING Columns: NAME, ROOT-DIR, INTERFACE, MEMORY-CURRENT, CPU-USAGE, CONTAINER-SIZE, DATA-SIZE, TAG # NAME ROOT-DIR INTERFACE MEMORY-CURRENT CPU-USAGE CONTAINER-SIZE DATA-SIZE TAG 1 S home-assistant /nvme1/apps/home-assistant/home-assistant_root veth-home-assistant 0 2201.9MiB 471.9KiB docker.io/homeassistant/home-assistant:latest ``` 1. After a container has been created, we can enable healthcheck on it by setting the healthcheck command. For this specific container. We can increase the healthcheck-interval as well as specify a start-period as HomeAssistant is a heavy container and may start slower on some devices. ```ros /container/set home-assistant healthcheck-cmd="curl -f http://localhost:8123" healthcheck-interval="00:01:00" healthcheck-start-period="00:02:00" ``` If successful and the container starts - you should see the container running with the "Healthy" status. Additionally, the healthcheck-status field is populated with the current status of the container as well as the output from the curl command. ```ros [admin@ROSE] > container print proplist=name,healthcheck-status Flags: S - STOPPED, R - RUNNING, H - HEALTHY Columns: NAME, HEALTHCHECK-STATUS # NAME HEALTHCHECK-STATUS H home-assistant good, output: % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed ``` As an extra step, you can create a script that polls the container status and sends a notification to your e-mail if healthcheck fails and add a scheduler to run the script regularly. 1. Create the script: ```ros /system script add name=unhealthy-container-alert source=" :global lastState\ \n:local currentState \"\"\ \n:local msg \"\"\ \n:foreach i in=[/container find where unhealthy] do={\ \n:local name [/container get \$i name]\ \n:set currentState (\$currentState . \$name . \";\")\ \n}\ \n:if ([:len \$currentState] = 0) do={\ \n:set lastState \"\"\ \n} else={\ \n:if (\$currentState != \$lastState) do={\ \n:set lastState \$currentState\ \n:foreach i in=[/container find where unhealthy] do={\ \n:local name [/container get \$i name]\ \n:set msg (\$msg . \$name . \" is UNHEALTHY\\n\")\ \n}\ \n/tool e-mail send to=\"admin@example.com\" subject=\"Unhealthy container(s)\" body=\$msg\ \n}\ \n}" ``` :::warning Make sure to replace admin@example.com with your email. ::: 1. Create the scheduler: ```ros /system scheduler add interval=2m name=container-healthcheck-alert on-event="/system/script/run unhealthy-container-alert" ``` ## Tips and tricks - Containers use up a lot of disk space. USB/SATA, NVMe attached media is highly recommended. For devices with USB ports - USB to SATA adapters can be used with 2.5" drives - for extra storage and faster file operations. - RAM usage can be limited by using: ```ros /container/config/set memory-high=200M ``` this will soft limit RAM usage - if RAM usage goes over the high boundary, the processes of the cgroup are throttled and put under heavy reclaim pressure. - For starting containers after a router reboot use the start-on-boot option (starting from 7.6beta6): ```ros /container/print 0 name="2e679415-2edd-4300-8fab-a779ec267058" tag="test_arm64:latest" os="linux" arch="arm" interface=veth2 root-dir=disk1/alpine mountlists="" dns="" logging=yes start-on-boot=yes status=running /container/set 0 start-on-boot=yes ``` - It is possible to get to a **running** container shell: ```ros /container/shell 0 ``` - It's possible to set the container timeout in seconds, otherwise it will stay open indefinitely: ```ros /container/shell 0 timeout=120 ``` - Enable logging to get output from the container: ```ros /container/set 0 logging=yes ``` - Some containers will require additional privileges in order to be able to run properly: ```routeros /container/set 0 user=0:0 ``` - You can execute commands inside a Container with a specific user and without invoking `/bin/sh`: ```routeros /container/shell nextcloud user=www-data cmd="php /var/www/html/cron.php" no-sh ``` - Starting from version 7.11beta5 multiple addresses and ipv6 addresses can be added: ```ros /interface/veth/add address=172.17.0.3/16,fd8d:5ad2:24:2::2/64 gateway=172.17.0.1 gateway6=fd8d:5ad2:24:2::1 ``` - Active running /dev/ nodes to container: ```shell /dev/full /dev/null /dev/random /dev/tty /dev/urandom /dev/zero /dev/console /dev/net/tun /dev/kvm /dev/fuse ``` - Using the `Devices` parameter, it is possible to allow the serial terminal to be exposed to the container. ```ros /container/set your-container devices=serial0:"" ``` :::info To allow the container to use the serial console port, you must first free the serial console used by RouterOS under `/system/console` ::: --- ## Container - freeradius server ## Introduction The introduction of the container feature into RouterOS made it possible to run all kinds of servers for all sorts of tasks inside the router. This is especially relevant for people who want to reduce the number of devices in their network. Instead of running a server on a separate device/machine, why not run it inside the router? [Radius](../../authentication-authorization-accounting/radius.md) is short for Remote Authentication Dial-In User Service. RouterOS has a RADIUS client feature that can authenticate for HotSpot, [PPP](../../mobile-networking/ppp.md), [PPPoE](../../virtual-private-networks/pppoe/index.md), [PPTP](../../virtual-private-networks/pptp.md), [L2TP](../../virtual-private-networks/l2tp/index.md), and ISDN connections. Basically, this feature allows you to connect RouterOS to a Radius Server, and then, utilize the user database from the server for client authentication. In our example, we will showcase the **[freeradius/freeradius-server](https://hub.docker.com/r/freeradius/freeradius-server/tags)** image installation. ## Summary **Sub-menu:** `/container` ***Note**:* The **container** package is required. Make sure to study our [container](../) guide before proceeding with the configuration. Make sure to check the [disclaimer](../#disclaimer) and [requirements](../#requirements) sections to understand all the risks and necessary steps you might be required to do. At the time when the guide was published, the image was available for Linux/**amd64** OS/architecture **only** (usable by CHR and x86 devices). For arm64 devices you will need to make your own container from the [FreeRADIUS source](https://github.com/FreeRADIUS/freeradius-server). For both arm64 and arm32 devices, you can also use **[freeradius/freeradius-server-dev](https://hub.docker.com/r/freeradius/freeradius-dev)** image **at your own risk** (as it is an "experimental/development" version of the image). To help you set up a CHR in a [Virtual Box](https://www.virtualbox.org/), please check our [YouTube tutorial](https://www.youtube.com/watch?v=oHXkaHkSVVo), or [Make your own x86 router](https://www.youtube.com/watch?v=JpccW9tYOkQ). :::warning This guide demonstrates a basic example! The tests were performed in a local environment! This guide is meant for basic RADIUS "testing" purposes! Not all "freeradius" feature were tested! ::: ## Configuration ### Container mode Enable container mode: ```ros /system/device-mode/update container=yes ``` You will need to confirm the device-mode with a cold reboot if using the container on X86. ### Networking Add veth interface for the container: ```ros /interface/veth/add name=veth3 address=172.17.0.2/24 gateway=172.17.0.1 ``` Create a bridge for the container, assign an IP network to it, and add veth to the bridge: ```ros /interface/bridge/add name=dockerfreeradius /ip/address/add address=172.17.0.1/24 interface=dockerfreeradius /interface/bridge/port/add bridge=dockerfreeradius interface=veth3 ``` Setup NAT for outgoing traffic if required: ```ros /ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24 ``` ### Getting image To simplify the configuration, we will get the image from an external library, but you can also import it via the [.tar](../#option-b-import-image-from-pc) file. Make sure that you have "Registry URL" set accordingly, limit RAM usage (if necessary), and set up a directory for the image: ```ros /container/config/set registry-url=https://registry-1.docker.io tmpdir=pull ``` Pull the image with the help of the command: ```ros /container/add remote-image=freeradius/freeradius-server:latest interface=veth3 root-dir=freeradius logging=yes cmd="-X" ``` where `cmd="-X"` enables debug logging (per the "freeradius" documentation). After running the command, RouterOS should start "extracting" the package. Check "File System" for newly created folders and monitor container status with the command `/container/print`. ### Starting the container After you make sure that the container has been added and the status has changed to `status=stopped` after using `/container/print`, you can initiate it: ```ros /container/start 0 ``` ### Altering the server's configuration files To access the server's configuration files (**clients.conf** and **authorize**), we will need to use the SFTP (file transfer over SSH) protocol, so make sure that SSH [service](../../system-information-and-utilities/services.md) is enabled. Open your command terminal ("CMD", as Administrator, for Windows users, or "Linux Shell or Command Terminal" for Linux users) and navigate to the directory where you want to download the configuration files. For example, to the "radius" folder on your "Desktop": ```powershell C:\WINDOWS\system32>cd C:\Users\Administrator\Desktop\radius C:\Users\Administrator\Desktop\radius> ``` Initiate SFTP to the device's IP address: ```powershell C:\Users\Administrator\Desktop\radius>sftp admin@10.55.8.53 admin@10.55.8.53's password: Connected to 10.55.8.53. sftp> ``` Go to the server's configuration file folder (use the `dir` or `ls` command to see the content of the folder you are in and the `cd` command to go to the folder of our choice). The first file, "clients.conf", allows you to define RADIUS clients. Per the "freeradius" documentation, it should be under the `/etc/freeradius` directory...so, navigate there and use the `get` command to download it: ```powershell sftp> dir freeradius pub pull skins sftp> cd freeradius/etc/freeradius sftp> dir README.rst certs clients.conf dictionary experimental.conf hints huntgroups mods-available mods-config mods-enabled panic.gdb policy.d proxy.conf radiusd.conf sites-available sites-enabled templates.conf trigger.conf users sftp> get clients.conf Fetching /freeradius/etc/freeradius/clients.conf to clients.conf /freeradius/etc/freeradius/clients.conf 100% 8323 1.2MB/s 00:00 ``` Open "**clients.conf**" via your preferred text editor (Notepad or any other). You can study the file to see all the options that you have (additionally, check [freeradius.org](https://wiki.freeradius.org/config/Configuration-files)). This example shows a basic setup, so we will just overwrite the whole file with the lines shown below: ```text client new { ipaddr = 0.0.0.0/0 secret = client_password } ``` where we indicate that our radius client can connect using any possible IP address (**ipaddr=0.0.0.0/0** ensures that, but you also can change it to the actual ip address/mask of your radius client if you need to do so) and that our secret is "client\_password" (you can change it to any other secret). Save the file/overwrite it. The second file, "authorize", allows you to set up users. Per the "freeradius" documentation, it should be under `/etc/freeradius/mods-config/files`. Go there and `get` the file: ```powershell sftp> dir freeradius pub pull skins sftp> cd freeradius/etc/freeradius/mods-config/files sftp> dir accounting authorize dhcp pre-proxy sftp> get authorize Fetching /freeradius/etc/freeradius/mods-config/files/authorize to authorize /freeradius/etc/freeradius/mods-config/files/authorize 100% 6594 1.1MB/s 00:00 ``` Open "**authorize**" via your preferred text editor (notepad or any other). This example shows a basic setup, so we will just uncomment (remove the "#" symbol from) the line shown below (leave the rest of the configuration/lines as they are): ```text bob Cleartext-Password := "hello" ``` which creates a username "bob" and sets the password to "hello" (you can change the username and password). Save the file/overwrite it. Upload both files back to overwrite the default files with the help of the `put` command: ```powershell sftp> dir freeradius pub pull skins sftp> cd freeradius/etc/freeradius sftp> dir README.rst certs clients.conf dictionary experimental.conf hints huntgroups mods-available mods-config mods-enabled panic.gdb policy.d proxy.conf radiusd.conf sites-available sites-enabled templates.conf trigger.conf users sftp> put clients.conf Uploading clients.conf to /freeradius/etc/freeradius/clients.conf clients.conf 100% 67 22.3KB/s 00:00 sftp> cd mods-config/files sftp> dir accounting authorize dhcp pre-proxy sftp> put authorize Uploading authorize to /freeradius/etc/freeradius/mods-config/files/authorize authorize 100% 6626 1.6MB/s 00:00 ``` Restart the container: ```ros /container/stop 0 /container/start 0 ``` Make sure to wait for the container to stop (`status=stopped` should be shown after using the `/container/print` command) before initiating it again. ## Result verification In RouterOS, add a new RADIUS client configuration: ```ros /radius/add service=login address=172.17.0.2 secret="client_password" ``` , where the `address` is the IP address of the veth3 interface, `secret` is the secret that we configured in the **clients.conf** file and `service` is the allowed service that you wish to use. Allow "login" with RADIUS users via the command: ```ros /user/aaa/set use-radius=yes ``` We have allowed the "login" service for RADIUS and we can test it using an ssh/winbox/webfig connection. For the SSH test, issue the command (where you need to indicate the device's management IP and input bob's password "hello" after): ```ros /system/ssh 10.55.8.53 user=bob ``` You should be able to verify that the terminal user changed from "admin@MikroTik" to "bob@MikroTik": ```ros [admin@MikroTik] > /system/ssh 10.55.8.53 user=bob password:hello MMM MMM KKK TTTTTTTTTTT KKK MMMM MMMM KKK TTTTTTTTTTT KKK MMM MMMM MMM III KKK KKK RRRRRR OOOOOO TTT III KKK KKK MMM MM MMM III KKKKK RRR RRR OOO OOO TTT III KKKKK MMM MMM III KKK KKK RRRRRR OOO OOO TTT III KKK KKK MMM MMM III KKK KKK RRR RRR OOOOOO TTT III KKK KKK MikroTik RouterOS 7.8alpha173 (c) 1999-2023 https://www.mikrotik.com/ Press F1 for help [bob@MikroTik] > ``` If you issue the command `/user/active/print`: ```ros /user/active/print Flags: R - RADIUS Columns: WHEN, NAME, ADDRESS, VIA # WHEN NAME ADDRESS VIA 0 2023-02-16 16:31:21 admin xx.xx.xx.xx winbox 1 2023-02-16 16:38:46 admin xx.xx.xx.xx console 2 R 2023-02-16 16:38:53 bob 10.55.8.53 ssh ``` you will be able to verify that a new user "bob" is "active" and has a flag "R" assigned, which indicates it is a RADIUS user. --- ## Container - HAProxy HAProxy is a high-performance reverse proxy and load balancer as a Container. For optimal security, it is highly recommended to use a reverse HTTP/HTTPS proxy like HAProxy as an intermediary between external users and your internal services, rather than exposing containers directly to the network. ## Configuration To set up a HAProxy Container on your RouterOS device, follow these steps below. :::info Make sure you have created a [Container network](../#networking-examples) before proceeding. ::: 1. Create HAProxy Container mount points. ```routeros /container/mounts/add list=haproxy_etc src=disk1/haproxy-etc dst=/usr/local/etc/haproxy ``` 2. Create a HAProxy Container. ```routeros /container/add remote-image=haproxy:latest interface=veth1 root-dir=disk1/haproxy mountlists=haproxy_etc user=0:0 name=haproxy ``` 3. Connect to your RouterOS device using an SFTP client (for example, WinSCP when using Microsoft Windows) and create a new file `disk1/haproxy-etc/haproxy.cfg` , you can use the following config as an example. ```cfg defaults mode http timeout client 10s timeout connect 10s timeout server 10s timeout http-request 10s frontend http_synapse bind *:80 use_backend synapse backend synapse server server1 172.17.0.2:8008 maxconn 32 ``` 1. Start the HAProxy Container. ```routeros /container/start [find where name=haproxy] ``` ## Advanced: HAProxy with Certbot This example shows how to configure HAProxy to serve HTTPS traffic and automatically renew the certificates by using Certbot and RFC2136. 1. Create HAProxy Container: ```routeros /container/mounts/add list=MOUNT_HAPROXY src=disk1/volumes/haproxy/config dst=/usr/local/etc/haproxy /container/add remote-image=haproxy:latest interface=veth1 root-dir=disk1/images/haproxy mountlists=MOUNT_HAPROXY name=haproxy start-on-boot=yes user=0:0 logging=yes ``` 2. Create a new file called `haproxy.cfg` on your PC and upload it to `disk1/volumes/haproxy/config/` , adjust the configuration to your needs: ```cfg global log stdout format raw local0 info stats socket :9999 level admin expose-fd listeners ssl-default-bind-ciphers EECDH+AESGCM:EDH+AESGCM ssl-default-server-ciphers EECDH+AESGCM:EDH+AESGCM ssl-default-bind-options ssl-min-ver TLSv1.2 ssl-default-server-options ssl-min-ver TLSv1.2 tune.ssl.default-dh-param 2048 tune.bufsize 43768 tune.ssl.cachesize 1000000 nbthread 8 defaults log global timeout client 10s timeout connect 10s timeout server 10s timeout http-request 10s frontend frontend_webapp mode http option httplog option http-server-close option forwardfor except 127.0.0.0/8 stick-table type ipv6 size 100k expire 30s store http_req_rate(10s) http-request track-sc0 src http-request deny deny_status 429 if { sc_http_req_rate(0) gt 10000 } bind *:80 bind *:443 ssl crt /usr/local/etc/haproxy/certs/ http-request redirect scheme https unless { ssl_fc } http-request set-header X-Forwarded-Host %[req.hdr(host)] http-request set-header X-Forwarded-For %[src] use_backend backend_webapp backend backend_webapp mode http balance roundrobin option http-server-close option forwardfor server server1 172.17.0.2:8080 ``` 1. Create the Certbot Container: ```routeros /container/mounts/add list=MOUNT_CERTBOT_CONFIG src=disk1/volumes/certbot/config dst=/etc/letsencrypt /container/mounts/add list=MOUNT_CERTBOT_DATA src=disk1/volumes/certbot/data dst=/var/lib/letsencrypt /container/mounts/add list=MOUNT_CERTBOT_LOG src=disk1/volumes/certbot/log dst=/var/log/letsencrypt /container/mounts/add list=MOUNT_CERTBOT_HAPROXY src=disk1/volumes/haproxy/config dst=/etc/haproxy /container/add remote-image=certbot/dns-rfc2136 cmd="certonly -n --agree-tos --dns-rfc2136 --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini -m admin@ --deploy-hook 'cat /etc/letsencrypt/li\ ve//fullchain.pem /etc/letsencrypt/live//privkey.pem | tee /etc/haproxy/certs/.pem > /dev/null; echo -e \"set ssl cert /usr/local/e\ tc/haproxy/certs/.pem <<\ \n\$(cat /etc/haproxy/certs/.pem)\ \n\" | nc 127.0.0.1:9999; echo \"commit ssl cert /usr/local/etc/haproxy/certs/.pem\" | nc 127.0.0.1:9999' -d --cert-name " \ interface=veth1 logging=yes mountlists=MOUNT_CERTBOT_CONFIG,MOUNT_CERTBOT_DATA,MOUNT_CERTBOT_LOG,MOUNT_CERTBOT_HAPROXY name=certbot root-dir=\ disk1/images/certbot start-on-boot=yes workdir=/opt/certbot ``` :::warning Make sure to replace all `` placeholders in the example above with your fully qualified domain name! ::: 1. Wait for the Container image to be downloaded and start the Certbot Container: ```routeros /container/start [find where name=certbot] ``` 2. Check the logs to make sure you successfully received a new certificate: ```routeros /log/print follow ``` 3. Start HAProxy Container: ```routeros /container/start [find where name=haproxy] ``` 4. Set up a schedule, for example, each day at 06:30 to check for a new certificate: ```routeros /system/scheduler add interval=1d name=SCHEDULE_RenewCertbot on-event=SCRIPT_RenewCertbot policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=\ 2025-03-10 start-time=06:30:00 /system/script add dont-require-permissions=no name=SCRIPT_RenewCertbot owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=\ "/container/start [find where name=\"certbot\"]" ``` 5. Done The certificate will automatically renew and replace old certificates in HAProxy without needing to restart the Container. --- ## Container - HomeAssistant The introduction of the **container** feature in RouterOS made it possible to run a wide variety of servers directly on the router. This is especially valuable for users who want to minimize the number of devices in their network. Instead of deploying a server on a separate machine, you can now host it inside the router itself. In this guide we will demonstrate how to install and run a **Home‑Assistant** server on RouterOS. Home‑Assistant is a popular platform for collecting data from numerous sensors and offers extensive support for a wide range of **integrations**. ## Summary Before proceeding with the configuration, ensure that you have studied our [container](../) guide. Additionally, review the [disclaimer](../#disclaimer) and [requirements](../#requirements) section to understand all associated risks and any necessary steps you may need to take. You can find supported architectures in the [link](https://hub.docker.com/r/homeassistant/home-assistant/tags). At the time this guide was published, the **home-assistant** image was available for ARM64 and AMD64 (CHR and x86) devices. Based on the information from the [Home Assistant website](https://www.home-assistant.io/installation/linux/), the recommended requirements are: - 2 GB RAM - 32 GB Storage But we will try to run it on lower spec device. ## Container configuration **Sub-menu:** `/container` ***note**:* The **container** package is required. ### Container mode Enable container mode: ```ros /system/device-mode/update container=yes ``` You will need to confirm the device-mode with a press of the reset button, or a cold reboot, if using a container on X86. ### Networking Add veth interface: ```ros /interface/veth/add name=veth2 address=172.19.0.2/24 gateway=172.19.0.1 ``` Create a bridge for the container and add the veth interface to it: ```ros /interface/bridge/add name=ha /ip/address/add address=172.19.0.1/24 interface=ha /interface/bridge/port/add bridge=ha interface=veth2 ``` Forward TCP 8123 for home-assistant management (where 192.168.88.1 is the device's LAN IP address) if NAT is required (optional): ```ros /ip/firewall/nat/add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=8123 protocol=tcp to-addresses=172.19.0.2 to-ports=8123 ``` ### Environment variables and mounts Per the home-assistant documentation, define mounts for the configuration files (where `/usb1` is our external USB storage folder): ```ros /container/mounts/add dst=/config list=ha_config src=/usb1/ha_config ``` Create an environment variable for home-assistant: ```ros /container/envs/add key=TZ list=ha_env value=America/Los_Angeles ``` ### Getting image To simplify the configuration, we will get the images from an external library. Make sure that you have "Registry URL" set accordingly, limit RAM usage (if necessary), and set up a directory for the images: ```ros /container/config/set registry-url=https://registry-1.docker.io tmpdir=/usb1/pull ``` Pull the home-assistant image and wait for it to be extracted: ```ros /container/add remote-image=homeassistant/home-assistant:latest interface=veth2 root-dir=/usb1/ha mountlists=ha_config envlists=ha_env logging=yes ``` After running the command, RouterOS should start "extracting" the package. Check "File System" for newly created folders and monitor container status with the command `/container/print`. ### Starting the container After you make sure that the container has been added and the status has changed to `status=stopped` after using `/container/print` → you can initiate it: ```ros /container/start 0 ``` ### Home-Assistant setup Open your preferred web browser and access the Home-Assistant management portal by specifying the management port ":8123": ![](./img/container-homeassistant-01.webp) Proceed with the setup. More information is explained in the [Home-Assistant onboarding guide](https://www.home-assistant.io/getting-started/onboarding/). ## Resources Just running **Home Assistant** (without any load/traffic) takes up ~300-400 MB of RAM: ```ros /system/resource/print uptime: 4m27s version: 7.13.3 (stable) build-time: 2024-01-24 13:16:46 factory-software: 7.10 free-memory: 143.0MiB total-memory: 448.0MiB ``` --- ## Container - Matrix (Synapse) Matrix is a decentralized communication protocol. Each Matrix server operates independently, maintaining its own set of users and defining its own rules and policies. ### Hosting Your Own Matrix Server You can host your own Matrix server directly on a RouterOS device using Containers. This allows you to maintain full control over your communication infrastructure. ### Federation Matrix servers can connect through federation to create a unified communication network. This enables users on different Matrix servers to communicate with each other securely, without requiring a central authority. ### Bridging to Other Platforms Matrix supports bridging to relay messages from other chat platforms, including: - WhatsApp - Discord - Signal - Telegram - And many other platforms By using Matrix bridges, you can consolidate communication from multiple platforms into a single application, such as [Element](https://element.io/). This allows you to communicate with users across different platforms through one unified interface. # Setting Up a Synapse Matrix Server on RouterOS This guide explains how to set up Synapse, one of several available Matrix servers on your MikroTik RouterOS device using containers. :::info Before proceeding, ensure you have created a Container network. For instructions, refer to the [Container network documentation](../#networking-examples). ::: --- ## Prerequisites - A RouterOS device with container support - An existing container network configured - Sufficient storage space for the database and Synapse data --- ## Step 1: Create PostgreSQL Container Environment Variables Configure the environment variables list for the PostgreSQL container: ```routeros /container/envs/add list=postgres_synapse_envs key=POSTGRES_DB value="synapse" /container/envs/add list=postgres_synapse_envs key=POSTGRES_PASSWORD value="" /container/envs/add list=postgres_synapse_envs key=POSTGRES_USER value="synapse_user" /container/envs/add list=postgres_synapse_envs key=PGDATA value="/var/lib/postgresql/data/pgdata" /container/envs/add list=postgres_synapse_envs key=POSTGRES_INITDB_ARGS value="--encoding='UTF8' --lc-collate='C' --lc-ctype='C'" /container/envs/add list=postgres_synapse_envs key=PGPORT value=5433 ``` :::note Replace `` with your desired PostgreSQL password. ::: --- ## Step 2: Create PostgreSQL Container Mount Create a mount point to persist the PostgreSQL data on your RouterOS device: ```routeros /container/mounts/add list=synapse_postgres_data src=disk1/synapse-postgres-data dst=/var/lib/postgresql/data ``` --- ## Step 3: Create the PostgreSQL Container Launch the PostgreSQL container using the configuration from the previous steps: ```routeros /container/add remote-image=postgres:17.2-alpine interface=veth1 root-dir=disk1/postgres-17.2-synapse mountlists=synapse_postgres_data envlists=postgres_synapse_envs name=postgresql_synapse ``` --- ## Step 4: Create Synapse Container Environment Variables Configure the environment variables for the Synapse container: ```routeros /container/envs/add list=synapse_envs key=SYNAPSE_CONFIG_DIR value="/data" /container/envs/add list=synapse_envs key=SYNAPSE_CONFIG_PATH value="/data/homeserver.yaml" /container/envs/add list=synapse_envs key=SYNAPSE_SERVER_NAME value="test.mt.lv" /container/envs/add list=synapse_envs key=SYNAPSE_REPORT_STATS value="yes" ``` :::note Replace `test.mt.lv` with your actual server domain name. ::: --- ## Step 5: Create Synapse Container Mount Create a mount point to persist Synapse data on your RouterOS device: ```routeros /container/mounts/add list=synapse_data src=disk1/synapse-data dst=/data ``` --- ## Step 6: Generate Initial Synapse Configuration Create and run a Synapse container to generate the required configuration files. The container runs with the `generate` command to create initial configuration: ```routeros /container/add remote-image=matrixdotorg/synapse:latest interface=veth1 cmd="generate" root-dir=disk1/synapse mountlists=synapse_data envlists=synapse_envs name=synapse ``` --- ## Step 7: Initialize Configuration Files Start and then stop the Synapse container to allow it to generate the necessary configuration files: ```routeros /container/start [find where name=synapse] /container/stop [find where name=synapse] ``` --- ## Step 8: Remove the Generate Command Clear the command parameter from the Synapse container so it runs in normal mode: ```routeros /container/set [find where name=synapse] cmd="" ``` --- ## Step 9: Configure Database Connection Connect to your RouterOS device using an SFTP client (such as WinSCP on Windows) and edit the generated configuration file at `disk1/synapse-data/homeserver.yaml`. Update the database section with the following settings: ```yaml database: name: psycopg2 args: user: synapse_user password: dbname: synapse host: 172.17.0.2 port: 5433 cp_min: 5 cp_max: 10 keepalives_idle: 10 # optional keepalives_interval: 10 # optional keepalives_count: 3 # optional ``` :::info Replace `` with the password you set in Step 1. ::: --- ## Step 10: Start the PostgreSQL Container Start the PostgreSQL container to prepare the database: ```routeros /container/start [find where name=postgresql_synapse] ``` --- ## Step 11: Start the Synapse Container Start the Synapse container to run your Matrix server: ```routeros /container/start [find where name=synapse] ``` --- ## Step 12: Register a Matrix User Enter the Synapse container's shell and register a new user: ```routeros /container/shell [find where name=synapse] ``` Once inside the container, run: ``` register_new_matrix_user -c /data/homeserver.yaml ``` Follow the prompts to create your admin user account. --- ## Step 13: Access Your Matrix Server Your Synapse Matrix server is now running. Access it using your RouterOS device's IP address or domain name. --- :::warning Always consult the official Synapse documentation for the latest configuration options and best practices, as configuration procedures may change with newer versions. ::: ### Discord bridge :::tip The example below is for configuring a Discord bridge, but the procedure for other types of [bridges](https://matrix.org/ecosystem/bridges/) is very similar. Check the official documentation of your desired [bridge](https://matrix.org/ecosystem/bridges/) for more information. ::: 1. Create PostgreSQL Discord bridge Container environment variables: ```routeros /container/envs/add list=postgres_discord_envs key=POSTGRES_DB value="synapse-discord" /container/envs/add list=postgres_discord_envs key=POSTGRES_PASSWORD value="" /container/envs/add list=postgres_discord_envs key=POSTGRES_USER value="synapse_discord" /container/envs/add list=postgres_discord_envs key=PGDATA value="/var/lib/postgresql/data/pgdata" /container/envs/add list=postgres_discord_envs key=POSTGRES_INITDB_ARGS value="--encoding='UTF8' --lc-collate='C' --lc-ctype='C'" /container/envs/add list=postgres_discord_envs key=PGPORT value=5434 ``` 2. Create PostgreSQL Discord bridge Container mounts: ```routeros /container/mounts/add list=discord_postgres_data src=disk1/discord-postgres-data dst=/var/lib/postgresql/data ``` 3. Create a PostgreSQL Container for Discord bridge: ```routeros /container/add remote-image=postgres:17.2-alpine interface=veth1 root-dir=disk1/postgres-17.2-discord mountlists=discord_postgres_data envlists=postgres_discord_envs name=postgresql_discord ``` 4. Follow the guide for [HAProxy](./container-haproxy.md) Container and set up a reverse proxy for port `8080` 5. Create Discord bridge Container mount points: ```routeros /container/mounts/add list=synapse_discord_data src=disk1/synapse-discord-data dst=/data ``` 6. Create a Discord Bridge Container: ```routeros /container/add remote-image=litetex/mau.mautrix.discord:latest interface=veth1 root-dir=disk1/synapse-discord mountlists=synapse_discord_data name=synapse_discord ``` 7. Start and stop the Discord bridge Container to generate files: ```routeros /container/start [find where name=synapse_discord] /container/stop [find where name=synapse_discord] ``` 8. Connect to your RouterOS device using an SFTP client (for example, WinSCP when using Microsoft Windows) and adjust the file `disk1/synapse-discord/config.yaml` : ```yaml homeserver address: http://172.17.0.2:8008 domain: test.mt.lv software: standard async_media: true appservice address: leave default hostname: leave default port: leave default database: type: postgres uri: postgres://synapse_discord:@172.17.0.2:5434/synapse-discord?sslmode=disable bridge: encryption: allow: true permissions: "*": relay "@your_admin_user1:test.mt.lv": admin "@your_admin_user2:test.mt.lv": admin ``` 9. Start and stop the Discord bridge Container again: ```routeros /container/start [find where name=synapse_discord] /container/stop [find where name=synapse_discord] ``` 10. Download the file `disk1/synapse-discord/registration.yaml` and upload it as a file `disk1/synapse-data/mautrix-discord-registration.yaml` 11. Connect to your RouterOS device using an SFTP client (for example, WinSCP when using Microsoft Windows) and add the following lines to `disk1/synapse-data/homeserver.yaml`: ```yaml ... app_service_config_files: - /data/mautrix-discord-registration.yaml ``` 12. Start the Synapse and Discord bridge Containers: ```routeros /container/start [find where name=postgresql_discord] /container/start [find where name=synapse_discord] /container/start [find where name=postgresql_synapse] /container/start [find where name=synapse] ``` 13. Your Matrix server should now have a new user called "Discord bridge bot". Follow the official documentation to create bridged rooms. --- ## Container - mosquitto MQTT server ## Introduction The introduction of the container feature into RouterOS made it possible to run all kinds of servers for all sorts of tasks inside the router. This is especially relevant for people who want to reduce the number of devices in their network. Instead of running a server on a separate device/machine, why not run it inside the router? In this guide, we will showcase how to install a basic MQTT broker (or in other words, server) called [eclipse-mosquitto](https://mosquitto.org/). The MQTT protocol is a very popular choice, especially in IoT topologies. It is an open OASIS and ISO standard lightweight, publish-subscribe network protocol that transports messages between devices. A typical topology consists of an MQTT publisher (a device that sends information), an MQTT broker (a server where the data is stored), and an MQTT subscriber (a device that listens to the data published on the server). RouterOS supports the [MQTT publish, subscribe](../../internet-of-things/mqtt/index.md) feature, and, now, we can also run the MQTT broker as well. The image that we are going to use can be found by following the hub.docker [link](https://hub.docker.com/_/eclipse-mosquitto). ## Summary Make sure to study our [container](../) guide before proceeding with the configuration. Make sure to check the [disclaimer](../#disclaimer) and [requirements](../#requirements) sections to understand all the risks and necessary steps you might be required to take. You can find supported architectures by following the [link](https://hub.docker.com/_/eclipse-mosquitto/tags). At the time, when the guide was published, the **eclipse-mosquitto** image was available for ARM32, ARM64, and AMD64 (CHR and x86) devices. In this example, we will run it on an ARM32 architecture device → [RB1100AHx4](https://mikrotik.com/product/rb1100ahx4). :::warning **A very basic** and **quick** configuration will be shown. Make sure to check the [mosquitto documentation](https://mosquitto.org/documentation/) page for more information about additional options and settings you can implement. If you want to use it for production, please **make sure to harden the security** in any way possible: - [Firewall](../../firewall-and-quality-of-service/firewall/index.md), so that access to the container is allowed only from your trusted IP addresses; - Increasing security from the mosquitto broker/server-side → use strong passwords, non-standard ports etc.; - Use SSL MQTT. ::: ## Container configuration **Sub-menu:** `/container` ***note**:* The **container** package is required. ### Container mode Enable container mode: ```ros /system/device-mode/update container=yes ``` You will need to confirm the device-mode with a press of the reset button, or a cold reboot, if using containers on X86. ### Networking Add veth interface for the container: ```ros /interface/veth/add name=veth2 address=172.19.0.2/24 gateway=172.19.0.1 ``` Create a bridge for containers and add veth to it: ```ros /interface/bridge/add name=msqt /ip/address/add address=172.19.0.1/24 interface=msqt /interface/bridge/port/add bridge=msqt interface=veth2 ``` Forward TCP 1883 for non-SSL MQTT (where 192.168.88.1 is the device's LAN IP address) for testing purposes if NAT is required (optional): ```ros /ip/firewall/nat/add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=1883 protocol=tcp to-addresses=172.19.0.2 to-ports=1883 ``` ### Environment variables and mounts Per the eclipse-mosquitto docker hub, define a mount for the configuration file. We will mount not just the configuration file, but the whole folder, because, for SSL MQTT, we will need to upload certificates into the folder as well: ```ros /container/mounts/add list=msqt_config src=/mosquitto_mounted dst=/mosquitto/config ``` ### Getting image To simplify the configuration, we will get the image from an external library, but you can also import it via the [.tar](../#option-b-import-image-from-pc) file. In this example, we will use the device's own storage. RB1100AHx4 has 128 MB disk space and a basic mosquitto installation should not take up more than ~15 MB. Make sure that you have "Registry URL" set accordingly, limit RAM usage (if necessary), and set up a directory for the image: ```ros /container/config/set registry-url=https://registry-1.docker.io tmpdir=pull ``` ### Pull image ```ros /container/add remote-image=library/eclipse-mosquitto:latest interface=veth2 root-dir=mosquitto mountlists=msqt_config logging=yes ``` After running the command, RouterOS should start "extracting" the package. Check "File System" for newly created folders and monitor container status with the command `/container/print`. ### Setting up mosquitto configuration file To get the **mosquitto.conf** file, we will need to use SFTP (file transfer over SSH) protocol, so make sure that SSH [service](../../system-information-and-utilities/services.md) is enabled. You can also use FTP. Open your command terminal ("CMD", as Administrator, for Windows users, or "Linux Shell or Command Terminal" for Linux users) and navigate to the directory where you want to download the configuration file. For example, to the "Container" folder on your "Desktop": ```powershell C:\WINDOWS\system32>cd C:\Users\Administrator\Desktop\Container C:\Users\Administrator\Desktop\Container> ``` Initiate SFTP to the device's IP address: ```powershell C:\Users\Administrator\Desktop\Container>sftp admin@192.168.88.1 The authenticity of host '192.168.88.1 (192.168.88.1)' can't be established. RSA key fingerprint is SHA256:lfxxs+xMrXlvP7hiHi9ZAEZlPi6/c5US+r6J7ljhkaA. Are you sure you want to continue connecting (yes/no/[fingerprint])?yes Warning: Permanently added '192.168.88.1' (RSA) to the list of known hosts. Connected to 192.168.88.1. sftp> ``` Go to the mosquitto configuration file folder (use the `dir` or `ls` command to see the content of the folder you are in and the `cd` command to go to the folder of your choice). By default, the configuration is loaded from the "/mosquitto/config/mosquitto.conf", so, navigate there and use the `get` command to download it: ```powershell sftp> cd mosquitto/mosquitto/config sftp> dir mosquitto.conf sftp> get mosquitto.conf Fetching /mosquitto/mosquitto/config/mosquitto.conf to mosquitto.conf /mosquitto/mosquitto/config/mosquitto.conf ``` Open "**mosquitto.conf**" via your preferred text editor (notepad or any other), and just overwrite it with two lines shown below: :::warning In this section, we will configure a basic non-SSL MQTT setup for testing purposes. Non-SSL MQTT is not secure for a production environment unless you are certain the required security/restrictions are in place. For a production environment, in topologies where the MQTT traffic can be captured/sniffed and/or in topologies where the MQTT traffic is routed directly via the internet (not locally), use SSL MQTT. Check the [SSL MQTT section](./container-mosquitto-mqtt-server.md#ssl-mqtt) for more information. ::: ```text listener 1883 allow_anonymous true ``` - The first line, **listener 1883**, will make the installation listen for incoming network connections on the specified port. - The second line, **allow\_anonymous true**, determines whether clients that connect without providing a username are allowed to connect. Overwrite the file using the same **mosquitto.conf** name. After you have created your own custom configuration file, upload it into the mounted directory/folder "**mosquitto\_mounted**". If you have not run the container yet, you will not have the "**mosquitto\_mounted**" folder and you can create it manually. If you did run it (`/container/start 0`), it should have been created automatically: ```powershell sftp> dir mosquitto mosquitto_mounted pub pull skins ``` Use SFTP from the directory where the edited mosquitto.conf file is located and `put` it into the mounted directory: ```powershell C:\Users\Administrator\Desktop\Container>dir Directory of C:\Users\Administrator\Desktop\Container 02/03/2023 12:09 PM . 02/03/2023 12:09 PM .. 02/03/2023 12:09 PM 40,449 mosquitto.conf 1 File(s) 40,449 bytes 2 Dir(s) 76,166,430,720 bytes free C:\Users\Administrator\Desktop\Container>sftp admin@192.168.88.1 Connected to 192.168.88.1. sftp> dir mosquitto mosquitto_mounted pub pull skins sftp> cd mosquitto_mounted sftp> put mosquitto.conf Uploading mosquitto.conf to /mosquitto_mounted/mosquitto.conf mosquitto.conf 100% 162 40.5KB/s 00:00 ``` Restart the container: ```ros [admin@MikroTik] > /container/stop 0 [admin@MikroTik] > /container/start 0 ``` Make sure to wait for the container to stop (`status=stopped` should be shown after using the `/container/print` command) before initiating it again. ### Starting the container After you make sure that the container has been added and the status has changed to `status=stopped` after using `/container/print` → you can initiate it: ```ros /container/start 0 ``` If you have enabled container logging, you would see something like this in the [Logs](../../diagnostics-monitoring-and-troubleshooting/log/index.md) section: ```text 12:12:46 container,info,debug 1707214366: mosquitto version 2.0.18 starting 12:12:46 container,info,debug 1707214366: Config loaded from /mosquitto/config/mosquitto.conf. 12:12:46 container,info,debug 1707214366: Opening ipv4 listen socket on port 1883. 12:12:46 container,info,debug 1707214366: Opening ipv6 listen socket on port 1883. 12:12:46 container,info,debug 1707214366: mosquitto version 2.0.18 running ``` ## MQTT publish and subscribe **Sub-menu:** `/iot/mqtt` ***note**:* The **iot** package is required. Add an MQTT broker: ```ros /iot/mqtt/brokers/add name=mosquitto username=test address=172.19.0.2 ``` Subscribe to the MQTT broker and the required topic: ```ros /iot/mqtt/subscribe broker=mosquitto topic=test/topic ``` Publish a static MQTT message: ```ros /iot/mqtt/publish broker="mosquitto" topic="test/topic" message="{\"test\":\"123\"}" ``` Check subscriptions for received messages: ```ros /iot/mqtt/subscriptions/recv/print 0 broker=mosquitto topic="test/topic" data="{"test":"123"}" time=2023-07-12 10:01:40 ``` You can also check the container logs (if enabled), to confirm the mosquitto is operational: ```text 12:47:28 container,info,debug 1675421248: New connection from 172.19.0.1:42240 on port 1883. 12:47:28 container,info,debug 1675421248: New client connected from 172.19.0.1:42240 as MTD8580EC793C4 (p2, c1, k60, u'test'). 12:47:38 container,info,debug 1675421258: Client MTD8580EC793C4 disconnected. ``` ## SSL MQTT Using **non-SSL MQTT** for a production environment **is not secure**. One can easily [capture/sniff](../../diagnostics-monitoring-and-troubleshooting/packet-sniffer.md) the packet exchange between the broker and the publisher and, as a result, will be able to obtain user credentials and other sensitive information. To increase security, use SSL MQTT. The first step is to generate the certificates. In this example, we will use a simple Root CA scenario (with no device/client certificate requirement). Use the official [mosquitto-tls user guide](https://mosquitto.org/man/mosquitto-tls-7.html) for the step-by-step. ### Server configuration You should have generated ca.crt (Certificate Authority file), server.crt (server certificate) and server.key (server's key): ```powershell C:\Users\Administrator\Desktop\Container>dir Directory of C:\Users\Administrator\Desktop\Container 07/12/2023 10:58 AM . 07/12/2023 10:58 AM .. 07/12/2023 10:56 AM 1,322 ca.crt 07/12/2023 10:56 AM 1,854 ca.key 07/12/2023 09:57 AM 35 mosquitto.conf 07/12/2023 10:58 AM 1,164 server.crt 07/12/2023 10:57 AM 960 server.csr 07/12/2023 10:56 AM 1,704 server.key 6 File(s) 7,039 bytes 2 Dir(s) 52,401,184,768 bytes free ``` Open the mounted "**mosquitto.conf**" via your preferred text editor (notepad or any other), and just overwrite it with the lines shown below: ```text tls_version tlsv1.2 port 8883 allow_anonymous true cafile /mosquitto/config/ca.crt keyfile /mosquitto/config/server.key certfile /mosquitto/config/server.crt ``` - **tls\_version** line sets minimal TLS version. - **port 8883** will make the installation listen for incoming network connection on the specified port. - **allow\_anonymous true** determines whether clients that connect without providing a username are allowed to connect. :::warning We are using a basic SSL configuration for testing purposes. **allow\_anonymous true** is not a secure setting for the production environment. ::: - **cafile /mosquitto/config/ca.crt** line specifies a path to the CA certificate file. - **keyfile /mosquitto/config/server.key** line specifies a path to the server key file. - **certfile /mosquitto/config/server.crt** line specifies a path to the server certificate file. Upload the certificate files and an updated SSL-ready mosquitto.conf file into the mounted folder "**mosquitto\_mounted**": ```powershell C:\Users\Administrator\Desktop\Container>sftp admin@192.168.88.1 Connected to 192.168.88.1. sftp> cd mosquitto_mounted sftp> dir mosquitto.conf sftp> put ca.crt Uploading ca.crt to /mosquitto_mounted/ca.crt ca.crt 100% 1322 323.0KB/s 00:00 sftp> put server.crt Uploading server.crt to /mosquitto_mounted/server.crt server.crt 100% 1164 227.3KB/s 00:00 sftp> put server.key Uploading server.key to /mosquitto_mounted/server.key server.key 100% 1704 415.7KB/s 00:00 sftp> dir ca.crt mosquitto.conf server.crt server.key sftp> put mosquitto.conf Uploading mosquitto.conf to /mosquitto_mounted/mosquitto.conf mosquitto.conf 100% 162 32.2KB/s 00:00 ``` Restart the container: ```ros [admin@MikroTik] > /container/stop 0 [admin@MikroTik] > /container/start 0 ``` Confirm that the broker listens on port 8883 using the logs: ```text 11:20:41 container,info,debug 1689160841: mosquitto version 2.0.15 starting 11:20:41 container,info,debug 1689160841: Config loaded from /mosquitto/config/mosquitto.conf. 11:20:41 container,info,debug 1689160841: Opening ipv4 listen socket on port 8883. 11:20:41 container,info,debug 1689160841: Opening ipv6 listen socket on port 8883. 11:20:41 container,info,debug 1689160841: mosquitto version 2.0.15 running 11:22:24 system,info,account user admin logged in from 10.5.217.34 via local ``` ### Testing the connection Upload the CA certificate (**ca.crt**) into RouterOS, into the device's "File List": ```ros /file/print Columns: NAME, TYPE, SIZE, CREATION-TIME # NAME TYPE SIZE CREATION-TIME 0 skins directory 1970-01-01 03:00:02 1 pub directory 2023-01-04 11:05:04 2 disk7 disk 2023-07-12 09:52:07 3 mosquitto container store 2023-07-12 09:52:09 4 mosquitto_mounted container store 2023-07-25 16:38:37 5 pull directory 2023-07-12 09:52:09 6 ca.crt .crt file 1322 2023-07-12 11:28:23 ``` Import the certificate: ```ros /certificate/import file-name=ca.crt passphrase="" ``` Add MQTT broker for SSL connection: ```ros /iot/mqtt/brokers/add name=mosquittoSSL username=test address=172.19.0.2 port=8883 ssl=yes ``` Subscribe to the MQTT broker and the required topic: ```ros /iot/mqtt/subscribe broker=mosquittoSSL topic=test/topic ``` Publish a static MQTT message: ```ros /iot/mqtt/publish broker="mosquittoSSL" topic="test/topic" message="{\"test\":\"123\"}" ``` Check subscriptions for received messages: ```ros /iot/mqtt/subscriptions/recv/print 0 broker=mosquittoSSL topic="test/topic" data="{"test":"123"}" time=2023-07-12 10:20:40 ``` --- ## Container - Postgres PostgreSQL is a powerful, widely-used SQL database engine that serves as the backbone for numerous applications, ranging from small web projects to enterprise-level systems. This guide will walk you through the essential steps required to get PostgreSQL up and running on RouterOS. Additionally, this guide will provide you with the necessary instructions to set up pgAdmin—a feature-rich, web-based interface that allows you to easily manage your PostgreSQL database. ## Configuration This section provides step-by-step instructions for setting up a PostgreSQL container on your MikroTik RouterOS device. PostgreSQL is a powerful, open-source relational database system that supports SQL standards and offers advanced features such as transactions, subqueries, and user-defined types. Before proceeding, ensure that you have already created a container network as described in the [Container network](../#networking-examples) documentation. ### Step 1: Create Mount Point for PostgreSQL Container Before creating the container, you need to create a persistent storage location where PostgreSQL will store its database files. This ensures that your data persists even if the container is recreated or removed, protecting your valuable database information. ```routeros /container/mounts/add list=MOUNT_POSTGRES src=disk1/volumes/postgres/data dst=/var/lib/postgresql/data ``` This mount point maps your local data directory to the container's `/var/lib/postgresql/data` path, which is where PostgreSQL will store all database files, transaction logs, and system catalogs. ### Step 2: Configure Environment Variables for PostgreSQL Container Environment variables provide configuration parameters that PostgreSQL requires at startup. These variables define the initial database name, user credentials, and data directory location. ```routeros /container/envs/add list=ENV_POSTGRES key=POSTGRES_DB value="myapp" /container/envs/add list=ENV_POSTGRES key=POSTGRES_PASSWORD value="" /container/envs/add list=ENV_POSTGRES key=POSTGRES_USER value="myapp" /container/envs/add list=ENV_POSTGRES key=PGDATA value="/var/lib/postgresql/data/pgdata" /container/envs/add list=ENV_POSTGRES key=POSTGRES_INITDB_ARGS value="--encoding='UTF8' --lc-collate='C' --lc-ctype='C'" ``` The `POSTGRES_DB` variable specifies the name of the initial database that will be created when PostgreSQL starts for the first time. The `POSTGRES_USER` and `POSTGRES_PASSWORD` variables define the superuser account credentials that you'll use to connect to and manage your database. The `PGDATA` variable indicates the location within the container where PostgreSQL will store its data files. The `POSTGRES_INITDB_ARGS` variable provides additional initialization parameters that set the database encoding to UTF8 and the locale settings to C for consistent behavior. ### Step 3: Create the PostgreSQL Container Now you're ready to create and configure the PostgreSQL container instance. This command pulls the official PostgreSQL Docker image from the remote registry and configures it with the environment variables and mount point which were established in the previous steps. ```routeros /container/add remote-image=postgres:15 interface=veth1 root-dir=disk1/images/postgres mountlists=MOUNT_POSTGRES envlists=ENV_POSTGRES name=postgres start-on-boot=yes logging=yes ``` :::warning You can specify a different version for PostgreSQL by changing the `postgres:15` value to any other available PostgreSQL version tag. ::: ### Step 4: Start the PostgreSQL Container With all configuration complete, you're now ready to initiate the PostgreSQL container. Starting the container will launch the PostgreSQL database server, which will become ready to accept connections from your applications. ```routeros /container/start [find where name=postgres] ``` Once started, PostgreSQL will automatically create the initial database and user based on the environment variables you configured. The container will automatically start on system boot if you have configured it to do so. ## Advanced: PostgreSQL with pgAdmin This guide demonstrates how to configure and deploy pgAdmin, the popular web-based administration tool for PostgreSQL databases, as a container on your MikroTik RouterOS device. pgAdmin provides an intuitive graphical interface for managing your PostgreSQL databases servers, allowing you to create databases, execute queries, manage users, and perform various administrative tasks through a web browser. ### Step 1: Create Mount Points Directories for pgAdmin Container Before creating the container, you need to create persistent storage locations where pgAdmin will store its configuration files, session data, and server connection settings. This ensures that your settings and connections remain intact even after container restarts or updates. ```routeros /container/mounts/add list=MOUNT_PGADMIN_CONFIG src=disk1/volumes/pgadmin/config dst=/config /container/mounts/add list=MOUNT_PGADMIN_DATA src=disk1/volumes/pgadmin/data dst=/var/lib/pgadmin ``` The first mount point maps your local configuration directory to the container's `/config` path, where pgAdmin will store server definitions and user preferences. The second mount point maps your local data directory to the container's `/var/lib/pgadmin` path, which houses session information, logs, and runtime data. ### Step 2: Configure Environment Variables for pgAdmin Container Environment variables provide configuration parameters that pgAdmin requires at startup. These variables define the application behavior, default credentials, and network settings. ```routeros /container/envs/add list=ENV_PGADMIN key=PGADMIN_LISTEN_PORT value=80 /container/envs/add list=ENV_PGADMIN key=PGADMIN_DEFAULT_EMAIL value="sysadmin@domain.com" /container/envs/add list=ENV_PGADMIN key=PGADMIN_DEFAULT_PASSWORD value="" /container/envs/add list=ENV_PGADMIN key=PGADMIN_SERVER_JSON_FILE value="/config/servers.json" /container/envs/add list=ENV_PGADMIN key=PGADMIN_PREFERENCES_JSON_FILE value="/config/preferences.json" /container/envs/add list=ENV_PGADMIN key=PGPASS_FILE value="/config/pgpass" /container/envs/add list=ENV_PGADMIN key=PGADMIN_DISABLE_POSTFIX value="True" ``` The `PGADMIN_LISTEN_PORT` variable specifies which port pgAdmin will listen on for incoming web connections—port 80 is used by default for standard HTTP access. The `PGADMIN_DEFAULT_EMAIL` and `PGADMIN_DEFAULT_PASSWORD` variables define the initial administrator credentials that you'll use to log into the pgAdmin web interface for the first time. The remaining variables specify file paths within the container where pgAdmin will store and retrieve server connection configurations, user preferences, and password files data. ### Step 3: Create the pgAdmin Container Now you're ready to create and configure the pgAdmin container instance. This command pulls the official dpage/pgadmin4 Docker image from the remote registry and configures it with the environment variables and mount points which were established in the previous steps. ```routeros /container/add remote-image=dpage/pgadmin4 envlists=ENV_PGADMIN mountlists=MOUNT_PGADMIN_CONFIG,MOUNT_PGADMIN_DATA interface=veth1 logging=yes name=pgadmin root-dir=disk1/images/pgadmin start-on-boot=yes user=0:0 ``` This command specifies the official pgAdmin4 Docker image from Docker Hub, applies your previously defined environment variable list and mount point list, assigns the container to the `veth1` virtual ethernet interface, enables logging for troubleshooting purposes, names the container "pgadmin" for easy identification, stores the container image files in the designated disk location, configures the container to start automatically whenever the router boots, and runs the container with root user privileges. ### Step 4: Disable the Webfig Service As pgAdmin operates as a web-based application and by default listens on HTTP port 80, it conflicts with RouterOS's built-in WebFig web interface which also uses port 80. To prevent this port conflict and ensure pgAdmin functions properly, you must disable the WebFig service. ```routeros /ip/service set www disabled=yes ``` :::tip You have an alternative approach if you prefer to keep WebFig accessible: simply modify the `PGADMIN_LISTEN_PORT` environment variable to use a different port number—such as 8080 or 8888—instead of the default port 80. This allows both services to run simultaneously without conflict. ::: ### Step 5: Start the pgAdmin Container With all configuration complete, you're now ready to initiate the pgAdmin container. Starting the container will launch the pgAdmin web application, which will become accessible through your web browser. ```routeros /container/start [find where name=pgadmin] ``` Once started, you can access the pgAdmin web interface by navigating to your router's IP address in a web browser. Use the email address and password you configured in Step 2 to authenticate and begin managing your PostgreSQL databases servers. --- ## Container - ThingsBoard MQTT/HTTP server The introduction of the container feature into RouterOS made it possible to run all kinds of servers for all sorts of tasks inside the router. This is especially relevant for people who want to reduce the number of devices in their network. Instead of running a server on a separate device/machine, why not run it inside the router? A lot of users need a server that is able to gather the data, store it and display it in a way that it is easy to understand. This is where a platform like [ThingsBoard](https://thingsboard.io/) can come into play. It is primarily positioned as an IoT platform and you can find all sorts of use cases for it that they demonstrate in the [link](https://thingsboard.io/iot-use-cases/). The most appealing part, from the RouterOS user standpoint, is that it can be used as an MQTT server (MQTT broker) or an HTTP server, meaning, you can use [MQTT publish](../../internet-of-things/mqtt/index.md) or [HTTP post](../../system-information-and-utilities/fetch.md) to post the data. You can find the ThingsBoard MQTT API guide by using the link [here](https://thingsboard.io/docs/reference/mqtt-api/) and the HTTP API by using the link [here](https://thingsboard.io/docs/reference/http-api/). In short, you can utilize [scripting](../../developer-guides/scripting/index.md) to collect RouterOS statistics (like uptime, GPS coordinates, packet statistics, and almost anything else that you print into the terminal), then store this information into variables and structure a JSON message out of those. You can then send this message using MQTT or HTTP post to the ThingsBoard via a [scheduler](../../system-information-and-utilities/scheduler.md) (that will run this script whenever you need it). You can find an example of a basic script that does it in [this guide](../../internet-of-things/mqtt/mqtt-and-thingsboard-configuration.md). ThingsBoard will store and display the data with the help of [widgets](https://thingsboard.io/docs/user-guide/ui/widget-library/), which can be used to help you set up dashboards that visualize the data in graphs, tables, maps, and other ways. For example, there are 2 below-mentioned options of the ThingsBoard instances available and each of them uses a different database: - [thingsboard/tb-postgres](https://hub.docker.com/r/thingsboard/tb-postgres/) - [thingsboard/tb-cassandra](https://hub.docker.com/r/thingsboard/tb-cassandra/) You can find more information in the ThingsBoard/docker documentation. In our example, we will showcase **tb-postgres** - a single instance of ThingsBoard with a PostgreSQL database for testing purposes. The guide will showcase an "in-memory" queue type service, but for a production environment, consider using other service types. You can find more information [here](https://thingsboard.io/docs/user-guide/install/docker/). ## Summary **Sub-menu:** `/container` ***note**:* **container** package is required. RouterOS versions that are older than v7.8 will not be able to run this scenario. Make sure to study our [container](../) guide before proceeding with the configuration. Make sure to check the [disclaimer](../#disclaimer) and [requirements](../#requirements) sections to understand all the risks and necessary steps you might be required to do. In this example, we will run it on a [Cloud Hosted Router, CHR](../../getting-started/routeros-licensing/chr/index.md). At the time when the guide was published, the **thingsboard/tb-postgres** image was available for linux/**arm64** and linux/**amd64** OS/architectures **only**. This means you are not able to run this scenario on our arm32-bit architecture RouterOS devices. There are a couple of parameters to keep in mind: - You need to understand that it is a **server** and that you will need to have additional space for the data that is stored there and the image itself. In our tests, 8 GB of disk space was plenty enough but! you might want to consider adding more for real-life applications, especially if you are planning on running more containers. Just remember → it might be better to have a reserve. - Same as with disk space, RAM memory is also important. Per the ThingsBoard documentation, when using a single instance of ThingsBoard with a PostgreSQL database, it is recommended to allocate at least 1GB of RAM and use a minimum load (a few messages per second). 2-4GB RAM is recommended. In other words, if you want to run it on a RouterBoard device, please understand that you might not be able to achieve it on devices that have less than 1 GB RAM. That is why → consider having a device with more RAM memory to spare. Go to the [tips and tricks](../#tips-and-tricks) section to understand how to limit RAM. ## Configuration ### Container mode Enable container mode: ```ros /system/device-mode/update container=yes ``` You will need to confirm the device-mode with a press of the reset button, or a cold reboot, if using a container on X86. ### Networking Add veth interface for the container ```ros /interface/veth/add name=veth1 address=172.18.0.2/24 gateway=172.18.0.1 ``` Create a bridge for the container, assign an IP network to it, and add veth to the bridge ```ros /interface/bridge/add name=dockertb /ip/address/add address=172.18.0.1/24 interface=dockertb /interface/bridge/port/add bridge=dockertb interface=veth1 ``` Setup NAT for outgoing traffic ```ros /ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.18.0.0/24 ``` Forward TCP 9090 for HTTP management (the default HTTP port per ThingsBoard documentation) :::warning We suggest using HTTP access only when testing locally or through a VPN (when you are certain that the local network is safe). When you want to access container WEB management from the internet (from the public network/WAN), please, instead, consider using **HTTPS**. ::: ```ros /ip/firewall/nat/add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=9090 protocol=tcp to-addresses=172.18.0.2 to-ports=9090 ``` In the `dst-address` field shown in the DNAT (dst-nat) rule above, we use the device's local IP address. First, **use local IPs** (local access) **to** **set everything up** **and** **confirm that everything is working**. :::info After going through the rest of the steps shown in this guide and verifying that the ThingsBoard management portal works locally → **further secure the setup**: - (a) make sure that all default ThingsBoard user credentials were changed/removed and strong passwords were implemented (reference ThingsBoard documentation); - (b) **enable** **HTTPS** (the steps will be explained later on in the guide); - (c) preferably change the HTTPS port to a non-standard one (reference ThingsBoard documentation). Only when you increase the security and only then → you can consider enabling remote access from WAN (by using your public IP address in the `dst-address` field instead of the local IP used in the example above). Additionally, to further increase security, use the `src-address` or `src-address-list` parameter, where you can input your trusted public source IP addresses (a list of known/trusted addresses that, for example, belong to your branch office from where you also want to have access to the server). Please understand that only you are responsible for the security. If you leave a door open, someone may exploit it. You need to have networking knowledge and understand the risks when setting up such scenarios. ::: Forward TCP 1883 for non-SSL MQTT (the default MQTT port used per ThingsBoard documentation) :::warning We suggest using non-SSL MQTT (TCP 1883) communication only when testing locally or through a VPN (when you are certain that the local network is safe). > Please consider using **SSL MQTT (TCP port 8883)**, instead of non-SSL MQTT (TCP port 1883), for real-life application, when it comes to access from the internet (from the public network). If you use non-SSL MQTT, the communication between the client (MQTT publisher) and the server (MQTT broker) can be easily sniff/packet captured, and that will compromise authentication data (such as client-ids, usernames and passwords). ::: ```ros /ip/firewall/nat/add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=1883 protocol=tcp to-addresses=172.18.0.2 to-ports=1883 ``` Same as with HTTP access, in the `dst-address` field shown in the DNAT (dst-nat) rule above, we use the device's local IP address. First, **use local IPs** (local access) **to** **set everything up** **and** **confirm that everything is working**. :::info After going through the rest of the steps shown in this guide and verifying that the ThingsBoard non-SSL MQTT communication works locally → **further secure the setup**: > - (a) consider removing template devices from the ThingsBoard installation; - (b) **enable SSL MQTT** (the steps will be explained later on in the guide); - (c) preferably change MQTT port to a non-standard one (reference ThingsBoard documentation). > When you enable SSL MQTT, you can consider opening TCP 8883 (which is the default SSL MQTT port) from WAN (by using your public IP address in the `dst-address` field instead of the local IP, and changing `dst-port` and `to-ports` from 1883 to 8883). Additionally, to further increase security, use `src-address` or `src-address-list` parameters, where you can set up your trusted public IP address list. As a result, only configured trusted IPs will be able to establish an MQTT connection with the ThingsBoard broker. ::: ### Environment variables and mounts Check the [docker-thingsboard](https://hub.docker.com/r/thingsboard/tb-postgres) documentation for exact mounts and variables that need to be added. #### Environment variables ```ros /container/envs/add list=tb_envs key=TB_QUEUE_TYPE value="in-memory" ``` #### Mounts ```ros /container/mounts/add list=mytb-data src=tb/mytb-data dst=/data /container/mounts/add list=mytb-logs src=tb/mytb-logs dst=/var/log/thingsboard ``` ### Getting image To simplify the configuration, we will get the image from an external library, but you can also import it via the [.tar](../#option-b-import-image-from-pc) file. Make sure that you have "Registry URL" set accordingly, limited RAM usage (if necessary), and set up a directory for the image. ```ros /container/config/set registry-url=https://registry-1.docker.io tmpdir=pull ram-high=2048.0MiB ``` Pull image: ```ros /container/add remote-image=thingsboard/tb-postgres:latest interface=veth1 root-dir=ThingsBoard mountlists=mytb-data,mytb-logs envlists=tb_envs logging=yes ``` After running the command, RouterOS should start "extracting" the package. Check "File System" for newly created folders and monitor container status with the command `/container/print`. ### Starting the container After you make sure that the container has been added and the status has changed to `status=stopped` after using `/container/print`, you can initiate it: ```ros /container/start 0 ``` Wait for a couple of minutes for the container to fully load. ## Verification ### Management access After the container is started and installed, access it using any browser, by going to → [http://192.168.88.1:9090](http://192.168.88.1:9090) (where the IP address is the address used in the DNAT rule): ![](./img/container-thingsboard-mqtt-http-server-01.webp) By default, credentials are (Username/Password): - **System Administrator**: sysadmin@thingsboard.org / sysadmin - **Tenant Administrator**: tenant@thingsboard.org / tenant The login prompt should confirm that the server is running. ### MQTT test Log in with the **tenant** and create a new device. Go to the "**Devices**" menu, click on the "**+**" (Add Device) button and choose the "**Add new device**" option: ![](./img/container-thingsboard-mqtt-http-server-02.webp) Name it, however you like, and click on "**Add**": ![](./img/container-thingsboard-mqtt-http-server-03.webp) Check your device access token by clicking on the device you've just created and selecting the "**Manage credentials**" setting (copy the access token generated or type in your own → "YOUR\_TOKEN"): ![](./img/container-thingsboard-mqtt-http-server-04.webp) After these steps, go to the RouterOS settings (back to CHR settings) and create a new [MQTT broker](../../internet-of-things/mqtt/index.md) (**make sure that you have the IoT package installed** because otherwise, you will not have this menu): ```ros /iot/mqtt/brokers/add name=tb address=172.18.0.2 port=1883 username=YOUR_TOKEN ``` Publish a static test MQTT message in the JSON format: ```ros /iot/mqtt/publish broker="tb" topic="v1/devices/me/telemetry" message="{\"test\":\"123\"}" ``` Confirm that the message was posted: ![](./img/container-thingsboard-mqtt-http-server-05.webp) ## Enabling HTTPS and SSL MQTT By default, HTTP and MQTT protocols are used. As mentioned previously in the "Networking" section, working with non-SSL HTTP and non-SSL MQTT is not very safe (unless they are used within heavily protected networks with a well-configured firewall/restricted access), and **we advise enabling HTTPS** and **SSL MQTT**. Please check ThingsBoard documentation for more information → [HTTP over SSL](https://thingsboard.io/docs/user-guide/ssl/http-over-ssl/) and [MQTT over SSL](https://thingsboard.io/docs/user-guide/mqtt-over-ssl/) guides. First of all, there is no SSL without a certificate, and one needs to be made (or purchased). In short, this section will demonstrate how to generate self-signed certificates for HTTPS and SSL MQTT. Then, you will need to upload them to the correct folder within the ThingsBoard installation and alter the ThingsBoard configuration file accordingly. In our guide, we will use RouterOS to generate both [certificates](../../authentication-authorization-accounting/certificates.md) (but you can also use OpenSSL or other tools you want). ### Create certificates Create a certificate for HTTPS: ```ros /certificate/add name=TBhttps common-name=172.18.0.2 /certificate/sign TBhttps ``` Create a certificate for MQTT: ```ros /certificate/add name=TBmqtt common-name=172.18.0.2 /certificate/sign TBmqtt ``` Confirm that they were added with the help of the `/certificate/print` command: ```ros [admin@MikroTik] > /certificate/print Flags: K - PRIVATE-KEY; A - AUTHORITY; T - TRUSTED Columns: NAME, COMMON-NAME, FINGERPRINT # NAME COMMON-NAME FINGERPRINT 0 KAT TBhttps 172.18.0.2 863f4547c74ce3ec70c3e82172502711517b52bbc055d18c24ba4aafec46152c 1 KAT TBmqtt 172.18.0.2 ebf3ff5d03ed4cc73546e058da9bc414cdaf24ce45da29b203348045fbbd21ae ``` Export the certificates using PKCS12 format and set up a password/passphrase for them: ```ros /certificate/export-certificate file-name=keystore export-passphrase=thingsboard_cert_password type=pkcs12 numbers=0 /certificate/export-certificate file-name=mqttserver export-passphrase=thingsboard_mqttcert_password type=pkcs12 numbers=1 ``` Use your own `export-passphrase` and remember it. The output from the command above will create certificate files **keystore.p12** and **mqttserver.p12** that you can download from the "[File List](../../system-information-and-utilities/files.md)" menu: ```ros [admin@MikroTik] > /file/print Columns: NAME, TYPE, SIZE, CREATION-TIME # NAME TYPE SIZE CREATION-TIME 0 tb/mytb-data container store 2023-01-19 13:43:16 1 container-log.0.txt .txt file 2240.5KiB 2023-01-27 15:37:41 2 skins directory 2023-01-18 15:12:22 3 tb/mytb-logs container store 2023-01-27 12:24:30 4 pull directory 2023-01-19 13:41:01 5 pub directory 2023-01-18 16:15:29 6 tb directory 2023-01-23 15:46:39 7 tb/data container store 2023-01-18 16:50:08 8 tb/logs container store 2023-01-18 16:50:08 9 mqttserver.p12 .p12 file 2438 2023-01-27 15:36:26 10 keystore.p12 .p12 file 2448 2023-01-27 15:08:07 11 ThingsBoard container store 2023-01-19 13:40:50 ``` Download both files from the router into any directory on your PC. For example, we've downloaded them into `C:\Users\Admin\Desktop\ThingsBoard` folder. ### Download the ThingsBoard's configuration file Open your command terminal ("CMD", as Administrator, for Windows users, or "Linux Shell or Command Terminal" for Linux users) and navigate to the directory where the certificates are: ```powershell C:\Windows\System32>cd c:\Users\Admin\Desktop\ThingsBoard C:\Users\Admin\Desktop\ThingsBoard>dir Directory of C:\Users\Admin\Desktop\ThingsBoard 27.01.2023 15:36 . 27.01.2023 15:36 .. 27.01.2023 15:09 2 448 keystore.p12 27.01.2023 15:36 2 434 mqttserver.p12 2 File(s) 4 882 bytes 2 Dir(s) 51 380 154 368 bytes free ``` From this directory, you will need to connect to the router's IP via SFTP (which allows you to transfer files using SSH protocol, so you need to make sure that [SSH service](../../system-information-and-utilities/services.md) is enabled beforehand): ```powershell c:\Users\Admin\Desktop\ThingsBoard>sftp admin@192.168.88.1 The authenticity of host '192.168.88.1 (192.168.88.1)' can't be established. RSA key fingerprint is SHA256:/WmmZErqWL51SOlS4EaGvSQ0i4HPnSIHCEjnc8AmP2c. Are you sure you want to continue connecting (yes/no/[fingerprint])?yes admin@192.168.88.1's password: Connected to 192.168.88.1. sftp> ``` While the container is running, go to the ThingsBoard configuration file folder (use `dir` or `ls` command to see the content of the folder you are in and `cd` command to go to the folder of our choice). By default, it should be the folder with the "**thingsboard.yml**" configuration file in it. In our example, we could locate it under: ```powershell sftp> cd ThingsBoard/usr/share/thingsboard/conf sftp> dir banner.txt i18n logback.xml templates thingsboard.conf thingsboard.yml ``` Download the "**thingsboard.yml**" configuration using the `get` command. This will download the default ThingsBoard configuration file to your machine (to the directory from where you initiated SFTP): ```powershell sftp> get thingsboard.yml Fetching /ThingsBoard/usr/share/thingsboard/conf/thingsboard.yml to thingsboard.yml /ThingsBoard/usr/share/thingsboard/conf/thingsboard.yml 100% 67KB 2.0MB/s 00:00 sftp> quit c:\Users\Admin\Desktop\ThingsBoard>dir Directory of c:\Users\Admin\Desktop\ThingsBoard 30.01.2023 10:59 . 30.01.2023 10:59 .. 27.01.2023 15:09 2 448 keystore.p12 27.01.2023 15:36 2 434 mqttserver.p12 30.01.2023 10:59 68 846 thingsboard.yml 3 File(s) 73 728 bytes 2 Dir(s) 50 901 626 880 bytes free ``` ### Alter the ThingsBoard's settings Open "**thingsboard.yml**" via your preferred text editor (notepad or any other), and alter a few lines. You can backup this file and save it with a different name to have a copy of the default settings, in case of misconfiguration. #### HTTPS-related settings 1. Enable SSL → Change "SSL\_ENABLED:**false**" to "SSL\_ENABLED:**true**". 2. Change credentials type → from "SSL\_CREDENTIALS\_TYPE:**PEM**" to "SSL\_CREDENTIALS\_TYPE:**KEYSTORE**". 3. Change the path → from "SSL\_KEY\_STORE:**classpath:keystore/keystore.p12**" to "SSL\_KEY\_STORE:**keystore.p12**" (optional). 4. Disable key alias setting → comment it → just put the "**#**" symbol in front of the `key_alias: "${SSL_KEY_ALIAS:tomcat}"` line. 5. Input your own certificate password that was used in RouterOS → from "SSL\_KEY\_STORE\_PASSWORD:**thingsboard**" to "SSL\_KEY\_STORE\_PASSWORD:**thingsboard\_cert\_password**" and from "SSL\_KEY\_PASSWORD:**thingsboard**" to "SSL\_KEY\_PASSWORD:**thingsboard\_cert\_password**". ```js ssl: # Enable/disable SSL support enabled: "${SSL_ENABLED:true}" # Server SSL credentials credentials: # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) type: "${SSL_CREDENTIALS_TYPE:KEYSTORE}" # Keystore server credentials keystore: # Type of the key store (JKS or PKCS12) type: "${SSL_KEY_STORE_TYPE:PKCS12}" # Path to the key store that holds the SSL certificate store_file: "${SSL_KEY_STORE:keystore.p12}" # Password used to access the key store store_password: "${SSL_KEY_STORE_PASSWORD:thingsboard_cert_password}" # Key alias #key_alias: "${SSL_KEY_ALIAS:tomcat}" # Password used to access the key key_password: "${SSL_KEY_PASSWORD:thingsboard_cert_password}" ``` #### MQTT-related settings 1. Enable SSL → Change "MQTT\_SSL\_ENABLED:**false**" to "MQTT\_SSL\_ENABLED:**true**"; 2. Change credential type → from "MQTT\_SSL\_CREDENTIALS\_TYPE:**PEM**" to "MQTT\_SSL\_CREDENTIALS\_TYPE:**KEYSTORE**"; 3. Change the type of key → from "MQTT\_SSL\_KEY\_STORE\_TYPE:**JKS**" to "MQTT\_SSL\_KEY\_STORE\_TYPE:**PKCS12**"; 4. Change the path (extension) → from "MQTT\_SSL\_KEY\_STORE:mqttserver**.jks**" to "MQTT\_SSL\_KEY\_STORE:mqttserver**.p12**". 5. Disable key alias setting → comment it → just put the "**#**" symbol in front of the `key_alias: "${MQTT_SSL_KEY_ALIAS:}"` line; 6. Input your own certificate password that was used in RouterOS → from "MQTT\_SSL\_KEY\_STORE\_PASSWORD:**server\_ks\_password**" to "MQTT\_SSL\_KEY\_STORE\_PASSWORD:**thingsboard\_mqttcert\_password**" and from "MQTT\_SSL\_KEY\_PASSWORD:**server\_key\_password**" to "MQTT\_SSL\_KEY\_PASSWORD:**thingsboard\_mqttcert\_password**". ```js ssl: # Enable/disable SSL support enabled: "${MQTT_SSL_ENABLED:true}" # Server SSL credentials credentials: # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) type: "${MQTT_SSL_CREDENTIALS_TYPE:KEYSTORE}" # Keystore server credentials keystore: # Type of the key store (JKS or PKCS12) type: "${MQTT_SSL_KEY_STORE_TYPE:PKCS12}" # Path to the key store that holds the SSL certificate store_file: "${MQTT_SSL_KEY_STORE:mqttserver.p12}" # Password used to access the key store store_password: "${MQTT_SSL_KEY_STORE_PASSWORD:thingsboard_mqttcert_password}" # Optional alias of the private key; If not set, the platform will load the first private key from the keystore; #key_alias: "${MQTT_SSL_KEY_ALIAS:}" # Optional password to access the private key. If not set, the platform will attempt to load the private keys that are not protected with the password; key_password: "${MQTT_SSL_KEY_PASSWORD:thingsboard_mqttcert_password}" ``` :::info Leave the rest of the settings at default value. Do not delete/change lines that are not shown in the examples above unless you know what you are doing. ::: Apply the changes to the "**thingsboard.yml**" file (re-save it after editing). ### Upload altered ThingsBoard configuration file All that is left is to overwrite the current configuration file with an altered file and upload both certificates. Once again, make sure your terminal is pointing to the right folder (where 3 files are located → both certificates and an altered "thingsboard.yml" file), and, from there, SFTP into the container's configuration file directory: ```powershell c:\Users\Admin\Desktop\ThingsBoard>dir Directory of c:\Users\Admin\Desktop\ThingsBoard 30.01.2023 10:59 . 30.01.2023 10:59 .. 27.01.2023 15:09 2 448 keystore.p12 27.01.2023 15:36 2 434 mqttserver.p12 30.01.2023 10:59 68 846 thingsboard.yml 3 File(s) 73 728 bytes 2 Dir(s) 50 901 626 880 bytes free c:\Users\Admin\Desktop\ThingsBoard>sftp admin@192.168.88.1 admin@192.168.88.1's password: Connected to 192.168.88.1. sftp> cd ThingsBoard/usr/share/thingsboard/conf sftp> dir banner.txt i18n logback.xml templates thingsboard.conf thingsboard.yml ``` Upload these files with the help of the `put` command: ```powershell sftp> put thingsboard.yml Uploading thingsboard.yml to /ThingsBoard/usr/share/thingsboard/conf/thingsboard.yml thingsboard.yml 100% 67KB 2.2MB/s 00:00 sftp> put keystore.p12 Uploading keystore.p12 to /ThingsBoard/usr/share/thingsboard/conf/keystore.p12 keystore.p12 100% 2448 1.2MB/s 00:00 sftp> put mqttserver.p12 Uploading mqttserver.p12 to /ThingsBoard/usr/share/thingsboard/conf/mqttserver.p12 mqttserver.p12 100% 2434 608.5KB/s 00:00 sftp> dir banner.txt i18n keystore.p12 logback.xml mqttserver.p12 templates thingsboard.conf thingsboard.yml ``` Restart the container: ```ros [admin@MikroTik] > /container/stop 0 [admin@MikroTik] > /container/start 0 ``` Make sure to wait for the container to stop (`status=stopped` should be shown after using `/container/print` command) before initiating it again. ### Confirm HTTPS access Now, you should be able to access [https://your\_IP:9090](https://192.168.88.1) (where the IP address is the address used in the DNAT rule): ![](./img/container-thingsboard-mqtt-http-server-06.webp) :::info Since we are using a self-signed certificate that was not issued by a trusted authority, an error indicating that the connection is not secure might appear but you can view the certificate through the browser (confirm it is the one), accept the risk, and continue. ::: ### Confirm SSL MQTT connection :::info **Do not forget to alter the port forwarding rule** that is shown in the "Networking" section by changing **`dst-port`** and **`to-ports`** from 1883 (standard non-SSL MQTT port) **to 8883** (**SSL MQTT port**). ::: In this example, we will test a [one-way SSL communication access token scenario](../../internet-of-things/mqtt/mqtt-and-thingsboard-configuration.md#one-way-ssl-communication-scenario). #### Testing with the device that is running the container :::info The MQTT certificate should already be installed into the device's system (because it is the device that generated it). ::: Add MQTT broker: ```ros /iot/mqtt/brokers/add name=tbssl address=172.18.0.2 port=8883 username=YOUR_TOKEN ssl=yes ``` Publish a static test MQTT message in the JSON format: ```ros /iot/mqtt/publish broker="tbssl" topic="v1/devices/me/telemetry" message="{\"test\":\"123\"}" ``` Confirm that it was received by the MQTT broker: ![](./img/container-thingsboard-mqtt-http-server-07.webp) #### Testing with another device When you have two RouterOS devices, one that is running the container (and, in our example, is the same device that generated the certificate) and the other one that you wish to test the MQTT connection from (let's say, an [LTAP](https://mikrotik.com/product/ltap) or any other RouterOS device with IoT package installed) → you will need to import the certificate to the second device. Drag and drop the exported certificate (**mqttserver.p12**) into the device's "File List": ```ros [admin@LTAP] > /file/print Columns: NAME, TYPE, SIZE, CREATION-TIME # NAME TYPE SIZE CREATION-TIME 0 mqttserver.p12 .p12 file 2438 2023-01-30 13:28:11 1 flash disk 2021-07-06 14:51:53 2 flash/pub directory 2021-07-06 14:51:53 3 flash/skins directory 1970-01-01 02:00:07 [admin@LTAP] > ``` Import the certificate: ```ros [admin@LTAP] > /certificate/import file-name=mqttserver.p12 passphrase=thingsboard_mqttcert_password ``` Add MQTT broker, where the address is the IP address `dst-address` that is used in the TCP 8883 port-forwarding rule on the ThingsBoard-container router: ```ros /iot/mqtt/brokers/add name=tbssl address=192.168.88.1 port=8883 username=YOUR_TOKEN ssl=yes ``` Publish a static test MQTT message in the JSON format: ```ros /iot/mqtt/publish broker="tbssl" topic="v1/devices/me/telemetry" message="{\"test\":\"123\"}" ``` And confirm that the broker received it → under the "Latest Telemetry" section on ThingsBoard. --- ## VETH(Containers) VETH (Virtual Ethernet) is a virtual network interface that provides network connectivity for containers. It functions as a virtual Ethernet port that connects RouterOS to a container, enabling the container to communicate with other interfaces and networks. VETH interfaces behave like standard Ethernet interfaces. They can be assigned static IPv4 and IPv6 addresses, obtain addresses via a DHCP client, and support SLAAC. Additionally, VETH interfaces can participate in bridge or routing configurations, just like physical interfaces. ## Basic Configuration Example There are multiple ways to configure VETH. Below are simple examples. ```ros # VETH with DHCP-client /interface/veth/add dhcp=yes # VETH with static address /interface/veth/add address=10.1.1.10/24 gateway=10.1.1.1 ``` After configuring the interface, you can assign it to a container. The container should obtain either the IP assigned by the DHCP server or the static address. ## Properties ### VETH **Sub-menu:** `/interface/veth/add` Configuration settings for the VETH interface. | Parameter | Type | Default | Description | | :-- | :-- | :-- | :-- | | **address** | IPv4/IPv6 address | **None** | IPv4 or IPv6 address that will be assigned to the interface | | **gateway** | IPv4 address | **None** | IPv4 gateway address | | **gateway6** | IPv6 address | **None** | IPv6 gateway address | | **mac-address** | MAC address | **None** | Interface MAC address | | **container-mac-address** | MAC address | **None** | MAC address that will be assigned to the container | | **dhcp** | yes / no | **no** | Enables DHCP client on the interface | | **name** | string | **None** | Interface name | --- ## API **Application Programming Interface (API)** lets users create custom software solutions to communicate with RouterOS for information gathering, adjusting configuration, and managing the router. The API closely follows the syntax of the **command-line interface (CLI)**. You can use it to create translated or custom configuration tools that make it easier to run and manage RouterOS routers. The API service must be enabled before you try to establish a connection. By default, the API uses TCP ports **8728** and **8729** (secure). The **API-SSL** service can operate in two modes: with or without a certificate. Without a certificate provided in the `/ip service` settings, the client must use an anonymous Diffie-Hellman cipher to establish a connection. If the service uses a certificate, the client can establish a TLS session. ## Protocol You communicate with the router by sending sentences and receiving one or more sentences in return. A sentence is a sequence of words terminated by a zero-length word. A word is part of a sentence encoded in a certain way: encoded length followed by data. When the router receives a full sentence (command word, one or more attribute words, and a zero-length word), it evaluates and executes the sentence and then forms and returns a reply. ### API sentences Sentence is the main object of communication with the API. - Empty sentences are ignored. - A sentence is processed after receiving zero length word. - There is a limit on the number and size of sentences that the client can send before it has logged in. - Do not rely on the order of attribute words, because the order and count can be changed by the `.proplist` attribute. The sentence structure is as follows: - The first word must contain a *command word*. - The sentence must contain a *zero-length word* to terminate it. - The sentence can contain zero or more *attribute words*. The order of attribute words does not matter. - The sentence can contain zero or more *query words*. The order of query words is important. :::danger If a zero-length word is not provided, the router will not start evaluating the sent words and will consider all the following input as part of the same sentence. ::: ### API words - Words are grouped into sentences. A zero-length word terminates a sentence. - Each word is encoded as a length followed by that many bytes of content. - The scheme allows encoding of lengths up to **0xFFFFFFFF**; only four-byte lengths are supported. - **len** bytes are sent most significant first (network order). - If the first byte of the word is **>= 0xF8**, it is a reserved control byte. After receiving an unknown control byte, an API client cannot proceed because it does not know how to interpret the following bytes. - Currently, control bytes are not used. The length of the word is encoded as follows: | Value of length | # of bytes | Encoding | |:--|--:|:--| | `0 <= len <= 0x7F` | 1 | len, lowest byte | | `0x80 <= len <= 0x3FFF` | 2 | len | 0x8000, two lower bytes | | `0x4000 <= len <= 0x1FFFFF` | 3 | len | 0xC00000, three lower bytes | | `0x200000 <= len <= 0xFFFFFFF` | 4 | len | 0xE0000000 | | `len >= 0x10000000` | 5 | 0xF0 and len as four bytes | In general, *words* can be described like this ``. Word content can be separated into five parts: *[command word](#command-word)*, *[attribute word](#attribute-word)*, *[API attribute word](#api-attribute-word)*, *[query word](#query-word)*, and *[reply word](#reply-word)* #### Command word The first word in the sentence must be a command, followed by attribute words and a zero-length or terminating word. The name of the command word must begin with a slash (`/`). Names of commands closely follow the CLI. Spaces between path objects are not supported; they must be replaced with slashes (`/`). Some commands are specific to API: - `login` - used for login process to provide login credentials. - `cancel` - used to cancel currently running command. Command word structure in the strict order: - encoded length - content prefix */* - CLI converted command A few examples of command word content: ```ros /login ``` ```ros /user/active/listen ``` ```ros /interface/vlan/remove ``` ```ros /system/reboot ``` #### Attribute word Each *command word* has its list of *attribute words* depending on content. The *attribute word* structure consists of five parts in this order: - encoded length - content is prefixed with equals (`=`) character - attribute name - equals (`=`) character as a name and value separator - attribute value if there is one. Some attribute examples (excluding encoded length prefix): ```ros =address=10.0.0.1 ``` ```ros =disable-running-check=yes ``` The value can contain *equal* (`=`) symbols: ``` =name=iu=c3Eeg ``` Value can be empty: ```ros =comment= ``` Keep in mind that the order of attribute words and **API** parameters is not important and should not be relied on. #### API attribute word API attribute word structure is in the strict order: - encoded length - content is prefixed with the dot (`.`) character - attribute name - equals (`=`) character as a name and value separator - attribute value Currently, the only such API attribute is the [`tag`](#tags). #### Query word Sentences can have additional query parameters that restrict their scope. See the [query section](#queries) for details. - Query words begin with `?`. - Currently, only the `print` command handles query words. Example of a sentence using query word attributes: ```ros /interface/print ?type=ether ?type=vlan ?#|! ``` :::info The order of query words is significant ::: #### Reply word It is only sent by the router in response to the full sentence received from the client. - The first word of reply begins with `!`. - Each sentence sent generates at least one reply (if a connection does not get terminated). - The last reply for every sentence is the reply that has the first word `!done`. - Errors and exceptional conditions begin with `!trap`. - Data replies begin with `!re`. - Replies of commands which do not have any data to reply with, begin with `!empty`. - If the **API** connection must be closed, RouterOS sends a `!fatal` with a reason in a description and then closes the connection. ## Initial login - The client sends a username and password in the first message. In our example, we use `admin` with an empty password: ```ros /login =name=admin =password= ``` The router replies with `!done` if authentication is successful. - The password is sent in plain text. - If an error occurs, the reply contains `=message=`. - After a successful login, the client can start issuing commands. ## Tags The **API** allows running several commands simultaneously without waiting for the previous one to complete. If the API client does this and needs to differentiate command responses, it can use the `tag` parameter in the command sentences. If a sentence contains a `tag`, each reply for that sentence will carry the same tag value. If you omit the `tag` parameter or leave it empty, responses for the command will not include a tag parameter. ## Command description - `/cancel` - Optional argument: `=tag=`; without it, all running commands are cancelled. - Does not cancel itself. - All canceled commands are interrupted and usually generate `!trap` and `!done` responses. - Note that `/cancel` is a separate command and can have its own unique `.tag` parameter that is not related to the command's `=tag` argument. - `listen` - The `listen` command is available wherever the CLI `print` command is available, but it may not work everywhere. - `!re` sentences are generated when something changes in a particular item list. - When an item is deleted or disappears, the `!re` sentence includes the value `=.dead=yes`. - This command does not terminate on its own; use the `/cancel` command to stop it. - `getall` - The `getall` command is available wherever the CLI `print` command is available (`getall` is an alias for `print`). - Replies contain a `=.id=` property. - `print` - The API `print` command differs from the CLI counterpart in the following ways: - The `where` argument is not supported; items can be filtered using [query words](#queries). - The `.proplist` argument is a comma-separated list of property names to include in returned items. - Returned items may have additional properties. - The order of returned properties is not significant and cannot be relied on. - If the list contains duplicate entries, handling of those duplicates is undefined. - If a property appears in `.proplist` but is absent from an item, that item does not have the property value (`?name` evaluates to false for that item). - If `.proplist` is absent, all properties are included as requested by the `print` command, even those with slow access time (such as file contents and performance counters). Therefore, use of `.proplist` is encouraged. Omitting `.proplist` may incur a high performance penalty if the `=detail=` argument is set. ### Queries The `print` and `getall` commands accept query words that limit the set of returned sentences. - Query words begin with `?`. - The order of query words is significant. A query is evaluated starting from the first word. - A query is evaluated for each item in the list. If the query succeeds, the item is processed, if a query fails, the item is ignored. - A query is evaluated using a stack of boolean values. Initially, the stack contains an infinite amount of `true` values. At the end of the evaluation, if the stack contains at least one `false` value, the query fails. - Query words operate according to the following rules: | Query | Description | |:--|:--| | `?name` | pushes `true` if an item has a value of property `name`, `false` if it does not. | | `?-name` | pushes `true` if an item does not have a value of property `name`, `false` otherwise. | | `?name=x` | pushes `true` if the property `name` has a value equal to *x*, `false` otherwise. | | `?name=x` | pushes `true` if the property `name` has a value greater than *x*, `false` otherwise. | | `?#operations` | applies operations to the values in the stack. operation string is evaluated from left to right.the sequence of decimal digits followed by any other character or end of the word is interpreted as a stack index. top value has an index 0.an index that is followed by a character pushes a copy of the value at that index.an index that is followed by the end of the word replaces all values with the value at that index.`!` character replaces the top value with the opposite.& pops two values and pushes the result of logical `and` operation.`\|` pops two values and pushes the result of logical `or` operation.`.` after an index does nothing.`.` after another character pushes a copy of the top value. | :::info Regular expressions are not supported in API, so do not try to send a query with the **`~`** symbol ::: Examples: - Get all ethernet and VLAN interfaces (equivalent to CLI command `/interface/print where type=ether || type=vlan`): ```ros /interface/print ?type=ether ?type=vlan ?#| ``` - Get all routes that have a non-empty comment (equivalent to CLI command `/ip/route/print where comment`): ```ros /ip/route/print ?>comment= ``` - Get all routes that do not have distance greater than 1 and gateway equal to 172.16.1.1 (equivalent to CLI command `/ip/route/print where !(distance>1 && gateway=172.16.1.1)`): ```ros /ip/route/print ?>distance=1 ?gateway=172.16.1.1 ?#&! ``` ### OID The `print` command can return OID values for properties that are available in SNMP. In the CLI, OID values can be seen by running the `print oid` command. In the API, these properties have names that end with `.oid` and can be retrieved by adding their names to the value of `.proplist`. An example: ```ros /system/resource/print =.proplist=uptime,cpu-load,uptime.oid,cpu-load.oid ``` The router sends a reply: ```ros !re =uptime=01:22:53 =cpu-load=0 =uptime.oid=.1.3.6.1.2.1.1.3.0 =cpu-load.oid=.1.3.6.1.2.1.25.3.3.1.2.1 !done ``` ### !trap When an API sentence fails for any reason, the router returns a trap accompanied by a: - A `message` attribute that provides more details about the failure. - A `category` attribute. If the error is general, the router returns the error category. Possible values for this attribute are: - 0 - missing item or command - 1 - argument value failure - 2 - execution of command interrupted - 3 - scripting related failure - 4 - a general failure - 5 - API related failure - 6 - TTY related failure - 7 - value generated with :return command ```ros /ip/address/add =address=192.168.88.1 =interface=asdf ``` Router reply with: ```bash !trap =category=1 =message=input does not match any value of interface ``` ## Modify existing items Like its CLI counterpart, the API has a `set` command that accepts an item's ID and parameters to set. The only exception is that the API does not accept queries directly with the `set` command. For example, CLI command to set MTU value on all ethernet interfaces: ```ros /interface set [find where type=ether] mtu=1500 ``` To achieve the same with API, you first need to run a `print` query to get IDs, and only then execute the `set` command. ```ros /interface/print =.proplist=.id ?type=ether ``` Router reply with: ```bash !re =.id=*1 !re =.id=*2 ``` Now you need to loop through returned IDs and send the `set` command for each: ```ros /interface/set =.id=*1 =mtu=1500 /interface/set =.id=*2 =mtu=1500 ``` ## Command examples ### `/user/active/listen` ```ros /user/active/listen !re =.id=*68 =radius=no =when=2006-10-24 08:40:42 =name=admin =address=0.0.0.0 =via=console !re =.id=*68 =.dead=yes ... more !re sentences ... ``` ### /cancel, simultaneous commands Start listening for interface changes (tag is 2): ```ros /interface/listen .tag=2 ``` Send a command to disable interface (tag is 3): ```ros /interface/set =disabled=yes =.id=ether1 .tag=3 ``` The router replies with `!done` for the `disable` command (executed with tag 3): ```ros !done .tag=3 ``` Enable interface (tag is 4): ```ros /interface/set =disabled=no =.id=ether1 .tag=4 ``` Client receives from the router an update for the `listen` command generated by a change made by the first `set` command (executed with tag 3): ```ros !re =.id=*1 =disabled=yes =dynamic=no =running=no =name=ether1 =mtu=1500 =type=ether .tag=2 ``` Followed by `done` for `enable` command (executed with tag 4): ```ros !done .tag=4 ``` Send a command to get interface list (tag is 5): ```ros /interface/getall .tag=5 ``` Client receives updates generated by a change made by the second `set` command (executed with tag 4): ```ros !re =.id=*1 =disabled=no =dynamic=no =running=yes =name=ether1 =mtu=1500 =type=ether .tag=2 ``` Client receives replies to `getall` command (executed with tag 5): ```ros !re =.id=*1 =disabled=no =dynamic=no =running=yes =name=ether1 =mtu=1500 =type=ether .tag=5 !re =.id=*2 =disabled=no =dynamic=no =running=yes =name=ether2 =mtu=1500 =type=ether .tag=5 !done .tag=5 ``` Stop listening - request to cancel command with tag 2, `cancel` itself uses tag 7: ```ros /cancel =tag=2 .tag=7 ``` `listen` command is interrupted (tag 2): ```ros !trap =category=2 =message=interrupted .tag=2 ``` `cancel` command is finished (tag 7): ```ros !done .tag=7 ``` `listen` command is finished (tag 2): ```ros !done .tag=2 ``` ## Example client A simple [API client in Python3](./python3-example.md) Example output with the old login method: ```bash debian@localhost:~/api-test$ ./api.py 10.0.0.1 admin '' <<< /login <<< >>> !done >>> =ret=93b438ec9b80057c06dd9fe67d56aa9a >>> <<< /login <<< =name=admin <<< =response=00e134102a9d330dd7b1849fedfea3cb57 <<< >>> !done >>> /user/getall <<< /user/getall <<< >>> !re >>> =.id=*1 >>> =disabled=no >>> =name=admin >>> =group=full >>> =address=0.0.0.0/0 >>> =netmask=0.0.0.0 >>> >>> !done >>> ``` --- ## Python3 Example A simple Python3 example client. - usage: `api.py `, for example: `api.py 10.0.0.1 admin Badpassword123 True` - after that, type words from the keyboard, terminating them with a new line - Because an empty word terminates a sentence, you should press enter **twice** after the last word to send a sentence to the router. ```py #!/usr/bin/python3 # -*- coding: latin-1 -*- import sys, binascii, socket, select, ssl import hashlib class ApiRos: "Routeros api" def __init__(self, sk): self.sk = sk self.currenttag = 0 def login(self, username, pwd): for repl, attrs in self.talk(["/login", "=name=" + username, "=password=" + pwd]): if repl == '!trap': return False elif '=ret' in attrs.keys(): #for repl, attrs in self.talk(["/login"]): chal = binascii.unhexlify((attrs['=ret']).encode(sys.stdout.encoding)) md = hashlib.md5() md.update(b'\x00') md.update(pwd.encode(sys.stdout.encoding)) md.update(chal) for repl2, attrs2 in self.talk(["/login", "=name=" + username, "=response=00" + binascii.hexlify(md.digest()).decode(sys.stdout.encoding) ]): if repl2 == '!trap': return False return True def talk(self, words): if self.writeSentence(words) == 0: return r = [] while 1: i = self.readSentence(); if len(i) == 0: continue reply = i[0] attrs = {} for w in i[1:]: j = w.find('=', 1) if (j == -1): attrs[w] = '' else: attrs[w[:j]] = w[j+1:] r.append((reply, attrs)) if reply == '!done': return r def writeSentence(self, words): ret = 0 for w in words: self.writeWord(w) ret += 1 self.writeWord('') return ret def readSentence(self): r = [] while 1: w = self.readWord() if w == '': return r r.append(w) def writeWord(self, w): print(("<<< " + w)) self.writeLen(len(w)) self.writeStr(w) def readWord(self): ret = self.readStr(self.readLen()) print((">>> " + ret)) return ret def writeLen(self, l): if l < 0x80: self.writeByte((l).to_bytes(1, sys.byteorder)) elif l < 0x4000: l |= 0x8000 self.writeByte(((l >> 8) & 0xFF).to_bytes(1, sys.byteorder)) self.writeByte((l & 0xFF).to_bytes(1, sys.byteorder)) elif l < 0x200000: l |= 0xC00000 self.writeByte(((l >> 16) & 0xFF).to_bytes(1, sys.byteorder)) self.writeByte(((l >> 8) & 0xFF).to_bytes(1, sys.byteorder)) self.writeByte((l & 0xFF).to_bytes(1, sys.byteorder)) elif l < 0x10000000: l |= 0xE0000000 self.writeByte(((l >> 24) & 0xFF).to_bytes(1, sys.byteorder)) self.writeByte(((l >> 16) & 0xFF).to_bytes(1, sys.byteorder)) self.writeByte(((l >> 8) & 0xFF).to_bytes(1, sys.byteorder)) self.writeByte((l & 0xFF).to_bytes(1, sys.byteorder)) else: self.writeByte((0xF0).to_bytes(1, sys.byteorder)) self.writeByte(((l >> 24) & 0xFF).to_bytes(1, sys.byteorder)) self.writeByte(((l >> 16) & 0xFF).to_bytes(1, sys.byteorder)) self.writeByte(((l >> 8) & 0xFF).to_bytes(1, sys.byteorder)) self.writeByte((l & 0xFF).to_bytes(1, sys.byteorder)) def readLen(self): c = ord(self.readStr(1)) # print (">rl> %i" % c) if (c & 0x80) == 0x00: pass elif (c & 0xC0) == 0x80: c &= ~0xC0 c <<= 8 c += ord(self.readStr(1)) elif (c & 0xE0) == 0xC0: c &= ~0xE0 c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) elif (c & 0xF0) == 0xE0: c &= ~0xF0 c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) elif (c & 0xF8) == 0xF0: c = ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) return c def writeStr(self, str): n = 0; while n < len(str): r = self.sk.send(bytes(str[n:], 'UTF-8')) if r == 0: raise RuntimeError("connection closed by remote end") n += r def writeByte(self, str): n = 0; while n < len(str): r = self.sk.send(str[n:]) if r == 0: raise RuntimeError("connection closed by remote end") n += r def readStr(self, length): ret = '' # print ("length: %i" % length) while len(ret) < length: s = self.sk.recv(length - len(ret)) if s == b'': raise RuntimeError("connection closed by remote end") ret += s.decode(sys.stdout.encoding, "replace") return ret def open_socket(dst, port, secure=False): s = None res = socket.getaddrinfo(dst, port, socket.AF_UNSPEC, socket.SOCK_STREAM) af, socktype, proto, canonname, sockaddr = res[0] skt = socket.socket(af, socktype, proto) if secure: context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) context.set_ciphers("ECDHE-RSA-AES256-GCM-SHA384") s = context.wrap_socket(skt, server_hostname=dst) else: s = skt s.connect(sockaddr) return s def main(): s = None dst = sys.argv[1] user = "admin" passw = "" secure = False port = 0 # use default username and password if not specified arg_nr = len(sys.argv) if arg_nr > 2: user = sys.argv[2] if arg_nr > 3: passw = sys.argv[3] if arg_nr > 4: secure = sys.argv[4].lower() == 'true' if (port==0): port = 8729 if secure else 8728 s = open_socket(dst, port, secure) if s is None: print ('could not open socket') sys.exit(1) apiros = ApiRos(s); if not apiros.login(user, passw): return inputsentence = [] while 1: r = select.select([s, sys.stdin], [], [], None) if s in r[0]: # something to read in socket, read sentence x = apiros.readSentence() if sys.stdin in r[0]: # read line from input and strip off newline l = sys.stdin.readline() l = l[:-1] # if empty line, send sentence and start with new # otherwise append to input sentence if l == '': apiros.writeSentence(inputsentence) inputsentence = [] else: inputsentence.append(l) if __name__ == '__main__': main() ``` --- ## Developer Guides import DocCardList from '@theme/DocCardList'; Cover RouterOS automation and integration interfaces, including the API, scripting, and REST API. Use this section when building tools, scripts, or applications that interact with RouterOS. --- ## REST API The term **REST API** generally refers to an **API** accessed via HTTP protocol at a predefined set of resource-oriented URLs. **REST API** is implemented as a JSON wrapper interface of the [**API**](./api/index.md). It allows you to create, read, update and delete resources and call arbitrary console commands. To start using REST API, enable either the `www-ssl` or `www` service in the [`IP Service`](../system-information-and-utilities/services.md) menu. When the `www-ssl` service is running (HTTPS access), you can connect to: - `https:///rest`. When the `www` service is running (HTTP access), you can connect to: - `http:///rest`. The main risk of using HTTP access (`www` service) is that authentication credentials can be read by passive eavesdropping. Use it only for tests on networks where an attacker does not have access or when you are certain the data cannot be decrypted, for example when HTTP is carried over an encrypted tunnel. The easiest way to begin is with cURL, wget, the fetch tool, or any other simple HTTP client. ```sh $ curl -k -u admin: https://10.155.101.214/rest/system/resource [{"architecture-name":"tile","board-name":"CCR1016-12S-1S+", "build-time":"2020-12-04 14:19:51","cpu":"tilegx","cpu-count":"16", "cpu-frequency":"1200","cpu-load":"1","free-hdd-space":"83439616", "free-memory":"1503133696","platform":"MikroTik", "total-hdd-space":"134217728","total-memory":"2046820352", "uptime":"2d20h12m20s","version":"7.1beta4 (development)"}] ``` ## Authentication Authentication to the REST API uses [HTTP Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication). Your username and password are the same as those of a console user (by default, **admin** with no password). To use a secure connection (HTTPS), set up certificates in the [Certificate menu](../authentication-authorization-accounting/certificates.md) and configure `www-ssl` to use the newly created or imported certificate. If you use a self‑signed certificate, import its CA into the client's trusted root. For tests you can connect insecurely (`-k` with cURL or `--no-check-certificate` with wget). ### JSON format The server broadly follows the ECMA‑404 standard, with the following notes: - In JSON replies all object values are encoded as strings, even if the underlying data is a number or a boolean. - The server also accepts numbers in octal format (begins with 0) and hexadecimal format (begins with 0x). If the numbers are sent in a string format, they are assumed to be in decimal format. - Numbers with exponents are not supported. ## HTTP Methods The following table summarizes the supported HTTP methods | HTTP Verb | CRUD | ROS | Description | |:--|:--|:--|:--| | GET | Read | print | To get the records. | | PATCH | Update/Modify | set | To update a single record. | | PUT | Create | add | To create a new record. | | DELETE | Delete | remove | To delete a single record. | | POST | | | Universal method to get access to all console commands. | ### GET This method allows getting the list of all records or a single record from the specified menu encoded in the URL. For example, get all IP addresses (equivalent to the `ip/address/print` CLI command): ```sh $ curl -k -u admin: https://10.155.101.214/rest/ip/address [{".id":"*1","actual-interface":"ether2","address":"10.0.0.111/24","disabled":"false", "dynamic":"false","interface":"ether2","invalid":"false","network":"10.0.0.0"}, {".id":"*2","actual-interface":"ether3","address":"10.0.0.109/24","disabled":"true", "dynamic":"false","interface":"ether3","invalid":"false","network":"10.0.0.0"}] ``` Append an ID at the end of the URL to return a single record: ```sh $ curl -k -u admin: https://10.155.101.214/rest/ip/address/*1 {".id":"*1","actual-interface":"ether2","address":"10.0.0.111/24","disabled":"false", "dynamic":"false","interface":"ether2","invalid":"false","network":"10.0.0.0"} ``` If the table contains named parameters, you can use the name instead of the ID; for example, to get **ether1**: ```sh curl -k -u admin: https://10.155.101.214/rest/interface/ether1 ``` You can also filter the output; for example, return only dynamic addresses that belong to the 10.155.101.0 network: ```sh $ curl -k -u admin: "https://10.155.101.214/rest/ip/address?network=10.155.101.0&dynamic=true" [{".id":"*8","actual-interface":"sfp12","address":"10.155.101.214/24","disabled":"false", "dynamic":"true","interface":"sfp12","invalid":"false","network":"10.155.101.0"}] ``` Another example returns only addresses on the "dummy" interface and with the comment "test": ```sh $ curl -k -u admin: 'https://10.155.101.214/rest/ip/address?comment=test&interface=dummy' [{".id":"*3","actual-interface":"dummy","address":"192.168.99.2/24","comment":"test", "disabled":"false","dynamic":"false","interface":"dummy","invalid":"false","network":"192.168.99.0"}] ``` If you want to return only specific properties, you can use the `.proplist`, followed by the `=` character and a list of comma-separated properties. For example, to show only the address and if it's disabled: ```sh $ curl -k -u admin: https://10.155.101.214/rest/ip/address?.proplist=address,disabled [{"address":"10.0.0.111/24","disabled":"false"},{"address":"10.0.0.109/24","disabled":"true"}] ``` ### PATCH Use this method to update a single record. Set the body of the PATCH request to a JSON object containing the fields and their new values. For example, add a comment: ```sh $ curl -k -u admin: -X PATCH https://10.155.101.214/rest/ip/address/*3 \ --data '{"comment": "test"}' -H "content-type: application/json" {".id":"*3","actual-interface":"dummy","address":"192.168.99.2/24","comment":"test", "disabled":"false","dynamic":"false","interface":"dummy","invalid":"false","network":"192.168.99.0"} ``` In case of a successful update, the server returns the updated object with all its parameters. ### PUT This method creates a new record. Set the request body to a JSON object containing the parameters for the record. Only one record can be created per request. In case of success, the server returns the created object with all its parameters. For example, add an IP address to a dummy interface: ```sh $ curl -k -u admin: -X PUT https://10.155.101.214/rest/ip/address \ --data '{"address": "192.168.111.111", "interface": "dummy"}' -H "content-type: application/json" {".id":"*A","actual-interface":"dummy","address":"192.168.111.111/32","disabled":"false", "dynamic":"false","interface":"dummy","invalid":"false","network":"192.168.111.111"} ``` ### DELETE Use this method to delete a record with a specified ID. If the deletion succeeds, the server responds with an empty body. For example, calling the same delete twice causes the router to return a `404` error on the second attempt: ```sh $ curl -k -u admin: -X DELETE https://10.155.101.214/rest/ip/address/*9 $ curl -k -u admin: -X DELETE https://10.155.101.214/rest/ip/address/*9 {"error":404,"message":"Not Found"} ``` ### POST All [**API**](./api/index.md) features are available via `POST`. Encode the command word in the URL and pass optional parameters as fields in a JSON object. For example, to change the password of the active user, send: ``` POST https://router/rest/password {"old-password":"old","new-password":"N3w", "confirm-new-password":"N3w"} ``` A REST response has the same structure as an API response: - If the response contains `!re` sentences (records), the JSON reply will contain a list of objects. - If the `!done` sentence contains data, the JSON reply will contain an object with the data. - If there are no records or data in the `!done` sentence, the response will hold an empty list. There are two special keys: `.proplist` and `.query`, which are used with the `print` command word. Read more about APIs responses, prop lists, and queries in the [API](./api/index.md) documentation. #### Proplist Use the `.proplist` key to specify which properties to return. The value can be a single comma-separated string: ``` POST https://router/rest/interface/print {".proplist":"name,type"} ``` or a list of strings: ``` POST https://router/rest/interface/print {".proplist":["name","type"]} ``` For example, return address and interface properties from the `ip/address` menu: ```sh $ curl -k -u admin: -X POST https://10.155.101.214/rest/ip/address/print\ --data '{".proplist": ["address","interface"]}' -H "content-type: application/json" [{"address":"192.168.99.2/24","interface":"dummy"}, {"address":"172.16.5.1/24","interface":"sfpplus1"}, {"address":"172.16.6.1/24","interface":"sfp2"}, {"address":"172.16.7.1/24","interface":"sfp3"}, {"address":"10.155.101.214/24","interface":"sfp12"}, {"address":"192.168.111.111/32","interface":"dummy"}] ``` #### Query The `.query` key is used to create a query stack. The value is a list of query words. For example: ``` POST https://router/rest/interface/print {".query":["type=ether","type=vlan","#|!"]} ``` is equivalent to the **API** sentence: ``` /interface/print ?type=ether ?type=vlan ?#|! ``` Example to combine `query` and `proplist`, to return `.id`, `address`, and `interface` properties for all dynamic records and records with the network 192.168.111.111 ```sh $ curl -k -u admin: -X POST https://10.155.101.214/rest/ip/address/print \ --data '{".proplist": [".id","address","interface"], ".query": ["network=192.168.111.111","dynamic=true","#|"]}'\ -H "content-type: application/json" [{".id":"*8","address":"10.155.101.214/24","interface":"sfp12"}, {".id":"*A","address":"192.168.111.111/32","interface":"dummy"}] ``` #### Timeout If a command runs indefinitely, it will eventually time out and connection will be closed with an error. The current timeout interval is 60 seconds. To avoid timeout errors, add a parameter that would sufficiently limit the command execution time. For example, the ping command will exceed the timeout unless you add a count parameter to limit its execution: ```sh $ curl -k -u admin: -X POST https://10.155.101.214/rest/ping \ --data '{"address":"10.155.101.1"}' \ -H "content-type: application/json" {"detail":"Session closed","error":400,"message":"Bad Request"} $ curl -k -u admin: -X POST https://10.155.101.214/rest/ping \ --data '{"address":"10.155.101.1","count":"4"}' \ -H "content-type: application/json" [{"avg-rtt":"453us","host":"10.155.101.1","max-rtt":"453us","min-rtt":"453us","packet-loss":"0","received":"1","sent":"1","seq":"0","size":"56","time":"453us","ttl":"64"}, {"avg-rtt":"417us","host":"10.155.101.1","max-rtt":"453us","min-rtt":"382us","packet-loss":"0","received":"2","sent":"2","seq":"1","size":"56","time":"382us","ttl":"64"}, {"avg-rtt":"495us","host":"10.155.101.1","max-rtt":"650us","min-rtt":"382us","packet-loss":"0","received":"3","sent":"3","seq":"2","size":"56","time":"650us","ttl":"64"}, {"avg-rtt":"461us","host":"10.155.101.1","max-rtt":"650us","min-rtt":"359us","packet-loss":"0","received":"4","sent":"4","seq":"3","size":"56","time":"359us","ttl":"64"}] ``` For commands that accept a duration parameter, the REST timeout still applies. Even if a command is asked to run for an hour, it will terminate early and return an error. For example, a bandwidth test tool can be limited by providing run duration less than a timeout value: ```sh $ curl -k -u admin: -X POST 'https://10.155.101.214/rest/tool/bandwidth-test' \ --data '{"address":"10.155.101.1","duration":"3s"}' \ -H "content-type: application/json" [{".section":"0","connection-count":"20","direction":"receive","lost-packets":"0", "random-data":"false","rx-10-second-average":"0","rx-current":"0","rx-size":"1500", "rx-total-average":"0", "status":"connecting"}, {".section":"1","connection-count":"20","direction":"receive","duration":"1s", "lost-packets":"0","random-data":"false","rx-10-second-average":"0","rx-current":"0", "rx-size":"1500","rx-total-average":"0", "status":"running"}, {".section":"2","connection-count":"20","direction":"receive","duration":"2s", "lost-packets":"581175","random-data":"false","rx-10-second-average":"854372352", "rx-current":"854372352","rx-size":"1500","rx-total-average":"854372352", "status":"running"}, {".section":"3","connection-count":"20","direction":"receive","duration":"3s", "lost-packets":"9014","random-data":"false","rx-10-second-average":"891979008", "rx-current":"929585664","rx-size":"1500","rx-total-average":"891979008", "status":"done testing"}] ``` ## Errors An API call’s success or failure is indicated by the HTTP status code. On failure (400 or higher), the response body contains a JSON object with an error code, description, and optional details. For example, attempting to delete an interface returns ```text {"error":406,"message":"Not Acceptable","detail":"no such command or directory (remove)"} ``` ## Monitor The REST API does not support continuous commands such as `monitor`. Use the `monitor once` parameter to print a single result. ## Examples Below we have added a short collection of REST API calls you can make to your devices: Make a log entry: ```bash curl -k -u : -X POST https:///rest/execute --data '{"script":"/log/info test"}' -H "content-type: application/json" ``` Run a script: ```bash curl -k -u : https:///rest/system/script/run --data '{".id":"*1"}' -H "content-type: application/json" ``` LTE monitor once: ```bash curl -k -u : https:///rest/interface/lte/monitor -d '{"numbers":"0", "once":""}' -H "content-type: application/json" ``` Export device configuration: ```bash curl -k -u : https:///rest/export --data '{"compact":"","file":"test.rsc"}' -H "content-type: application/json" ``` Move a firewall entry (switch positions): ```bash curl -k -u : -X POST https:///rest/ip/firewall/nat/move --data '{".id":"*9","destination":"*C"}' -H "content-type: application/json" ``` LTE firmware update: ```bash curl -k -u : -X POST 'https:///rest/interface/lte/firmware-upgrade' --data '{"numbers":"lte2"}' -H "content-type: application/json" ``` Get OIDs from `/system/resource` menu: ```bash curl -k -u : -X POST https:///rest/system/resource/print --data '{"oid":""}' -H "content-type: application/json" ``` Use `/tool/fetch` to run a REST API POST from one RouterOS device to another RouterOS device: ```ros /tool fetch http-method=post url="https:///rest/execute" \ http-data="{\"script\":\"/log info fetchtest\"}" \ http-header-field="Content-Type:application/json" \ output=user user= password= ``` --- ## Scripting RouterOS includes a powerful scripting language for automating maintenance tasks. You create user-defined scripts and bind them to events. You can store scripts in the Script repository or write them directly in the CLI. Common triggers include the System Scheduler, Traffic Monitoring Tool, and Netwatch Tool events. If you are already familiar with scripting in RouterOS, you might want to see our [Tips & Tricks](./scripting-tips-and-tricks.md). ## Line structure The RouterOS script is divided into a number of command lines. Command lines are executed one by one until the end of the script or until a runtime error occurs. ### Command-line The RouterOS CLI uses the following command syntax: `[prefix] [path] command [uparam] [param=[value]] .. [param=[value]]` - [prefix] - `:` or `/` character indicates if following word is a [global command](#global-commands) or a path. Prefix is not required when called from root menu or from the menu relative to the called path/command. - [path] - relative path to the desired menu level. It may not be required. - command - one of the [commands](#commands) available at the specified menu level. - [uparam] - unnamed parameter, must be specified if the command requires it. - [params] - a sequence of named parameters followed by values (if a parameter requires a value). The end of the command line is represented by the token `;` or *NEWLINE*. A command enclosed in `()`, `[]` or `{}` does not require any end-of-command character. The end of the command is determined by the content of the whole script ```ros :if ( true ) do={ :put "lala" } ``` Each command line inside another command line starts and ends with square brackets `[]` [(command concatenation operator)](#other-operators). ```ros :put [/ip route get [find gateway=1.1.1.1]]; ``` Notice that the code above contains three command lines: - `:put` - `/ip route get` - `find gateway=1.1.1.1` Notice that menu specific `find` command does not require a full path because the path is derived from the parent command's path. A command line can be constructed from more than one physical line by following [line joining rules](#line-joining). ### Physical Line A physical line is a sequence of characters terminated by an end-of-line (**EOL**) sequence. Any of the standard platform line termination sequences can be used: - **Unix** – ASCII LF; - **Windows** – ASCII CR LF; - **mac** – ASCII CR; Standard C conventions for newline characters can be used ( `\n`, `\r\n` characters). ### Comments The following rules apply to a comment: - A comment starts with a hash character `#` and ends at the end of the physical line. - RouterOS does not support multiline comments. - If a `#` character appears inside the string it is not considered a comment. ```ros # this is a comment # continued comment in the next line :global a; # comment describing variable :global myStr "part of the string # is not a comment" ``` ### Line joining Two or more physical lines may be joined into logical lines using the **backslash** character (`\`). The following rules apply to using backslash as a line-joining tool: - A line ending in a backslash cannot carry a comment. - A backslash does not continue a comment. - A backslash does not continue a token except for string literals. - A backslash is illegal elsewhere on a line outside a string literal. ```ros :if ($a = true \ and $b=false) do={ :put "$a $b"; } :if ($a = true \ # bad comment (syntax error) and $b=false) do={ :put "$a $b"; } # comment \ continued is invalid (syntax error) ``` ### Whitespace between tokens Whitespace can be used to separate tokens. Whitespace is necessary between two tokens only if their concatenation could be interpreted as a different token. Example: ```ros {   :local a true; :local b false; # whitespace is not required :put (a&&b); # whitespace is required   :put (a and b); } ``` Whitespace characters are not allowed: - between `=`. - between `from=`, `to=`, `step=`, `in=`, `do=`, `else=`. Example: ```ros #incorrect: :for i from = 1 to = 2 do = { :put $i } #correct syntax: :for i from=1 to=2 do={ :put $i } :for i from= 1 to= 2 do={ :put $i } #incorrect /ip route add gateway = 3.3.3.3 #correct /ip route add gateway=3.3.3.3 ``` ### Scopes Variables can be used only in certain regions of the script called scopes. These regions determine the visibility of the variable. A variable declared within a block is accessible only within that block and its nested blocks, and only after the declaration point. There are two types of scopes — **global** and **local**. #### Global scope Global scope or root scope is the default scope of the script. It is created automatically and cannot be turned off. A global variable set by another script can be accessed by declaring it without assigning a value. For example, first script sets the myVar value to 3: ```ros :global myVar 3 ``` To access this variable from another script: ```ros :global myVar :put "myVar=$myVar" ``` Output: ``` myVar=3 ``` #### Local scope You can define groups to limit variable access; these are called local scopes. Each local scope is enclosed in curly braces (`{}`). ```ros {   :local a 3; {   :local b 4;   :put ($a+$b); } #line below will show variable b in light red color since it is not defined in this scope   :put ($a+$b); } ``` Variable `b` is declared in a local scope and is not accessible after the closing curly brace. Each line written in the CLI is treated as a local scope. For example, the defined local variable is not visible in the next command line and generates a syntax error ```ros [admin@MikroTik] > :local myVar a; [admin@MikroTik] > :put $myVar syntax error (line 1 column 7) ``` :::danger Do not define a **global** variable inside a **local** scope. ::: Even if variable can be defined as global, it will be available only from its scope unless it is not referenced to be visible outside of the scope. ```ros {   :local a 3; {   :global b 4; }   :put ($a+$b); } ``` The code outputs 3 because `b` is not visible outside the scope. The following code fixes the problem and outputs 7 as intended: ```ros {   :local a 3; {   :global b 4; } :global b;   :put ($a+$b); } ``` ## Keywords The following words are keywords and cannot be used as variable and function names: ``` and or in ``` ## Delimiters The following tokens serve as delimiters in the grammar: ``` () [] {}  :  ; $ / ``` ## Data types RouterOS scripting language has the following data types: | Type | Description | |:--|:--| | **num (number)** | 64bit signed integer, possible hexadecimal input; | | **bool (boolean)** | values can be `true` or `false`. | | **str (string)** | character sequence. | | **ip** | IP address. | | **ip-prefix** | IP prefix. | | **ip6** | IPv6 address. | | **ip6-prefix** | IPv6 prefix. | | **id (internal ID)** | Hexadecimal value prefixed by `*` character. Each menu item has an assigned unique number - internal ID. | | **time** | Date and time value. | | **array** | Sequence of values organized in an array. | | **nil** | Default variable type if no value is assigned. | ## Constant Escape Sequences Following escape sequences can be used to define certain special characters within a string: | | | |:--|:--| | **\"** | Insert double quote. | | **\\** | Insert backslash. | | **\n** | Insert newline. | | **\r** | Insert carriage return. | | **\t** | Insert horizontal tab. | | **\$** | Output $ character. Otherwise, $ is used to link the variable. | | **\\_** | Space. | | **\a** | BEL (0x07). | | **\b** | Backspace (0x08). | | **\f** | Form feed (0x0C). | | **\v** | Insert vertical tab. | | **\xx** | A print character from hex value. Hex numbers should use capital letters. | For example: ```ros :put "\48\45\4C\4C\4F\r\nThis\r\nis\r\na\r\ntest"; ``` will output: ``` HELLO This is a test ``` ## Operators ### Arithmetic Operators Common arithmetic operators are supported in the RouterOS scripting language: | Operator | Description | Example | |:--|:--|:--| | **`+`** | binary addition | `:put (3+4);` | | **`-`** | binary subtraction | `:put (1-6);` | | **`*`** | binary multiplication | `:put (4*5);` | | **`/`** | binary division | `:put (10 / 2); :put ((10)/2)` | | **`%`** | modulo operation | `:put (5 % 3);` | | **`-`** | unary negation | `{ :local a 1; :put (-a); }` | Note that for the division to work, you have to use braces or spaces around the dividend so it is not mistaken as an IP address. ### Relational Operators | Operator | Description | Example | |:--|:--|:--| | **`<`** | less | `:put (3<4);` | | **`>`** | greater | `:put (3>4);` | | **`=`** | equal | `:put (2=2);` | | **`<=`** | less or equal | | | **`>=`** | greater or equal | | | **`!=`** | not equal | | To negate an expression, you can use `=false`. For example, to print all interfaces that are not "ethernet", you can use expression negation like this: ```ros /interface/print where (name~"ether")=false ``` Or to do the opposite, you can use `=true`: ```ros /interface/print where (name~"ether")=true ``` ### Logical Operators | Operator | Description | Example | |:--|:--|:--| | **`!`** | logical NOT | `:put (!true);` | | **`&&`, `and`** | logical AND | `:put (true&&true)` | | **`\|\|`, `or`** | logical OR | `:put (true\|\|false);` | | **`in`** | | `:put (1.1.1.1/32 in 1.0.0.0/8);` | ### Bitwise Operators Bitwise operators are working only on IP, and IPv6 address [data types](#data-types). | Operator | Description | Example | |:--|:--|:--| | **`~`** | Bit inversion. | `:put (~0.0.0.0)` `:put (~::ffff)` | | **`\|`** | Bitwise OR performs logical OR operation on each pair of corresponding bits. In each pair the result is “1” if one of the bits or both bits is “1”, otherwise the result is “0”. | `:put (192.168.88.0\|0.0.0.255)` `:put (2001::1\|::ffff)` | | **`^`** | Bitwise XOR is the same as OR, but the result in each position is “1” if two bits are not equal, and “0” if the bits are equal. | `:put (1.1.1.1^255.255.0.0)` `:put (2001::ffff:1^::ffff:0)` | | **`&`** | Bitwise AND result is “1” if the first and second bit is “1”. Otherwise, the result is “0”. | `:put (192.168.88.77&255.255.255.0)` `:put (2001::1111&ffff::)` | | **`<<`** | Left shift by a given amount of bits, not supported for IPv6 address data type. | `:put (192.168.88.77<<8)` | | **`>>`** | Right shift by a given amount of bits, not supported for IPv6 address data type. | `:put (192.168.88.77>>24)` | For example, calculate a subnet address from a given IP and CIDR netmask with the `&` operator: ```ros { :local IP 192.168.88.77; :local CIDRnetmask 255.255.255.0; :put ($IP&$CIDRnetmask); } ``` Get the last 8 bits from the given IP addresses: ```ros :put (192.168.88.77&0.0.0.255); ``` Use the `|` operator and an inverted CIDR mask to calculate the broadcast address: ```ros { :local IP 192.168.88.77; :local Network 192.168.88.0; :local CIDRnetmask 255.255.255.0; :local InvertedCIDR (~$CIDRnetmask); :put ($Network|$InvertedCIDR) } ``` ### Concatenation Operators | Operator | Description | Example | |:--|:--|:--| | **`.`** | Concatenates two strings.| `:put ("concatenate" . " " . "string");` | | **`,`** | Concatenates two arrays or adds an element to the array. | `:put ({1;2;3} , 5 );` | It is possible to add variable values directly to strings without a concatenation operator: ```ros :global myVar "world"; # value can be added with concatenation operator :put ("Hello " . $myVar); # or without operator :put "Hello $myVar"; ``` Using `$[]` and `$()` you can execute expressions and insert the resulting value into strings: ```ros :local a 5; :local b 6; :put " 5x6 = $($a * $b)"; :put " We have $[ :len [/ip route find] ] routes"; ``` ### Other Operators | Operator | Description | Example | |:--|:--|:--| | **`[]`** | Command substitution can contain only a single command line` | `:put [ :len "my test string"; ];` | | **`()`** | Subexpression or grouping operator. | `:put ( "value is " . (4+5));` | | **`$`** | Substitution operator. | `:global a 5; :put $a;` | | **`~`** | The binary operator that matches value against POSIX extended regular expression. | Print all routes whose gateway ends with 202: `/ip/route/print where gateway~"^[0-9 \\.]*202\$"` | | **`->`** | Get an array element by key. | `[admin@x86] >:global aaa {a=1;b=2}``[admin@x86] > :put ($aaa->"a")``1``[admin@x86] > :put ($aaa->"b")``2` | ## Variables The scripting language has two types of variables: - **global** - Accessible from all scripts created by the current user, defined by [`global`](#global-scope) keyword. - **local** - Accessible only within the current [scope](#local-scope), defined by `local` keyword. Variables may be undefined. When that happens, the parser looks for built-in variables provided by the application. For example, the DHCP `lease-script` supplies several built-in variables: ```ros /system script add name=myLeaseScript policy=\ ftp,reboot,read,write,policy,test,winbox,password,sniff,sensitive,api \ source=":log info \$leaseActIP\r\ \n:log info \$leaseActMAC\r\ \n:log info \$leaseServerName\r\ \n:log info \$leaseBound" /ip dhcp-server set myServer lease-script=myLeaseScript ``` Except for built-in RouterOS variables, every variable must be declared before use with the `local` or `global` keyword. Using an undeclared variable results in a compilation error. For example: ```ros # following code will result in compilation error, because myVar is used without declaration :set myVar "my value"; :put $myVar ``` Correct code: ```ros :local myVar; :set myVar "my value"; :put $myVar; ``` Valid characters in variable names are letters and digits. If a variable name contains any character other than letters or digits (including operators), enclose it in double quotes (`""`). Example: ```ros #valid variable name :local myVar; #invalid variable name :local my-var; #valid because double quoted :global "my-var"; ``` If a variable is initially defined without a value, the [variable data type](#data-types) is set to ***nil***; otherwise, the scripting engine determines the data type automatically. Sometimes conversion from one data type to another is required. It can be achieved using [data conversion commands](#global-commands). Example: ```ros #convert string to array :local myStr "1,2,3,4,5"; :put [:typeof $myStr]; :local myArr [:toarray $myStr]; :put [:typeof $myArr] ``` Variable names are case-sensitive. ```ros :local myVar "hello" # following line will generate error, because variable myVAr is not defined :put $myVAr # correct code :put $myVar ``` The `set` command without a value undefines a variable: ```ros #remove variable from environment :global myVar "myValue" :set myVar; ``` ### Reserved variable names All built-in RouterOS properties are reserved variables. Variables defined with the same names as RouterOS built-in properties can cause errors. To avoid this, choose different names. For example, the following script will not work: ```ros { :local type "ether1"; /interface print where name=$type; } ``` But will work with different defined variables: ```ros { :local customname "ether1"; /interface print where name=$customname; } ``` ## Commands ### Global commands Every global command should start with the **`:`** token; otherwise it is treated as a variable. | Command | Syntax | Description | Example | |:--|:--|:--|:--| | **/** | | Go to the root menu. | | | **..** | | Go back by one menu level. | | | **?** | | List all available menu commands and brief descriptions. | | | **global** | `:global []` | Define a global variable. | `:global myVar "something"; :put $myVar;` | | **local** | `:local []` | Define the local variable. | `{ :local myLocalVar "I am local"; :put $myLocalVar; }` | | **beep** | `:beep frequency=[num] length=[num]` | Beep the built-in speaker. | | | **convert** | `:convert from=[arg] to=[arg] transform=[arg]` | Converts specified value from one format to another. By default uses an automatically parsed value, if the `from` format is not specified (for example, "001" becomes "1", "10.1" becomes "10.0.0.1", etc.). **`from`** - Specifies the format of the value: *base32, base64, bit-array-lsb, bit-array-msb, byte-array, hex, num, raw, url*. **`to`** - Specifies the format of the output value: *base32, base64, bit-array-lsb, bit-array-msb, byte-array, hex, num, raw, url*. **`transform`** - Specifies how to transform values: *lc (transforms value to be in lowercases), uc (uppercases), lcfirst (first value to lowercase), ucfirst (first value to uppercase), crlf, ed25519-private-to-x25519-private, none, rot 13, x25519-private-to-x25519-public, ed25519-private-to-ed25519-public, ed25519-public-to-x25519-public, md5, reverse (reverses text), sha512.* | `:put [:convert 001 to=hex ]` `31` `:put [:convert [/ip dhcp-client/option/get hostname raw-value] from=hex to=raw ]` `MikroTik` `:put [:convert transform=lc "AAA"]` `aaa` | | **delay** | `:delay