smf_context

package
v0.0.0-...-3a7200f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2022 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Index

Constants

View Source
const (
	OperationCodeCreateNewQoSRule                                   uint8 = 1
	OperationCodeDeleteExistingQoSRule                              uint8 = 2
	OperationCodeModifyExistingQoSRuleAndAddPacketFilters           uint8 = 3
	OperationCodeModifyExistingQoSRuleAndReplaceAllPacketFilters    uint8 = 4
	OperationCodeModifyExistingQoSRuleAndDeletePacketFilters        uint8 = 5
	OperationCodeModifyExistingQoSRuleWithoutModifyingPacketFilters uint8 = 6
)
View Source
const (
	PacketFilterDirectionDownlink      uint8 = 1
	PacketFilterDirectionUplink        uint8 = 2
	PacketFilterDirectionBidirectional uint8 = 3
)
View Source
const (
	PacketFilterComponentTypeMatchAll                       uint8 = 0x01
	PacketFilterComponentTypeIPv4RemoteAddress              uint8 = 0x10
	PacketFilterComponentTypeIPv4LocalAddress               uint8 = 0x11
	PacketFilterComponentTypeIPv6RemoteAddress              uint8 = 0x21
	PacketFilterComponentTypeIPv6LocalAddress               uint8 = 0x23
	PacketFilterComponentTypeProtocolIdentifierOrNextHeader uint8 = 0x30
	PacketFilterComponentTypeSingleLocalPort                uint8 = 0x40
	PacketFilterComponentTypeLocalPortRange                 uint8 = 0x41
	PacketFilterComponentTypeSingleRemotePort               uint8 = 0x50
	PacketFilterComponentTypeRemotePortRange                uint8 = 0x51
	PacketFilterComponentTypeSecurityParameterIndex         uint8 = 0x60
	PacketFilterComponentTypeTypeOfServiceOrTrafficClass    uint8 = 0x70
	PacketFilterComponentTypeFlowLabel                      uint8 = 0x80
	PacketFilterComponentTypeDestinationMACAddress          uint8 = 0x81
	PacketFilterComponentTypeSourceMACAddress               uint8 = 0x82
	PacketFilterComponentType8021Q_CTAG_VID                 uint8 = 0x83
	PacketFilterComponentType8021Q_STAG_VID                 uint8 = 0x84
	PacketFilterComponentType8021Q_CTAG_PCPOrDEI            uint8 = 0x85
	PacketFilterComponentType8021Q_STAG_PCPOrDEI            uint8 = 0x86
	PacketFilterComponentTypeEthertype                      uint8 = 0x87
)

TS 24.501 Table 9.11.4.13.1

Variables

View Source
var NFServices *[]models.NfService
View Source
var NfServiceVersion *[]models.NfServiceVersion
View Source
var SmfInfo *models.SmfInfo

Functions

func AllocUEIP

func AllocUEIP() net.IP

func AllocateUPFID

func AllocateUPFID()

func BuildGSMPDUSessionEstablishmentAccept

func BuildGSMPDUSessionEstablishmentAccept(smContext *SMContext) ([]byte, error)

func BuildGSMPDUSessionModificationCommand

func BuildGSMPDUSessionModificationCommand(smContext *SMContext) ([]byte, error)

func BuildGSMPDUSessionReleaseCommand

func BuildGSMPDUSessionReleaseCommand(smContext *SMContext) ([]byte, error)

func BuildGSMPDUSessionReleaseReject

func BuildGSMPDUSessionReleaseReject(smContext *SMContext) ([]byte, error)

func BuildHandoverCommandTransfer

func BuildHandoverCommandTransfer(ctx *SMContext) (buf []byte, err error)

func BuildPDUSessionResourceReleaseCommandTransfer

func BuildPDUSessionResourceReleaseCommandTransfer(ctx *SMContext) (buf []byte, err error)

func BuildPDUSessionResourceSetupRequestTransfer

func BuildPDUSessionResourceSetupRequestTransfer(ctx *SMContext) (buf []byte, err error)

func BuildPathSwitchRequestAcknowledgeTransfer

func BuildPathSwitchRequestAcknowledgeTransfer(ctx *SMContext) (buf []byte, err error)

TS 38.413 9.3.4.9

func BuildPathSwitchRequestUnsuccessfulTransfer

func BuildPathSwitchRequestUnsuccessfulTransfer(causePresent int, causeValue aper.Enumerated) (buf []byte, err error)

func CheckUEHasPreConfig

func CheckUEHasPreConfig(SUPI string) (exist bool)

func GetSMContextCount

func GetSMContextCount() uint64

func HandleHandoverRequestAcknowledgeTransfer

func HandleHandoverRequestAcknowledgeTransfer(b []byte, ctx *SMContext) (err error)

func HandleHandoverRequiredTransfer

func HandleHandoverRequiredTransfer(b []byte, ctx *SMContext) (err error)

func HandlePDUSessionResourceSetupResponseTransfer

func HandlePDUSessionResourceSetupResponseTransfer(b []byte, ctx *SMContext) (err error)

func HandlePathSwitchRequestSetupFailedTransfer

func HandlePathSwitchRequestSetupFailedTransfer(b []byte, ctx *SMContext) (err error)

func HandlePathSwitchRequestTransfer

func HandlePathSwitchRequestTransfer(b []byte, ctx *SMContext) (err error)

func InitSMFUERouting

func InitSMFUERouting(routingConfig *factory.RoutingConfig)

func InitSmfContext

func InitSmfContext(config *factory.Config)

func RemoveSMContext

func RemoveSMContext(ref string)

func RemoveUPFNodeByNodeId

func RemoveUPFNodeByNodeId(nodeID pfcpType.NodeID)

func ResolveRef

func ResolveRef(identifier string, pduSessID int32) (ref string, err error)

func SetupNFProfile

func SetupNFProfile(config *factory.Config)

func SetupSMFContext

func SetupSMFContext(config *factory.Config) error

Types

type BAR

type BAR struct {
	BARID uint8

	DownlinkDataNotificationDelay  pfcpType.DownlinkDataNotificationDelay
	SuggestedBufferingPacketsCount pfcpType.SuggestedBufferingPacketsCount

	State RuleState
}

Buffering Action Rule 7.5.2.6-1

type BPManager

type BPManager struct {
	BPStatus   BPStatus
	ANUPFState map[*DataPathNode]bool
	PSAState   map[*DataPathNode]PDUSessionAnchorState

	//Need these variable conducting Add addtional PSA (TS23.502 4.3.5.4)
	//There value will change from time to time
	PSA1Path         []*UPNode
	PSA2Path         []*UPNode
	ULCL             *UPNode
	ULCLIdx          int
	ULCLDataPathNode *DataPathNode
	ULCLState        ULCLState
}

func NewBPManager

func NewBPManager(supi string) (bpManager *BPManager)

func (*BPManager) FindULCL

func (bpMGR *BPManager) FindULCL(smContext *SMContext) (err error)

func (*BPManager) SelectPSA2

func (bpMGR *BPManager) SelectPSA2()

func (*BPManager) SetPSAStatus

func (bpMGR *BPManager) SetPSAStatus(psa_path []*UPNode)

type BPStatus

type BPStatus int
const (
	UnInitialized BPStatus = iota
	HasSendPFCPMsg
	InitializedSuccess
	InitializedFail
)
type DataPathDownLink struct {
	To *DataPathNode

	// Filter Rules
	DestinationIP   string
	DestinationPort string

	// related context
	UpLinkPDR *PDR
}
func NewDataPathDownLink() (link *DataPathDownLink)

type DataPathNode

type DataPathNode struct {
	UPF          *UPF
	DataPathToAN *DataPathDownLink
	DataPathToDN map[string]*DataPathUpLink //uuid to DataPathLink

	UpLinkTunnel   *GTPTunnel
	DownLinkTunnel *GTPTunnel

	InUse                bool
	IsBranchingPoint     bool
	DLDataPathLinkForPSA *DataPathUpLink
	BPUpLinkPDRs         map[string]*DataPathDownLink // uuid to UpLink

	HaveSession bool
}

func GenerateDataPath

func GenerateDataPath(upPath UPPath, smContext *SMContext) (root *DataPathNode)

func NewDataPathNode

func NewDataPathNode() (node *DataPathNode)

func NewUEDataPathNode

func NewUEDataPathNode(name string) (node *DataPathNode, err error)

func (*DataPathNode) AddChild

func (node *DataPathNode) AddChild(child *DataPathNode) (err error)

func (*DataPathNode) AddDestinationOfChild

func (node *DataPathNode) AddDestinationOfChild(child *DataPathNode, Dest *DataPathUpLink) (err error)

func (*DataPathNode) AddParent

func (node *DataPathNode) AddParent(parent *DataPathNode) (err error)

func (*DataPathNode) EnableUserPlanePath

func (root *DataPathNode) EnableUserPlanePath(path []*UPNode) (err error)

func (*DataPathNode) GetNodeIP

func (node *DataPathNode) GetNodeIP() (ip string)

func (*DataPathNode) GetParent

func (node *DataPathNode) GetParent() (parent *DataPathNode)

func (*DataPathNode) GetUPFID

func (node *DataPathNode) GetUPFID() (id string, err error)
func (node *DataPathNode) GetUpLink() (link *DataPathDownLink)

func (*DataPathNode) GetUpLinkFAR

func (node *DataPathNode) GetUpLinkFAR() (far *FAR)

func (*DataPathNode) GetUpLinkPDR

func (node *DataPathNode) GetUpLinkPDR() (pdr *PDR)

func (*DataPathNode) IsANUPF

func (node *DataPathNode) IsANUPF() bool

func (*DataPathNode) IsAnchorUPF

func (node *DataPathNode) IsAnchorUPF() bool

func (*DataPathNode) PathToString

func (node *DataPathNode) PathToString() string

func (*DataPathNode) SetDownLinkSrcNode

func (node *DataPathNode) SetDownLinkSrcNode(nextDownLinkNode *DataPathNode) (err error)

func (*DataPathNode) SetUpLinkSrcNode

func (node *DataPathNode) SetUpLinkSrcNode(nextUpLinkNode *DataPathNode) (err error)
type DataPathUpLink struct {
	To *DataPathNode

	// Filter Rules
	DestinationIP   string
	DestinationPort string

	// related context
	DownLinkPDR *PDR
}
func NewDataPathUpLink() (link *DataPathUpLink)

type FAR

type FAR struct {
	FARID uint32

	ApplyAction          pfcpType.ApplyAction
	ForwardingParameters *ForwardingParameters

	BAR   *BAR
	State RuleState
}

Forwarding Action Rule. 7.5.2.3-1

func (*FAR) InitializeFAR

func (far *FAR) InitializeFAR(smContext *SMContext)

type ForwardingParameters

type ForwardingParameters struct {
	DestinationInterface pfcpType.DestinationInterface
	NetworkInstance      util_3gpp.Dnn
	OuterHeaderCreation  *pfcpType.OuterHeaderCreation
}

Forwarding Parameters. 7.5.2.3-2

type GTPTunnel

type GTPTunnel struct {
	SrcEndPoint  *DataPathNode
	DestEndPoint *DataPathNode

	TEID       uint32
	MatchedPDR *PDR
}

GTPTunnel represents the GTP tunnel information

type IDQueue

type IDQueue struct {
	QueueType IDType
	Queue     []int
}

func NewIDQueue

func NewIDQueue(idType IDType) (idQueue *IDQueue)

func (*IDQueue) IsEmpty

func (q *IDQueue) IsEmpty() (isEmpty bool)

func (*IDQueue) Pop

func (q *IDQueue) Pop() (id int, err error)

func (*IDQueue) Push

func (q *IDQueue) Push(item int)

type IDType

type IDType int
const (
	PDRType IDType = iota
	FARType
	BARType
	TEIDType
)

type PDI

type PDI struct {
	SourceInterface pfcpType.SourceInterface
	LocalFTeid      *pfcpType.FTEID
	NetworkInstance util_3gpp.Dnn
	UEIPAddress     *pfcpType.UEIPAddress
	SDFFilter       *pfcpType.SDFFilter
}

Packet Detection. 7.5.2.2-2

type PDR

type PDR struct {
	PDRID uint16

	Precedence         uint32
	PDI                PDI
	OuterHeaderRemoval *pfcpType.OuterHeaderRemoval

	FAR *FAR
	URR *URR
	QER *QER

	State RuleState
}

Packet Detection Rule. Table 7.5.2.2-1

func (*PDR) InitializePDR

func (pdr *PDR) InitializePDR(smContext *SMContext)

type PDUSessionAnchorState

type PDUSessionAnchorState int
const (
	NotAdded PDUSessionAnchorState = iota
	AddPSASuccess
	AddPSAFail
)

type PacketFilter

type PacketFilter struct {
	Direction     uint8
	Identifier    uint8
	ComponentType uint8
	Component     []byte
}

func (*PacketFilter) MarshalBinary

func (pf *PacketFilter) MarshalBinary() (data []byte, err error)

type QER

type QER struct {
}

QoS Enhancement Rule

type QoSRule

type QoSRule struct {
	Identifier       uint8
	OperationCode    uint8
	DQR              uint8
	Segregation      uint8
	PacketFilterList []PacketFilter
	Precedence       uint8
	QFI              uint8
}

func (*QoSRule) MarshalBinary

func (r *QoSRule) MarshalBinary() (data []byte, err error)

type QoSRules

type QoSRules []QoSRule

func (QoSRules) MarshalBinary

func (rs QoSRules) MarshalBinary() (data []byte, err error)

type RuleState

type RuleState uint8
const (
	RULE_INITIAL RuleState = 0
	RULE_CREATE  RuleState = 1
	RULE_UPDATE  RuleState = 2
	RULE_REMOVE  RuleState = 3
)

type SMContext

type SMContext struct {
	Ref string

	LocalSEID  uint64
	RemoteSEID uint64

	UnauthenticatedSupi bool
	// SUPI or PEI
	Supi           string
	Pei            string
	Identifier     string
	Gpsi           string
	PDUSessionID   int32
	Dnn            string
	Snssai         *models.Snssai
	HplmnSnssai    *models.Snssai
	ServingNetwork *models.PlmnId
	ServingNfId    string

	UpCnxState models.UpCnxState

	AnType          models.AccessType
	RatType         models.RatType
	PresenceInLadn  models.PresenceState
	UeLocation      *models.UserLocation
	UeTimeZone      string
	AddUeLocation   *models.UserLocation
	OldPduSessionId int32
	HoState         models.HoState

	PDUAddress             net.IP
	SelectedPDUSessionType uint8

	DnnConfiguration models.DnnConfiguration
	SessionRule      models.SessionRule

	// Client
	SMPolicyClient      *Npcf_SMPolicyControl.APIClient
	CommunicationClient *Namf_Communication.APIClient

	AMFProfile         models.NfProfile
	SelectedPCFProfile models.NfProfile
	SmStatusNotifyUri  string

	SMState SMState

	Tunnel    *UPTunnel
	BPManager *BPManager
}

func GetSMContext

func GetSMContext(ref string) (smContext *SMContext)

func GetSMContextBySEID

func GetSMContextBySEID(SEID uint64) *SMContext

func NewSMContext

func NewSMContext(identifier string, pduSessID int32) (smContext *SMContext)

func (*SMContext) BuildCreatedData

func (smContext *SMContext) BuildCreatedData() (createdData *models.SmContextCreatedData)

func (*SMContext) HandlePDUSessionEstablishmentRequest

func (smContext *SMContext) HandlePDUSessionEstablishmentRequest(req *nasMessage.PDUSessionEstablishmentRequest)

func (*SMContext) HandlePDUSessionReleaseRequest

func (smContext *SMContext) HandlePDUSessionReleaseRequest(req *nasMessage.PDUSessionReleaseRequest)

func (*SMContext) PCFSelection

func (smContext *SMContext) PCFSelection() (err error)

PCFSelection will select PCF for this SM Context

func (*SMContext) PDUAddressToNAS

func (smContext *SMContext) PDUAddressToNAS() (addr [12]byte, addrLen uint8)

func (*SMContext) SetCreateData

func (smContext *SMContext) SetCreateData(createData *models.SmContextCreateData)

type SMFContext

type SMFContext struct {
	Name         string
	NfInstanceID string

	URIScheme   models.UriScheme
	HTTPAddress string
	HTTPPort    int

	CPNodeID pfcpType.NodeID

	UDMProfile models.NfProfile

	UPNodeIDs []pfcpType.NodeID
	Key       string
	PEM       string
	KeyLog    string

	UESubNet      *net.IPNet
	UEAddressTemp net.IP

	NrfUri                         string
	NFManagementClient             *Nnrf_NFManagement.APIClient
	NFDiscoveryClient              *Nnrf_NFDiscovery.APIClient
	SubscriberDataManagementClient *Nudm_SubscriberDataManagement.APIClient

	UserPlaneInformation UserPlaneInformation
	//*** For ULCL ** //
	ULCLSupport     bool
	UERoutingPaths  map[string][]factory.Path
	UERoutingGraphs map[string]*UEDataPathGraph
}

func SMF_Self

func SMF_Self() *SMFContext

type SMState

type SMState int
const (
	PDUSessionInactive SMState = 0
	PDUSessionActive   SMState = 1
)

type UEDataPathGraph

type UEDataPathGraph struct {
	SUPI  string
	Graph []*DataPathNode
	ANUPF map[*DataPathNode]bool
	PSA   map[*DataPathNode]bool
}

func GetUERoutingGraph

func GetUERoutingGraph(SUPI string) *UEDataPathGraph

func NewUEDataPathGraph

func NewUEDataPathGraph(SUPI string) (UEPGraph *UEDataPathGraph, err error)

func (*UEDataPathGraph) AddANUPF

func (uepg *UEDataPathGraph) AddANUPF(node *DataPathNode)

func (*UEDataPathGraph) AddPSA

func (uepg *UEDataPathGraph) AddPSA(node *DataPathNode)

func (*UEDataPathGraph) FindBranchingPoints

func (uepg *UEDataPathGraph) FindBranchingPoints()

func (*UEDataPathGraph) GetGraphRoot

func (uepg *UEDataPathGraph) GetGraphRoot() *DataPathNode

type UEPathEndPoint

type UEPathEndPoint struct {
	EndPointIP   string
	EndPointPort string
}

type UEPathGraph

type UEPathGraph struct {
	SUPI  string
	Graph []*UEPathNode
}

func NewUEPathGraph

func NewUEPathGraph(SUPI string) (UEPGraph *UEPathGraph)

func (*UEPathGraph) FindBranchingPoints

func (uepg *UEPathGraph) FindBranchingPoints()

func (*UEPathGraph) IsBranchingPoint

func (uepg *UEPathGraph) IsBranchingPoint(name string) bool

check a given upf name is a branching point or not

type UEPathNode

type UEPathNode struct {
	UPFName             string
	Parent              string
	Neighbors           map[string]*UEPathNode
	IsBranchingPoint    bool
	EndPointOfEachChild map[string]*UEPathEndPoint
}

func NewUEPathNode

func NewUEPathNode(name string) (node *UEPathNode)

func (*UEPathNode) AddEndPointOfChild

func (node *UEPathNode) AddEndPointOfChild(neighbor *UEPathNode, EndPoint *UEPathEndPoint)

Add End Point Info to of child node to the map "EndPointOfEachChild" If the node is leaf node, it will add the end point info for itself name.

func (*UEPathNode) AddNeighbor

func (node *UEPathNode) AddNeighbor(neighbor *UEPathNode)

func (*UEPathNode) GetChild

func (node *UEPathNode) GetChild() []*UEPathNode

func (*UEPathNode) IsLeafNode

func (node *UEPathNode) IsLeafNode() bool

func (*UEPathNode) RmbParent

func (node *UEPathNode) RmbParent(parent string)

type ULCLState

type ULCLState int
const (
	IsOnlyULCL ULCLState = iota
	IsULCLAndPSA1
	IsULCLAndPSA2
)

type UPF

type UPF struct {
	NodeID    pfcpType.NodeID
	UPIPInfo  pfcpType.UserPlaneIPResourceInformation
	UPFStatus UPFStatus

	TEIDCount uint32
	// contains filtered or unexported fields
}

func NewUPF

func NewUPF(nodeID *pfcpType.NodeID) (upf *UPF)

NewUPF returns a new UPF context in SMF

func RetrieveUPFNodeByNodeID

func RetrieveUPFNodeByNodeID(nodeID pfcpType.NodeID) (upf *UPF)

func SelectUPFByDnn

func SelectUPFByDnn(Dnn string) *UPF

func (*UPF) AddBAR

func (upf *UPF) AddBAR() (bar *BAR, err error)

func (*UPF) AddFAR

func (upf *UPF) AddFAR() (far *FAR, err error)

func (*UPF) AddPDR

func (upf *UPF) AddPDR() (pdr *PDR, err error)

func (*UPF) CheckBARIDExist

func (upf *UPF) CheckBARIDExist(id int) (exist bool)

func (*UPF) CheckFARIDExist

func (upf *UPF) CheckFARIDExist(id int) (exist bool)

func (*UPF) CheckPDRIDExist

func (upf *UPF) CheckPDRIDExist(id int) (exist bool)

func (*UPF) GenerateTEID

func (upf *UPF) GenerateTEID() (id uint32, err error)

func (*UPF) GetUPFID

func (upf *UPF) GetUPFID() string

func (*UPF) GetUPFIP

func (upf *UPF) GetUPFIP() string

func (*UPF) GetValidID

func (upf *UPF) GetValidID(idType IDType) (id int)

func (*UPF) PFCPAddr

func (upf *UPF) PFCPAddr() *net.UDPAddr

func (*UPF) RemoveBAR

func (upf *UPF) RemoveBAR(bar *BAR) (err error)

func (*UPF) RemoveFAR

func (upf *UPF) RemoveFAR(far *FAR) (err error)

func (*UPF) RemovePDR

func (upf *UPF) RemovePDR(pdr *PDR) (err error)

func (*UPF) UUID

func (upf *UPF) UUID() string

UUID return this UPF UUID (allocate by SMF in this time) Maybe allocate by UPF in future

type UPFStatus

type UPFStatus int
const (
	NotAssociated          UPFStatus = 0
	AssociatedSettingUp    UPFStatus = 1
	AssociatedSetUpSuccess UPFStatus = 2
)

type UPNode

type UPNode struct {
	Type         UPNodeType
	NodeID       pfcpType.NodeID
	UPResourceIP net.IP
	ANIP         net.IP
	Dnn          string
	Links        []*UPNode
	UPF          *UPF
}

UPNode represent the user plane node topology

type UPNodeType

type UPNodeType string
const (
	UPNODE_UPF UPNodeType = "UPF"
	UPNODE_AN  UPNodeType = "AN"
)

type UPPath

type UPPath []*UPNode

UPPath represent User Plane Sequence of this path

type UPTunnel

type UPTunnel struct {
	Node  *UPF
	ULPDR *PDR
	DLPDR *PDR

	ULTEID uint32
	DLTEID uint32

	UpfRoot  *DataPathNode
	ULCLRoot *DataPathNode
}

type URR

type URR struct {
}

Usage Report Rule

type UserPlaneInformation

type UserPlaneInformation struct {
	UPNodes              map[string]*UPNode
	UPFs                 map[string]*UPNode
	AccessNetwork        map[string]*UPNode
	UPFIPToName          map[string]string
	UPFsID               map[string]string    // name to id
	UPFsIPtoID           map[string]string    // ip->id table, for speed optimization
	DefaultUserPlanePath map[string][]*UPNode // DNN to Default Path
}

UserPlaneInformation store userplane topology

func GetUserPlaneInformation

func GetUserPlaneInformation() *UserPlaneInformation

func (*UserPlaneInformation) ExistDefaultPath

func (upi *UserPlaneInformation) ExistDefaultPath(dnn string) bool

func (*UserPlaneInformation) GenerateDefaultPath

func (upi *UserPlaneInformation) GenerateDefaultPath(dnn string) (pathExist bool)

func (*UserPlaneInformation) GetDefaultUserPlanePathByDNN

func (upi *UserPlaneInformation) GetDefaultUserPlanePathByDNN(dnn string) (path UPPath)

func (*UserPlaneInformation) GetUPFIDByIP

func (upi *UserPlaneInformation) GetUPFIDByIP(ip string) string

func (*UserPlaneInformation) GetUPFNameByIp

func (upi *UserPlaneInformation) GetUPFNameByIp(ip string) string

func (*UserPlaneInformation) GetUPFNodeByIP

func (upi *UserPlaneInformation) GetUPFNodeByIP(ip string) *UPNode

func (*UserPlaneInformation) GetUPFNodeIDByName

func (upi *UserPlaneInformation) GetUPFNodeIDByName(name string) pfcpType.NodeID

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL