blob: ae45edec71e3ae3813169651a9de86ef6cd748a7 [file] [log] [blame]
Jonathan Hart60c5d772020-03-30 18:28:40 -07001/*
2 Copyright 2020 the original author or authors.
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 openflow
18
19import (
20 "context"
Andrea Campanella22aa3ed2021-03-04 15:58:55 +010021 "fmt"
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000022
Jonathan Hart828908c2020-04-15 14:23:45 -070023 "github.com/opencord/goloxi"
24 ofp "github.com/opencord/goloxi/of13"
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000025 "github.com/opencord/voltha-lib-go/v7/pkg/log"
26 "github.com/opencord/voltha-protos/v5/go/openflow_13"
27 "github.com/opencord/voltha-protos/v5/go/voltha"
Jonathan Hart60c5d772020-03-30 18:28:40 -070028)
29
Rohan Agrawalc32d9932020-06-15 11:01:47 +000030func (ofc *OFConnection) handleGroupMod(ctx context.Context, groupMod ofp.IGroupMod) {
Girish Kumar01e0c632020-08-10 16:48:56 +000031 span, ctx := log.CreateChildSpan(ctx, "openflow-group-modification")
32 defer span.Finish()
Jonathan Hart60c5d772020-03-30 18:28:40 -070033
34 volthaClient := ofc.VolthaClient.Get()
35 if volthaClient == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000036 logger.Errorw(ctx, "no-voltha-connection",
Jonathan Hart60c5d772020-03-30 18:28:40 -070037 log.Fields{"device-id": ofc.DeviceID})
38 return
39 }
40
41 groupUpdate := &openflow_13.FlowGroupTableUpdate{
42 Id: ofc.DeviceID,
43 GroupMod: &voltha.OfpGroupMod{
Rohan Agrawalc32d9932020-06-15 11:01:47 +000044 Command: openflowGroupModCommandToVoltha(ctx, groupMod.GetCommand()),
45 Type: openflowGroupTypeToVoltha(ctx, groupMod.GetGroupType()),
Jonathan Hart60c5d772020-03-30 18:28:40 -070046 GroupId: groupMod.GetGroupId(),
47 Buckets: openflowBucketsToVoltha(groupMod.GetBuckets()),
48 },
49 }
50
Girish Kumar01e0c632020-08-10 16:48:56 +000051 _, err := volthaClient.UpdateLogicalDeviceFlowGroupTable(log.WithSpanFromContext(context.Background(), ctx), groupUpdate)
Jonathan Hart60c5d772020-03-30 18:28:40 -070052 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000053 logger.Errorw(ctx, "Error updating group table",
Jonathan Hart60c5d772020-03-30 18:28:40 -070054 log.Fields{"device-id": ofc.DeviceID, "error": err})
55 }
56
57}
58
Rohan Agrawalc32d9932020-06-15 11:01:47 +000059func openflowGroupModCommandToVoltha(ctx context.Context, command ofp.GroupModCommand) openflow_13.OfpGroupModCommand {
Jonathan Hart60c5d772020-03-30 18:28:40 -070060 switch command {
61 case ofp.OFPGCAdd:
62 return openflow_13.OfpGroupModCommand_OFPGC_ADD
63 case ofp.OFPGCModify:
64 return openflow_13.OfpGroupModCommand_OFPGC_MODIFY
65 case ofp.OFPGCDelete:
66 return openflow_13.OfpGroupModCommand_OFPGC_DELETE
67 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +000068 logger.Errorw(ctx, "Unknown group mod command", log.Fields{"command": command})
Jonathan Hart60c5d772020-03-30 18:28:40 -070069 return 0
70}
71
Rohan Agrawalc32d9932020-06-15 11:01:47 +000072func openflowGroupTypeToVoltha(ctx context.Context, t ofp.GroupType) openflow_13.OfpGroupType {
Jonathan Hart60c5d772020-03-30 18:28:40 -070073 switch t {
74 case ofp.OFPGTAll:
75 return openflow_13.OfpGroupType_OFPGT_ALL
76 case ofp.OFPGTSelect:
77 return openflow_13.OfpGroupType_OFPGT_SELECT
78 case ofp.OFPGTIndirect:
79 return openflow_13.OfpGroupType_OFPGT_INDIRECT
80 case ofp.OFPGTFf:
81 return openflow_13.OfpGroupType_OFPGT_FF
82 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +000083 logger.Errorw(ctx, "Unknown openflow group type", log.Fields{"type": t})
Jonathan Hart60c5d772020-03-30 18:28:40 -070084 return 0
85}
86
Rohan Agrawalc32d9932020-06-15 11:01:47 +000087func volthaGroupTypeToOpenflow(ctx context.Context, t openflow_13.OfpGroupType) ofp.GroupType {
Jonathan Hart60c5d772020-03-30 18:28:40 -070088 switch t {
89 case openflow_13.OfpGroupType_OFPGT_ALL:
90 return ofp.OFPGTAll
91 case openflow_13.OfpGroupType_OFPGT_SELECT:
92 return ofp.OFPGTSelect
93 case openflow_13.OfpGroupType_OFPGT_INDIRECT:
94 return ofp.OFPGTIndirect
95 case openflow_13.OfpGroupType_OFPGT_FF:
96 return ofp.OFPGTFf
97 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +000098 logger.Errorw(ctx, "Unknown voltha group type", log.Fields{"type": t})
Jonathan Hart60c5d772020-03-30 18:28:40 -070099 return 0
100}
101
102func openflowBucketsToVoltha(buckets []*ofp.Bucket) []*openflow_13.OfpBucket {
103 outBuckets := make([]*openflow_13.OfpBucket, len(buckets))
104
105 for i, bucket := range buckets {
106 b := &openflow_13.OfpBucket{
107 Weight: uint32(bucket.Weight),
108 WatchPort: uint32(bucket.WatchPort),
109 WatchGroup: bucket.WatchGroup,
110 Actions: openflowActionsToVoltha(bucket.Actions),
111 }
112 outBuckets[i] = b
113 }
114
115 return outBuckets
116}
117
118func openflowActionsToVoltha(actions []goloxi.IAction) []*openflow_13.OfpAction {
119 outActions := make([]*openflow_13.OfpAction, len(actions))
120
121 for i, action := range actions {
122 outActions[i] = extractAction(action)
123 }
124
125 return outActions
126}
127
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100128func volthaBucketsToOpenflow(ctx context.Context, buckets []*openflow_13.OfpBucket) ([]*ofp.Bucket, error) {
Jonathan Hart60c5d772020-03-30 18:28:40 -0700129 outBuckets := make([]*ofp.Bucket, len(buckets))
130
131 for i, bucket := range buckets {
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100132 actions, err := volthaActionsToOpenflow(ctx, bucket.Actions)
133 if err != nil {
134 return nil, err
135 }
Jonathan Hart60c5d772020-03-30 18:28:40 -0700136 b := &ofp.Bucket{
Jonathan Hart60c5d772020-03-30 18:28:40 -0700137 Weight: uint16(bucket.Weight),
138 WatchPort: ofp.Port(bucket.WatchPort),
139 WatchGroup: bucket.WatchGroup,
140 Actions: actions,
141 }
142 outBuckets[i] = b
143 }
144
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100145 return outBuckets, nil
Jonathan Hart60c5d772020-03-30 18:28:40 -0700146}
147
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100148func volthaActionsToOpenflow(ctx context.Context, actions []*openflow_13.OfpAction) ([]goloxi.IAction, error) {
Jonathan Hart60c5d772020-03-30 18:28:40 -0700149 outActions := make([]goloxi.IAction, len(actions))
150
Jonathan Hart60c5d772020-03-30 18:28:40 -0700151 for i, action := range actions {
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100152 outAction, err := parseAction(ctx, action)
153 if err == nil {
154 outActions[i] = outAction
155 } else {
156 return nil, fmt.Errorf("can't-parse-action %v", err)
157 }
158
Jonathan Hart60c5d772020-03-30 18:28:40 -0700159 }
160
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100161 return outActions, nil
Jonathan Hart60c5d772020-03-30 18:28:40 -0700162}