Zack Williams | e940c7a | 2019-08-21 14:25:39 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019-present Ciena Corporation |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | package model |
| 17 | |
| 18 | import ( |
| 19 | "fmt" |
| 20 | "github.com/jhump/protoreflect/dynamic" |
| 21 | "strings" |
| 22 | ) |
| 23 | |
| 24 | type LogicalDevice struct { |
| 25 | Id string `json:"id"` |
| 26 | DatapathId string `json:"datapathid"` |
| 27 | RootDeviceId string `json:"rootdeviceid"` |
| 28 | SerialNumber string `json:"serialnumber"` |
| 29 | Features struct { |
| 30 | NBuffers uint32 `json:"nbuffers"` |
| 31 | NTables uint32 `json:"ntables"` |
| 32 | Capabilities string `json:"capabilities"` |
| 33 | } `json:"features"` |
| 34 | Ports []LogicalPort `json:"ports"` |
| 35 | Flows []Flow `json:"flows"` |
| 36 | } |
| 37 | |
| 38 | type LogicalPort struct { |
| 39 | Id string `json:"id"` |
| 40 | DeviceId string `json:"deviceid"` |
| 41 | DevicePortNo uint32 `json:"deviceportno"` |
| 42 | RootPort bool `json:"rootport"` |
| 43 | Openflow struct { |
| 44 | PortNo uint32 `json:"portno"` |
| 45 | HwAddr string `json:"hwaddr"` |
| 46 | Name string `json:"name"` |
| 47 | Config string `json:"config"` |
| 48 | State string `json:"state"` |
| 49 | Features struct { |
| 50 | Advertised string `json:"advertised"` |
| 51 | Current string `json:"current"` |
| 52 | Supported string `json:"supported"` |
| 53 | Peer string `json:"peer"` |
| 54 | } `json:"features"` |
| 55 | Bitrate struct { |
| 56 | Current uint32 `json:"current"` |
| 57 | Max uint32 `json:"max"` |
| 58 | } |
| 59 | } `json:"openflow"` |
| 60 | } |
| 61 | |
| 62 | func (device *LogicalDevice) PopulateFrom(val *dynamic.Message) { |
| 63 | device.Id = val.GetFieldByName("id").(string) |
| 64 | device.DatapathId = fmt.Sprintf("%016x", val.GetFieldByName("datapath_id").(uint64)) |
| 65 | device.RootDeviceId = val.GetFieldByName("root_device_id").(string) |
| 66 | desc := val.GetFieldByName("desc").(*dynamic.Message) |
| 67 | device.SerialNumber = desc.GetFieldByName("serial_num").(string) |
| 68 | features := val.GetFieldByName("switch_features").(*dynamic.Message) |
| 69 | device.Features.NBuffers = features.GetFieldByName("n_buffers").(uint32) |
| 70 | device.Features.NTables = features.GetFieldByName("n_tables").(uint32) |
| 71 | device.Features.Capabilities = fmt.Sprintf("0x%08x", features.GetFieldByName("capabilities").(uint32)) |
| 72 | |
| 73 | ports := val.GetFieldByName("ports").([]interface{}) |
| 74 | device.Ports = make([]LogicalPort, len(ports)) |
| 75 | for i, port := range ports { |
| 76 | device.Ports[i].PopulateFrom(port.(*dynamic.Message)) |
| 77 | } |
| 78 | |
| 79 | flows := val.GetFieldByName("flows").(*dynamic.Message) |
| 80 | if flows == nil { |
| 81 | device.Flows = make([]Flow, 0) |
| 82 | } else { |
| 83 | items := flows.GetFieldByName("items").([]interface{}) |
| 84 | device.Flows = make([]Flow, len(items)) |
| 85 | for i, flow := range items { |
| 86 | device.Flows[i].PopulateFrom(flow.(*dynamic.Message)) |
| 87 | } |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | func (port *LogicalPort) PopulateFrom(val *dynamic.Message) { |
| 92 | port.Id = val.GetFieldByName("id").(string) |
| 93 | port.DeviceId = val.GetFieldByName("device_id").(string) |
| 94 | port.DevicePortNo = val.GetFieldByName("device_port_no").(uint32) |
| 95 | port.RootPort = val.GetFieldByName("root_port").(bool) |
| 96 | ofp := val.GetFieldByName("ofp_port").(*dynamic.Message) |
| 97 | hw := strings.Builder{} |
| 98 | first := true |
| 99 | for _, b := range ofp.GetFieldByName("hw_addr").([]interface{}) { |
| 100 | if !first { |
| 101 | hw.WriteString(":") |
| 102 | } |
| 103 | first = false |
| 104 | hw.WriteString(fmt.Sprintf("%02x", b)) |
| 105 | } |
| 106 | port.Openflow.HwAddr = hw.String() |
| 107 | port.Openflow.PortNo = ofp.GetFieldByName("port_no").(uint32) |
| 108 | port.Openflow.Name = ofp.GetFieldByName("name").(string) |
| 109 | port.Openflow.Config = fmt.Sprintf("0x%08x", ofp.GetFieldByName("config").(uint32)) |
| 110 | port.Openflow.State = fmt.Sprintf("0x%08x", ofp.GetFieldByName("state").(uint32)) |
| 111 | port.Openflow.Features.Current = fmt.Sprintf("0x%08x", ofp.GetFieldByName("curr").(uint32)) |
| 112 | port.Openflow.Features.Advertised = fmt.Sprintf("0x%08x", ofp.GetFieldByName("advertised").(uint32)) |
| 113 | port.Openflow.Features.Supported = fmt.Sprintf("0x%08x", ofp.GetFieldByName("supported").(uint32)) |
| 114 | port.Openflow.Features.Peer = fmt.Sprintf("0x%08x", ofp.GetFieldByName("peer").(uint32)) |
| 115 | port.Openflow.Bitrate.Current = ofp.GetFieldByName("curr_speed").(uint32) |
| 116 | port.Openflow.Bitrate.Max = ofp.GetFieldByName("max_speed").(uint32) |
| 117 | } |