blob: 101f160925adbf962d712d681226c365be67553c [file] [log] [blame]
/*
* Copyright 2022-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package onos_nbi
import (
"strconv"
"voltha-go-controller/internal/pkg/of"
app "voltha-go-controller/internal/pkg/application"
)
const (
/** Switch input port. */
IN_PORT string = "IN_PORT"
/** Switch physical input port. */
IN_PHY_PORT string = "IN_PHY_PORT"
/** Metadata passed between tables. */
METADATA string = "METADATA"
/** Ethernet destination address. */
ETH_DST string = "ETH_DST"
/** Ethernet destination address with masking. */
ETH_DST_MASKED = "ETH_DST_MASKED"
/** Ethernet source address. */
ETH_SRC string = "ETH_SRC"
/** Ethernet source address with masking. */
ETH_SRC_MASKED string = "ETH_SRC_MASKED"
/** Ethernet frame type. */
ETH_TYPE string = "ETH_TYPE"
/** VLAN id. */
VLAN_VID string = "VLAN_VID"
/** VLAN priority. */
VLAN_PCP string = "VLAN_PCP"
/**
* Inner VLAN id.
*
* Note: Some drivers may not support this.
*/
INNER_VLAN_VID string = "INNER_VLAN_VID"
/**
* Inner VLAN pcp.
*
* Note: Some drivers may not support this.
*/
INNER_VLAN_PCP string = "INNER_VLAN_PCP"
/** IP DSCP (6 bits in ToS field). */
IP_DSCP string = "IP_DSCP"
/** IP ECN (2 bits in ToS field). */
IP_ECN string = "IP_ECN"
/** IP protocol. */
IP_PROTO string = "IP_PROTO"
/** IPv4 source address. */
IPV4_SRC string = "IPV4_SRC"
/** IPv4 destination address. */
IPV4_DST string = "IPV4_DST"
/** TCP source port. */
TCP_SRC string = "TCP_SRC"
/** TCP source port with masking. */
TCP_SRC_MASKED string = "TCP_SRC_MASKED"
/** TCP destination port. */
TCP_DST string = "TCP_DST"
/** TCP destination port with masking. */
TCP_DST_MASKED string = "TCP_DST"
/** UDP source port. */
UDP_SRC string = "UDP_SRC"
/** UDP source port with masking. */
UDP_SRC_MASKED string = "UDP_SRC_MASKED"
/** UDP destination port. */
UDP_DST string = "UDP_DST"
/** UDP destination port with masking. */
UDP_DST_MASKED string = "UDP_DST_MASKED"
/** SCTP source port. */
SCTP_SRC string = "SCTP_SRC"
/** SCTP source port with masking. */
SCTP_SRC_MASKED string = "SCTP_SRC_MASKED"
/** SCTP destination port. */
SCTP_DST string = "SCTP_DST"
/** SCTP destination port with masking. */
SCTP_DST_MASKED string = "SCTP_DST_MASKED"
/** ICMP type. */
ICMPV4_TYPE string = "ICMPV4_TYPE"
/** ICMP code. */
ICMPV4_CODE string = "ICMPV4_CODE"
/** ARP opcode. */
ARP_OP string = "ARP_OP"
/** ARP source IPv4 address. */
ARP_SPA string = "ARP_SPA"
/** ARP target IPv4 address. */
ARP_TPA string = "ARP_TPA"
/** ARP source hardware address. */
ARP_THA string = "ARP_THA"
/** IPv6 source address. */
IPV6_SRC string = "IPV6_SRC"
/** IPv6 destination address. */
IPV6_DST string = "IPV6_DST"
/** IPv6 Flow Label. */
IPV6_FLABEL string = "IPV6_FLABEL"
/** ICMPv6 type. */
ICMPV6_TYPE string = "ICMPV6_TYPE"
/** ICMPv6 code. */
ICMPV6_CODE string = "ICMPV6_CODE"
/** Target address for ND. */
IPV6_ND_TARGET string = "IPV6_ND_TARGET"
/** Source link-layer for ND. */
IPV6_ND_SLL string = "IPV6_ND_SLL"
/** Target link-layer for ND. */
IPV6_ND_TLL string = "IPV6_ND_TLL"
/** MPLS label. */
MPLS_LABEL string = "MPLS_LABEL"
/** MPLS TC. */
MPLS_TC string = "MPLS_TC"
/** MPLS BoS bit. */
MPLS_BOS string = "MPLS_BOS"
/** PBB I-SID. */
PBB_ISID string = "PBB_ISID"
/** Logical Port Metadata. */
TUNNEL_ID string = "TUNNEL_ID"
/** IPv6 Extension Header pseudo-field. */
IPV6_EXTHDR string = "IPV6_EXTHDR"
/** Unassigned value: 40. */
UNASSIGNED_40 string = "UNASSIGNED_40"
/** PBB UCA header field. */
PBB_UCA string = "PBB_UCA"
/** TCP flags. */
TCP_FLAGS string = "TCP_FLAGS"
/** Output port from action set metadata. */
ACTSET_OUTPUT string = "ACTSET_OUTPUT"
/** Packet type value. */
PACKET_TYPE string = "PACKET_TYPE"
//
// NOTE: Everything below is defined elsewhere: ONOS-specific,
// extensions, etc.
//
/** Optical channel signal ID (lambda). */
OCH_SIGID string = "OCH_SIGID"
/** Optical channel signal type (fixed or flexible). */
OCH_SIGTYPE string = "OCH_SIGTYPE"
/** ODU (Optical channel Data Unit) signal ID. */
ODU_SIGID string = "ODU_SIGID"
/** ODU (Optical channel Data Unit) signal type. */
ODU_SIGTYPE string = "ODU_SIGTYPE"
/** Protocol-independent. */
PROTOCOL_INDEPENDENT string = "PROTOCOL_INDEPENDENT"
/** Extension criterion. */
EXTENSION string = "EXTENSION"
/** An empty criterion. */
DUMMY string = "DUMMY"
/* OUTPUT instruction */
OUTPUT string = "OUTPUT"
/* METER instruction */
METER string = "METER"
/* L2MODIFICATION instruction type */
L2MODIFICATION string = "L2MODIFICATION"
/* VLAN_PUSH operation */
VLAN_PUSH string = "VLAN_PUSH"
/* VLAN_ID instruction */
VLAN_ID string = "VLAN_ID"
/* VLAN_POP operation */
VLAN_POP string = "VLAN_POP"
/* VLAN_SET operation */
VLAN_SET string = "VLAN_SET"
)
// Selector Critrtion structs
type Criterion interface{
GetType() string
}
type PortSelector struct {
Type string `json:"type"`
Port int `json:"port,omitempty"`
}
func (s PortSelector) GetType() string {
return s.Type
}
type EthTypeSelector struct {
Type string `json:"type"`
EthType string `json:"ethType,omitempty"`
}
func (s EthTypeSelector) GetType() string {
return s.Type
}
type ProtocolSelector struct {
Type string `json:"type"`
Protocol int `json:"protocol,omitempty"`
}
func (s ProtocolSelector) GetType() string {
return s.Type
}
type UDPPortSelector struct {
Type string `json:"type"`
UDPPort int `json:"udpPort,omitempty"`
}
func (s UDPPortSelector) GetType() string {
return s.Type
}
type VlanSelector struct {
Type string `json:"type"`
VlanID int `json:"vlanId,omitempty"`
}
func (s VlanSelector) GetType() string {
return s.Type
}
type EthSrcSelector struct {
Type string `json:"type"`
EthSrc string `json:"ethsrc,omitempty"`
}
func (s EthSrcSelector) GetType() string {
return s.Type
}
type EthDstSelector struct {
Type string `json:"type"`
DstSrc string `json:"ethdst,omitempty"`
}
func (s EthDstSelector) GetType() string {
return s.Type
}
type MetaDataSelector struct {
Type string `json:"type"`
Metadata uint64 `json:"metadata,omitempty"`
}
func (s MetaDataSelector) GetType() string {
return s.Type
}
///////// END of selector interfaces
type SelectorInfo struct {
Criteria []Criterion `json:"criteria"`
}
// Instruction structs are defined here
type Instruction interface {
GetInstructionType() string
}
type PortInstruction struct {
Type string `json:"type"`
Port string `json:"port"`
}
func (i PortInstruction) GetInstructionType() string {
return i.Type
}
type PushVlanInstruction struct {
Type string `json:"type"`
SubType string `json:"subtype"`
EthernetType string `json:"ethernetType"`
}
func (i PushVlanInstruction) GetInstructionType() string {
return i.Type
}
type VlanInstruction struct {
Type string `json:"type"`
SubType string `json:"subtype"`
VlanID int `json:"vlanId"`
}
func (i VlanInstruction) GetInstructionType() string {
return i.Type
}
type PopVlanInstruction struct {
Type string `json:"type"`
SubType string `json:"subtype"`
}
func (i PopVlanInstruction) GetInstructionType() string {
return i.Type
}
type MeterInstruction struct {
Type string `json:"type"`
MeterID string `json:"meterId"`
}
func (i MeterInstruction) GetInstructionType() string {
return i.Type
}
type TreatmentInfo struct {
Instructions []Instruction `json:"instructions"`
Deferred []interface{} `json:"deferred"`
}
type Flow struct {
GroupID int `json:"groupId"`
State string `json:"state"`
Life int `json:"life"`
LiveType string `json:"liveType"`
LastSeen int64 `json:"lastSeen"`
Packets int `json:"packets"`
Bytes int `json:"bytes"`
ID string `json:"id"`
AppID string `json:"appId"`
Priority int `json:"priority"`
Timeout int `json:"timeout"`
IsPermanent bool `json:"isPermanent"`
DeviceID string `json:"deviceId"`
TableID int `json:"tableId"`
TableName string `json:"tableName"`
Treatment TreatmentInfo `json:"treatment"`
Selector SelectorInfo `json:"selector"`
}
type FlowEntry struct {
Flows []Flow `json:"flows"`
}
func ConvertFlowToFlowEntry (subFlow *of.VoltSubFlow) FlowEntry {
var flowEntry FlowEntry
flow := ConvertVoltSubFlowToOnosFlow(subFlow)
flowEntry.Flows = append(flowEntry.Flows, flow)
return flowEntry
}
func ConvertFlowsToFlowEntry (subFlows []*of.VoltSubFlow) FlowEntry {
var flowEntry FlowEntry
for _, subFlow := range subFlows {
flow := ConvertVoltSubFlowToOnosFlow(subFlow)
flowEntry.Flows = append(flowEntry.Flows, flow)
}
return flowEntry
}
func ConvertVoltSubFlowToOnosFlow(subFlow *of.VoltSubFlow) Flow {
var flow Flow
flow.ID = strconv.FormatUint(subFlow.Cookie, 10)
flow.TableID = int(subFlow.TableID)
flow.Priority = int(subFlow.Priority)
//flow.State = subFlow.State
// Fill Match criteria
if subFlow.InPort != 0 {
portSelector := PortSelector {
Type: IN_PORT,
Port: int(subFlow.InPort),
}
flow.Selector.Criteria = append(flow.Selector.Criteria, Criterion(portSelector))
}
if subFlow.MatchVlan != of.VlanNone {
vlanSelector := VlanSelector {
Type: VLAN_VID,
VlanID: int(subFlow.MatchVlan),
}
flow.Selector.Criteria = append(flow.Selector.Criteria, Criterion(vlanSelector))
}
if subFlow.SrcMacMatch {
ethSrcSelector := EthSrcSelector {
Type: ETH_SRC,
EthSrc: subFlow.SrcMacAddr.String(),
}
flow.Selector.Criteria = append(flow.Selector.Criteria, Criterion(ethSrcSelector))
}
if subFlow.DstMacMatch {
ethDstSelector := EthDstSelector {
Type: ETH_DST,
DstSrc: subFlow.DstMacAddr.String(),
}
flow.Selector.Criteria = append(flow.Selector.Criteria, Criterion(ethDstSelector))
}
if subFlow.L3Protocol != of.EtherTypeAny {
ethTypeSelector := EthTypeSelector {
Type: ETH_TYPE,
EthType : strconv.FormatUint(uint64(subFlow.L3Protocol), 16) ,
}
flow.Selector.Criteria = append(flow.Selector.Criteria, Criterion(ethTypeSelector))
}
if subFlow.L4Protocol != of.IPProtocolIgnore {
protocolSelector := ProtocolSelector {
Type: IP_PROTO,
Protocol : int(subFlow.L4Protocol),
}
flow.Selector.Criteria = append(flow.Selector.Criteria, Criterion(protocolSelector))
}
if subFlow.SrcPort != 0 {
udpPortSelector := UDPPortSelector {
Type: UDP_SRC,
UDPPort : int(subFlow.SrcPort) ,
}
flow.Selector.Criteria = append(flow.Selector.Criteria, Criterion(udpPortSelector))
}
if subFlow.DstPort != 0 {
udpPortSelector := UDPPortSelector {
Type: UDP_DST,
UDPPort : int(subFlow.DstPort) ,
}
flow.Selector.Criteria = append(flow.Selector.Criteria, Criterion(udpPortSelector))
}
if subFlow.TableMetadata != 0 {
metaDataSelector := MetaDataSelector {
Type: METADATA,
Metadata : subFlow.TableMetadata,
}
flow.Selector.Criteria = append(flow.Selector.Criteria, Criterion(metaDataSelector))
}
// Fill actions
if subFlow.Output != 0 {
portInstruction := PortInstruction {
Type: OUTPUT,
}
switch subFlow.Output {
case of.OutputTypeToController:
portInstruction.Port = "CONTROLLER"
case of.OutputTypeToNetwork:
portInstruction.Port = strconv.FormatUint(uint64(subFlow.OutPort) , 10)
case of.OutputTypeGoToTable:
portInstruction.Port = strconv.FormatUint(uint64(subFlow.GoToTableID) , 10)
}
flow.Treatment.Instructions = append(flow.Treatment.Instructions, Instruction(portInstruction))
}
if len(subFlow.PushVlan) != 0 {
for _, vlan := range subFlow.PushVlan {
if vlan == of.VlanNone {
continue
}
pushVlanInstruction := PushVlanInstruction {
Type: L2MODIFICATION,
SubType: VLAN_PUSH,
EthernetType: "0x8100" ,
}
flow.Treatment.Instructions = append(flow.Treatment.Instructions, Instruction(pushVlanInstruction))
vlanInstruction := VlanInstruction {
Type: L2MODIFICATION,
SubType: VLAN_ID,
VlanID: int(vlan),
}
flow.Treatment.Instructions = append(flow.Treatment.Instructions, Instruction(vlanInstruction))
}
}
if subFlow.SetVlan != of.VlanNone {
vlanInstruction := VlanInstruction {
Type: L2MODIFICATION,
SubType: VLAN_SET,
VlanID: int(subFlow.SetVlan) ,
}
flow.Treatment.Instructions = append(flow.Treatment.Instructions, Instruction(vlanInstruction))
}
if subFlow.RemoveVlan != 0 {
popVlanInstruction := PopVlanInstruction {
Type: L2MODIFICATION,
SubType: VLAN_POP,
}
flow.Treatment.Instructions = append(flow.Treatment.Instructions, Instruction(popVlanInstruction))
}
if subFlow.MeterID != 0 {
meterInstruction := MeterInstruction {
Type: METER,
MeterID: strconv.FormatUint(uint64(subFlow.MeterID), 10),
}
flow.Treatment.Instructions = append(flow.Treatment.Instructions, Instruction(meterInstruction))
}
return flow
}
func convertServiceToSubscriberInfo(svcs []*app.VoltService) []*SubscriberInfo {
var subs []*SubscriberInfo
for _, vs := range svcs {
pbit := vs.GetServicePbit()
sub := &SubscriberInfo{
Location : vs.Device,
TagInfo : UniTagInformation {
UniTagMatch: int(vs.UniVlan),
PonCTag: int(vs.CVlan),
PonSTag: int(vs.SVlan),
UsPonCTagPriority: pbit,
UsPonSTagPriority: pbit,
DsPonCTagPriority: pbit,
DsPonSTagPriority: pbit,
TechnologyProfileID: int(vs.TechProfileID),
UpstreamBandwidthProfile: vs.UsMeterProfile,
DownstreamBandwidthProfile: vs.DsMeterProfile,
UpstreamOltBandwidthProfile: vs.UsMeterProfile,
DownstreamOltBandwidthProfile: vs.DsMeterProfile,
ServiceName: vs.Name,
EnableMacLearning: vs.MacLearning == app.Learn,
ConfiguredMacAddress: vs.MacAddr.String(),
IsDhcpRequired: vs.MacLearning == app.Learn,
IsIgmpRequired: vs.IgmpEnabled,
IsPppoeRequired: false,
},
}
subs = append(subs, sub)
}
return subs
}