blob: 67d7c293355f4c6c80746426da2a5770d99a7b96 [file] [log] [blame]
khenaidoo89b0e942018-10-21 21:11:33 -04001/*
2 * Copyright 2018-present Open Networking Foundation
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 */
16package utils
17
18import (
19 "bytes"
20 "github.com/cevaris/ordered_map"
21 "github.com/gogo/protobuf/proto"
22 ofp "github.com/opencord/voltha-go/protos/openflow_13"
23)
24
25type OfpFlowModArgs map[string]uint64
26
27type FlowArgs struct {
28 MatchFields []*ofp.OfpOxmOfbField
29 Actions []*ofp.OfpAction
30 Command *ofp.OfpFlowModCommand
31 Priority uint32
32 KV OfpFlowModArgs
33}
34
khenaidood20a5852018-10-22 22:09:55 -040035type GroupArgs struct {
36 GroupId uint32
37 Buckets []*ofp.OfpBucket
38 Command *ofp.OfpGroupModCommand
39}
40
khenaidoo89b0e942018-10-21 21:11:33 -040041type FlowsAndGroups struct {
42 Flows *ordered_map.OrderedMap
43 Groups *ordered_map.OrderedMap
44}
45
46func NewFlowsAndGroups() *FlowsAndGroups {
47 var fg FlowsAndGroups
48 fg.Flows = ordered_map.NewOrderedMap()
49 fg.Groups = ordered_map.NewOrderedMap()
50 return &fg
51}
52
53func (fg *FlowsAndGroups) Copy() *FlowsAndGroups {
54 copyFG := NewFlowsAndGroups()
55 iter := fg.Flows.IterFunc()
56 for kv, ok := iter(); ok; kv, ok = iter() {
57 if protoMsg, isMsg := kv.Value.(*ofp.OfpFlowStats); isMsg {
58 copyFG.Flows.Set(kv.Key, proto.Clone(protoMsg))
59 }
60 }
61 iter = fg.Groups.IterFunc()
62 for kv, ok := iter(); ok; kv, ok = iter() {
63 if protoMsg, isMsg := kv.Value.(*ofp.OfpGroupEntry); isMsg {
64 copyFG.Groups.Set(kv.Key, proto.Clone(protoMsg))
65 }
66 }
67 return copyFG
68}
69
70func (fg *FlowsAndGroups) GetFlow(index int) *ofp.OfpFlowStats {
71 iter := fg.Flows.IterFunc()
72 pos := 0
73 for kv, ok := iter(); ok; kv, ok = iter() {
74 if pos == index {
75 if protoMsg, isMsg := kv.Value.(*ofp.OfpFlowStats); isMsg {
76 return protoMsg
77 }
78 return nil
79 }
80 pos += 1
81 }
82 return nil
83}
84
85func (fg *FlowsAndGroups) String() string {
86 var buffer bytes.Buffer
87 iter := fg.Flows.IterFunc()
88 for kv, ok := iter(); ok; kv, ok = iter() {
89 if protoMsg, isMsg := kv.Value.(*ofp.OfpFlowStats); isMsg {
90 buffer.WriteString("\nFlow:\n")
91 buffer.WriteString(proto.MarshalTextString(protoMsg))
92 buffer.WriteString("\n")
93 }
94 }
95 iter = fg.Groups.IterFunc()
96 for kv, ok := iter(); ok; kv, ok = iter() {
97 if protoMsg, isMsg := kv.Value.(*ofp.OfpGroupEntry); isMsg {
98 buffer.WriteString("\nGroup:\n")
99 buffer.WriteString(proto.MarshalTextString(protoMsg))
100 buffer.WriteString("\n")
101 }
102 }
103 return buffer.String()
104}
105
106func (fg *FlowsAndGroups) AddFlow(flow *ofp.OfpFlowStats) {
107 if fg.Flows == nil {
108 fg.Flows = ordered_map.NewOrderedMap()
109 }
110 if fg.Groups == nil {
111 fg.Groups = ordered_map.NewOrderedMap()
112 }
113 //Add flow only if absent
114 if _, exist := fg.Flows.Get(flow.Id); !exist {
115 fg.Flows.Set(flow.Id, flow)
116 }
117}
118
119//AddFrom add flows and groups from the argument into this structure only if they do not already exist
120func (fg *FlowsAndGroups) AddFrom(from *FlowsAndGroups) {
121 iter := from.Flows.IterFunc()
122 for kv, ok := iter(); ok; kv, ok = iter() {
123 if protoMsg, isMsg := kv.Value.(*ofp.OfpFlowStats); isMsg {
124 if _, exist := fg.Flows.Get(protoMsg.Id); !exist {
125 fg.Flows.Set(protoMsg.Id, protoMsg)
126 }
127 }
128 }
129 iter = from.Groups.IterFunc()
130 for kv, ok := iter(); ok; kv, ok = iter() {
131 if protoMsg, isMsg := kv.Value.(*ofp.OfpGroupEntry); isMsg {
132 if _, exist := fg.Groups.Get(protoMsg.Stats.GroupId); !exist {
133 fg.Groups.Set(protoMsg.Stats.GroupId, protoMsg)
134 }
135 }
136 }
137}
138
139type DeviceRules struct {
140 Rules map[string]*FlowsAndGroups
141}
142
143func NewDeviceRules() *DeviceRules {
144 var dr DeviceRules
145 dr.Rules = make(map[string]*FlowsAndGroups)
146 return &dr
147}
148
149func (dr *DeviceRules) Copy() *DeviceRules {
150 copyDR := NewDeviceRules()
151 for key, val := range dr.Rules {
152 copyDR.Rules[key] = val.Copy()
153 }
154 return copyDR
155}
156
157func (dr *DeviceRules) String() string {
158 var buffer bytes.Buffer
159 for key, value := range dr.Rules {
160 buffer.WriteString("DeviceId:")
161 buffer.WriteString(key)
162 buffer.WriteString(value.String())
163 buffer.WriteString("\n\n")
164 }
165 return buffer.String()
166}
167
168func (dr *DeviceRules) AddFlowsAndGroup(deviceId string, fg *FlowsAndGroups) {
khenaidood20a5852018-10-22 22:09:55 -0400169 if _, ok := dr.Rules[deviceId]; !ok {
170 dr.Rules[deviceId] = NewFlowsAndGroups()
171 }
khenaidoo89b0e942018-10-21 21:11:33 -0400172 dr.Rules[deviceId] = fg
173}
khenaidood20a5852018-10-22 22:09:55 -0400174
175// CreateEntryIfNotExist creates a new deviceId in the Map if it does not exist and assigns an
176// empty FlowsAndGroups to it. Otherwise, it does nothing.
177func (dr *DeviceRules) CreateEntryIfNotExist(deviceId string) {
178 if _, ok := dr.Rules[deviceId]; !ok {
179 dr.Rules[deviceId] = NewFlowsAndGroups()
180 }
181}