// to display images directly on GitHub
ifdef::env-github[]
:encoding: UTF-8
:lang: en
:doctype: book
:toc: left
:imagesdir: ../images
endif::[]

////

    This file is part of the PacketFence project.

    See PacketFence_Developers_Guide.asciidoc
    for authors, copyright and license information.

////

//== Creating a new Switch via a Template

=== Using web admin

You can directly create or edit switch templates in `_Configuration -> Integration -> Switch Templates_` menu.

=== Using CLI

To create a new Switch Template you must create a template file in the [filename]`/usr/local/pf/lib/pf/Switch` directory.
The file must have the following pattern [filename]`/usr/local/pf/lib/pf/Switch/_<Vendor>_/_<SwitchName>_.def`.

For example to create a template for the vendor `Cyberdyne` and switch `Switchinator 800`.
The file name is [filename]`/usr/local/pf/lib/pf/Switch/Cyberdyne/Switchinator800.def`
The file name must must only consist of alphanumeric characters and under scores and must begin with a letter.

Once you have completed your switch template, you will need to perform the following commands so it can be used:

[source,bash]
----
/usr/local/pf/addons/dev-helpers/bin/generator-template-switches-defaults.pl
/usr/local/pf/bin/pfcmd configreload hard
/usr/local/pf/bin/pfcmd service pf restart
----

The file consist of parameter names and their values. There is no sections but RADIUS scope parameters act like this.

No scopes are inherited from a base switch template, you need to define each scope you want to use.

You can find a full working example
<<_full_working_example,below>>. Other examples are available in
[filename]`/usr/local/pf/lib/pf/Switch/` folder.

=== Required Parameters

* description      - The description of the switch.
* radiusDisconnect - The RADIUS disconnect methods to use. Must be one of the following values coa|disconnect|coaOrDisconnect .

=== RADIUS scope Parameters

* acceptVlan - Attributes for accept vlan scope
* acceptRole - Attributes for accept role scope.
* reject     - Attributes for rejection scope.
* disconnect - Attributes for disconnect scope (required if radiusDisconnect is 'disconnect' or 'coaOrDisconnect')
* coa        - Attributes for CoA scope (required if radiusDisconnect is 'coa' or 'coaOrDisconnect')
* voip       - Attributes for VOIP scope (If VOIP is enabled)
* bounce     - Attributes for bounce scope

=== Additional parameters

* snmpDisconnect - If SNMP protocol should be use to disconnect (values: `enabled` or `disabled`)

=== Comments

The line of a comment must begin with a '#'
For example:
....
# This is a comment
....

=== Defining RADIUS Attributes

....
scopeName = <<EOT
Attribute-Name1 = value1
Attribute-Name2 = value2
EOT
....

=== Dynamic RADIUS Attribute Value Syntax

Some values depends on the context of the current request.
So here is mini templating language to format values.

* Text replacement: `$name`
* Embedded text replacement:  `start-${name}-end`
* Functions: `${f1("",$var, f2())}`

==== Available variables for RADIUS scope

* acceptRole - (Same as acceptVlan)

* reject - (Same as acceptVlan)

* acceptVlan
** autoreg
** connection_sub_type
** connection_type
** eap_type
** fingerbank_info.device_name
** fingerbank_info.device_fq
** fingerbank_info.device_hierarchy_names
** fingerbank_info.device_hierarchy_ids
** fingerbank_info.score
** fingerbank_info.version
** fingerbank_info.mobile
** ifDesc
** ifIndex
** isPhone
** last_accounting.acctsessionid
** last_accounting.username
** locationlog.connection_sub_type
** locationlog.connection_type
** locationlog.dot1x_username
** locationlog.end_time
** locationlog.ifDesc
** locationlog.mac
** locationlog.port
** locationlog.realm
** locationlog.role
** locationlog.session_id
** locationlog.ssid
** locationlog.start_time
** locationlog.stripped_user_name
** locationlog.switch
** locationlog.switch_ip
** locationlog.switch_ip_int
** locationlog.switch_mac
** locationlog.vlan
** locationlog.voip
** mac
** nas_port_id
** nas_port_type
** node_info.autoreg
** node_info.status
** node_info.bypass_vlan
** node_info.bandwidth_balance
** node_info.regdate
** node_info.bypass_role
** node_info.device_class
** node_info.device_type
** node_info.device_version
** node_info.device_score
** node_info.pid
** node_info.machine_account
** node_info.category
** node_info.mac
** node_info.last_arp
** node_info.last_dhcp
** node_info.user_agent
** node_info.computername
** node_info.dhcp_fingerprint
** node_info.detect_date
** node_info.voip
** node_info.notes
** node_info.time_balance
** node_info.sessionid
** node_info.dhcp_vendor
** profile._access_registration_when_registered
** profile._always_use_redirecturl
** profile._autoregister
** profile._block_interval
** profile._description
** profile._dot1x_recompute_role_from_portal
** profile._dot1x_unset_on_unmatch
** profile._dpsk
** profile._locale
** profile._login_attempt_limit
** profile._logo
** profile._name
** profile._network_logoff
** profile._network_logoff_popup
** profile._preregistration
** profile._redirecturl
** profile._reuse_dot1x_credentials
** profile._root_module
** profile._self_service
** profile._sms_pin_retry_limit
** profile._sms_request_limit
** profile._status
** profile._unreg_on_acct_stop
** profile._vlan_pool_technique
** radius_request.<Radius Attribute Name>
** realm
** session_id
** source_ip
** ssid
** stripped_user_name
** switch._ExternalPortalEnforcement
** switch._RoleMap
** switch._VpnMap
** switch._SNMPAuthPasswordRead
** switch._SNMPAuthPasswordTrap
** switch._SNMPAuthPasswordWrite
** switch._SNMPAuthProtocolRead
** switch._SNMPAuthProtocolTrap
** switch._SNMPAuthProtocolWrite
** switch._SNMPCommunityRead
** switch._SNMPCommunityTrap
** switch._SNMPCommunityWrite
** switch._SNMPEngineID
** switch._SNMPPrivPasswordRead
** switch._SNMPPrivPasswordTrap
** switch._SNMPPrivPasswordWrite
** switch._SNMPPrivProtocolRead
** switch._SNMPPrivProtocolTrap
** switch._SNMPPrivProtocolWrite
** switch._SNMPUserNameRead
** switch._SNMPUserNameTrap
** switch._SNMPUserNameWrite
** switch._SNMPVersion
** switch._SNMPVersionTrap
** switch._TenantId
** switch._UrlMap
** switch._VlanMap
** switch._VoIPEnabled
** switch._cliEnablePwd
** switch._cliPwd
** switch._cliTransport
** switch._cliUser
** switch._coaPort
** switch._controllerIp
** switch._deauthMethod
** switch._disconnectPort
** switch._id
** switch._inlineTrigger
** switch._ip
** switch._macSearchesMaxNb
** switch._macSearchesSleepInterval
** switch._mode
** switch._roles
** switch._switchIp
** switch._switchMac
** switch._uplink
** switch._useCoA
** switch._vlans
** switch._wsPwd
** switch._wsTransport
** switch._wsUser
** switch_ip
** switch_mac
** time
** user_name
** user_role
** vlan
** wasInline

* coa
** last_accounting.acctsessionid
** last_accounting.username
** mac
** locationlog.connection_sub_type
** locationlog.connection_type
** locationlog.dot1x_username
** locationlog.end_time
** locationlog.ifDesc
** locationlog.mac
** locationlog.port
** locationlog.realm
** locationlog.role
** locationlog.session_id
** locationlog.ssid
** locationlog.start_time
** locationlog.stripped_user_name
** locationlog.switch
** locationlog.switch_ip
** locationlog.switch_ip_int
** locationlog.switch_mac
** locationlog.vlan
** locationlog.voip
** role
** time

* disconnect
** disconnectIp
** last_accounting.acctsessionid
** last_accounting.username
** locationlog.connection_sub_type
** locationlog.connection_type
** locationlog.dot1x_username
** locationlog.end_time
** locationlog.ifDesc
** locationlog.mac
** locationlog.port
** locationlog.realm
** locationlog.role
** locationlog.session_id
** locationlog.ssid
** locationlog.start_time
** locationlog.stripped_user_name
** locationlog.switch
** locationlog.switch_ip
** locationlog.switch_ip_int
** locationlog.switch_mac
** locationlog.vlan
** locationlog.voip
** mac
** time

* voip
** switch._ExternalPortalEnforcement
** switch._RoleMap
** switch._VpnMap
** switch._SNMPAuthPasswordRead
** switch._SNMPAuthPasswordTrap
** switch._SNMPAuthPasswordWrite
** switch._SNMPAuthProtocolRead
** switch._SNMPAuthProtocolTrap
** switch._SNMPAuthProtocolWrite
** switch._SNMPCommunityRead
** switch._SNMPCommunityTrap
** switch._SNMPCommunityWrite
** switch._SNMPEngineID
** switch._SNMPPrivPasswordRead
** switch._SNMPPrivPasswordTrap
** switch._SNMPPrivPasswordWrite
** switch._SNMPPrivProtocolRead
** switch._SNMPPrivProtocolTrap
** switch._SNMPPrivProtocolWrite
** switch._SNMPUserNameRead
** switch._SNMPUserNameTrap
** switch._SNMPUserNameWrite
** switch._SNMPVersion
** switch._SNMPVersionTrap
** switch._TenantId
** switch._UrlMap
** switch._VlanMap
** switch._VoIPEnabled
** switch._cliEnablePwd
** switch._cliPwd
** switch._cliTransport
** switch._cliUser
** switch._coaPort
** switch._controllerIp
** switch._deauthMethod
** switch._disconnectPort
** switch._id
** switch._inlineTrigger
** switch._ip
** switch._macSearchesMaxNb
** switch._macSearchesSleepInterval
** switch._mode
** switch._roles
** switch._switchIp
** switch._switchMac
** switch._uplink
** switch._useCoA
** switch._vlans
** switch._wsPwd
** switch._wsTransport
** switch._wsUser
** time
** vlan

* bounce
** disconnectIp
** ifIndex
** last_accounting.acctsessionid
** last_accounting.username
** locationlog.connection_sub_type
** locationlog.connection_type
** locationlog.dot1x_username
** locationlog.end_time
** locationlog.ifDesc
** locationlog.mac
** locationlog.port
** locationlog.realm
** locationlog.role
** locationlog.session_id
** locationlog.ssid
** locationlog.start_time
** locationlog.stripped_user_name
** locationlog.switch
** locationlog.switch_ip
** locationlog.switch_ip_int
** locationlog.switch_mac
** locationlog.vlan
** locationlog.voip
** mac
** switch._cliEnablePwd
** switch._cliPwd
** switch._cliTransport
** switch._cliUser
** switch._coaPort
** switch._controllerIp
** switch._deauthMethod
** switch._disconnectPort
** switch._ExternalPortalEnforcement
** switch._id
** switch._inlineTrigger
** switch._ip
** switch._macSearchesMaxNb
** switch._macSearchesSleepInterval
** switch._mode
** switch._RoleMap
** switch._VpnMap
** switch._roles
** switch._SNMPAuthPasswordRead
** switch._SNMPAuthPasswordTrap
** switch._SNMPAuthPasswordWrite
** switch._SNMPAuthProtocolRead
** switch._SNMPAuthProtocolTrap
** switch._SNMPAuthProtocolWrite
** switch._SNMPCommunityRead
** switch._SNMPCommunityTrap
** switch._SNMPCommunityWrite
** switch._SNMPEngineID
** switch._SNMPPrivPasswordRead
** switch._SNMPPrivPasswordTrap
** switch._SNMPPrivPasswordWrite
** switch._SNMPPrivProtocolRead
** switch._SNMPPrivProtocolTrap
** switch._SNMPPrivProtocolWrite
** switch._SNMPUserNameRead
** switch._SNMPUserNameTrap
** switch._SNMPUserNameWrite
** switch._SNMPVersion
** switch._SNMPVersionTrap
** switch._switchIp
** switch._switchMac
** switch._TenantId
** switch._uplink
** switch._UrlMap
** switch._useCoA
** switch._VlanMap
** switch._vlans
** switch._VoIPEnabled
** switch._wsPwd
** switch._wsTransport
** switch._wsUser
** time

==== Available functions

* `macToEUI48($mac)`            - format a mac to AA-BB-CC-DD-FF-EE format
* `uc($string)`                 - uppercases a string
* `lc($string)`                 - lowercases a string
* `log($string)`                - log a message to the log
* `substr($str, $offset, $len)` - Extracts a substring from a string
* `split($sep, $str)`           - Split a string by a seperator.
* `join($sep, $a, $b, ..)`      - Join a list of string with a seperator.
* `replace($str, $old, $new)`   - Replace the old string with a new string.

==== Full Working Example

....
description = The Switchinator 800
radiusDisconnect = disconnect

acceptVlan = <<EOT
Tunnel-Medium-Type = 6
Tunnel-Type = 13
Tunnel-Private-Group-Id = $vlan
EOT

acceptRole = <<EOT
Filter-Id = $role
EOT

reject = <<EOT
Reply-Message = Hasta la vista, baby.
EOT

disconnect = <<EOT
Calling-Station-Id= ${macToEUI48($mac)}
NAS-IP-Address = $disconnectIp
EOT

coa = <<EOT
Calling-Station-Id= ${macToEUI48($mac)}
NAS-IP-Address = $disconnectIp
Filter-Id = $role
EOT

bounce= <<EOT
Cisco-AVPair = subscriber:command=bounce-host-port
Acct-Session-Id = $last_accounting.acctsessionid
EOT
....
