blob: 53e4076a58e2a6db069b280ab2bd9262e32f5b2e [file] [log] [blame]
Kent Hagerman3136fbd2020-05-14 10:30:45 -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 */
16
17package device
18
19import (
20 "context"
21 "fmt"
22 "sync"
23
24 "github.com/gogo/protobuf/proto"
25 "github.com/opencord/voltha-lib-go/v3/pkg/log"
26 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
27)
28
29//GroupChunk keeps a group entry and its lock. The lock in the struct is used to syncronize the
30//modifications for the related group.
31type GroupChunk struct {
32 group *ofp.OfpGroupEntry
33 lock sync.Mutex
34}
35
36func (agent *LogicalAgent) loadGroups(ctx context.Context) {
37 agent.groupLock.Lock()
38 defer agent.groupLock.Unlock()
39
40 var groups []*ofp.OfpGroupEntry
41 if err := agent.clusterDataProxy.List(ctx, "groups/"+agent.logicalDeviceID, &groups); err != nil {
42 logger.Errorw("Failed-to-list-groups-from-proxy", log.Fields{"error": err})
43 return
44 }
45 for _, group := range groups {
46 if group.Desc != nil {
47 groupChunk := GroupChunk{
48 group: group,
49 }
50 agent.groups[group.Desc.GroupId] = &groupChunk
51 }
52 }
53 logger.Infow("Groups-are-loaded-into-the-cache-from-store", log.Fields{"logicalDeviceID": agent.logicalDeviceID})
54}
55
56//updateLogicalDeviceFlowGroup updates the flow groups in store and cache
57//It is assumed that the chunk lock has been acquired before this function is called
58func (agent *LogicalAgent) updateLogicalDeviceFlowGroup(ctx context.Context, groupEntry *ofp.OfpGroupEntry, groupChunk *GroupChunk) error {
59 path := fmt.Sprintf("groups/%s/%d", agent.logicalDeviceID, groupEntry.Desc.GroupId)
60 if err := agent.clusterDataProxy.Update(ctx, path, groupEntry); err != nil {
61 logger.Errorw("error-updating-logical-device-with-group", log.Fields{"error": err})
62 return err
63 }
64 groupChunk.group = groupEntry
65 return nil
66}
67
68//removeLogicalDeviceFlowGroup removes the flow groups in store and cache
69//It is assumed that the chunk lock has been acquired before this function is called
70func (agent *LogicalAgent) removeLogicalDeviceFlowGroup(ctx context.Context, groupID uint32) error {
71 path := fmt.Sprintf("groups/%s/%d", agent.logicalDeviceID, groupID)
72 if err := agent.clusterDataProxy.Remove(ctx, path); err != nil {
73 return fmt.Errorf("couldnt-delete-group-from-store-%s", path)
74 }
75 agent.groupLock.Lock()
76 defer agent.groupLock.Unlock()
77 delete(agent.groups, groupID)
78 return nil
79}
80
81// ListLogicalDeviceFlowGroups returns logical device flow groups
82func (agent *LogicalAgent) ListLogicalDeviceFlowGroups(ctx context.Context) (*ofp.FlowGroups, error) {
83 logger.Debug("ListLogicalDeviceFlowGroups")
84
85 var groupEntries []*ofp.OfpGroupEntry
86 agent.groupLock.RLock()
87 defer agent.groupLock.RUnlock()
88 for _, value := range agent.groups {
89 groupEntries = append(groupEntries, (proto.Clone(value.group)).(*ofp.OfpGroupEntry))
90 }
91 return &ofp.FlowGroups{Items: groupEntries}, nil
92}