blob: 30253c64ab7f755668c0fd1b2e679ea2a510f9f6 [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"
Jonathan Hart828908c2020-04-15 14:23:45 -070022 "github.com/opencord/goloxi"
23 ofp "github.com/opencord/goloxi/of13"
Andrea Campanella18448bc2021-07-08 18:47:22 +020024 "github.com/opencord/voltha-lib-go/v5/pkg/log"
Maninder12b909f2020-10-23 14:23:36 +053025 "github.com/opencord/voltha-protos/v4/go/openflow_13"
26 "github.com/opencord/voltha-protos/v4/go/voltha"
Jonathan Hart60c5d772020-03-30 18:28:40 -070027)
28
Rohan Agrawalc32d9932020-06-15 11:01:47 +000029func (ofc *OFConnection) handleGroupMod(ctx context.Context, groupMod ofp.IGroupMod) {
Girish Kumar01e0c632020-08-10 16:48:56 +000030 span, ctx := log.CreateChildSpan(ctx, "openflow-group-modification")
31 defer span.Finish()
Jonathan Hart60c5d772020-03-30 18:28:40 -070032
33 volthaClient := ofc.VolthaClient.Get()
34 if volthaClient == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000035 logger.Errorw(ctx, "no-voltha-connection",
Jonathan Hart60c5d772020-03-30 18:28:40 -070036 log.Fields{"device-id": ofc.DeviceID})
37 return
38 }
39
40 groupUpdate := &openflow_13.FlowGroupTableUpdate{
41 Id: ofc.DeviceID,
42 GroupMod: &voltha.OfpGroupMod{
Rohan Agrawalc32d9932020-06-15 11:01:47 +000043 Command: openflowGroupModCommandToVoltha(ctx, groupMod.GetCommand()),
44 Type: openflowGroupTypeToVoltha(ctx, groupMod.GetGroupType()),
Jonathan Hart60c5d772020-03-30 18:28:40 -070045 GroupId: groupMod.GetGroupId(),
46 Buckets: openflowBucketsToVoltha(groupMod.GetBuckets()),
47 },
48 }
49
Girish Kumar01e0c632020-08-10 16:48:56 +000050 _, err := volthaClient.UpdateLogicalDeviceFlowGroupTable(log.WithSpanFromContext(context.Background(), ctx), groupUpdate)
Jonathan Hart60c5d772020-03-30 18:28:40 -070051 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000052 logger.Errorw(ctx, "Error updating group table",
Jonathan Hart60c5d772020-03-30 18:28:40 -070053 log.Fields{"device-id": ofc.DeviceID, "error": err})
54 }
55
56}
57
Rohan Agrawalc32d9932020-06-15 11:01:47 +000058func openflowGroupModCommandToVoltha(ctx context.Context, command ofp.GroupModCommand) openflow_13.OfpGroupModCommand {
Jonathan Hart60c5d772020-03-30 18:28:40 -070059 switch command {
60 case ofp.OFPGCAdd:
61 return openflow_13.OfpGroupModCommand_OFPGC_ADD
62 case ofp.OFPGCModify:
63 return openflow_13.OfpGroupModCommand_OFPGC_MODIFY
64 case ofp.OFPGCDelete:
65 return openflow_13.OfpGroupModCommand_OFPGC_DELETE
66 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +000067 logger.Errorw(ctx, "Unknown group mod command", log.Fields{"command": command})
Jonathan Hart60c5d772020-03-30 18:28:40 -070068 return 0
69}
70
Rohan Agrawalc32d9932020-06-15 11:01:47 +000071func openflowGroupTypeToVoltha(ctx context.Context, t ofp.GroupType) openflow_13.OfpGroupType {
Jonathan Hart60c5d772020-03-30 18:28:40 -070072 switch t {
73 case ofp.OFPGTAll:
74 return openflow_13.OfpGroupType_OFPGT_ALL
75 case ofp.OFPGTSelect:
76 return openflow_13.OfpGroupType_OFPGT_SELECT
77 case ofp.OFPGTIndirect:
78 return openflow_13.OfpGroupType_OFPGT_INDIRECT
79 case ofp.OFPGTFf:
80 return openflow_13.OfpGroupType_OFPGT_FF
81 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +000082 logger.Errorw(ctx, "Unknown openflow group type", log.Fields{"type": t})
Jonathan Hart60c5d772020-03-30 18:28:40 -070083 return 0
84}
85
Rohan Agrawalc32d9932020-06-15 11:01:47 +000086func volthaGroupTypeToOpenflow(ctx context.Context, t openflow_13.OfpGroupType) ofp.GroupType {
Jonathan Hart60c5d772020-03-30 18:28:40 -070087 switch t {
88 case openflow_13.OfpGroupType_OFPGT_ALL:
89 return ofp.OFPGTAll
90 case openflow_13.OfpGroupType_OFPGT_SELECT:
91 return ofp.OFPGTSelect
92 case openflow_13.OfpGroupType_OFPGT_INDIRECT:
93 return ofp.OFPGTIndirect
94 case openflow_13.OfpGroupType_OFPGT_FF:
95 return ofp.OFPGTFf
96 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +000097 logger.Errorw(ctx, "Unknown voltha group type", log.Fields{"type": t})
Jonathan Hart60c5d772020-03-30 18:28:40 -070098 return 0
99}
100
101func openflowBucketsToVoltha(buckets []*ofp.Bucket) []*openflow_13.OfpBucket {
102 outBuckets := make([]*openflow_13.OfpBucket, len(buckets))
103
104 for i, bucket := range buckets {
105 b := &openflow_13.OfpBucket{
106 Weight: uint32(bucket.Weight),
107 WatchPort: uint32(bucket.WatchPort),
108 WatchGroup: bucket.WatchGroup,
109 Actions: openflowActionsToVoltha(bucket.Actions),
110 }
111 outBuckets[i] = b
112 }
113
114 return outBuckets
115}
116
117func openflowActionsToVoltha(actions []goloxi.IAction) []*openflow_13.OfpAction {
118 outActions := make([]*openflow_13.OfpAction, len(actions))
119
120 for i, action := range actions {
121 outActions[i] = extractAction(action)
122 }
123
124 return outActions
125}
126
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100127func volthaBucketsToOpenflow(ctx context.Context, buckets []*openflow_13.OfpBucket) ([]*ofp.Bucket, error) {
Jonathan Hart60c5d772020-03-30 18:28:40 -0700128 outBuckets := make([]*ofp.Bucket, len(buckets))
129
130 for i, bucket := range buckets {
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100131 actions, err := volthaActionsToOpenflow(ctx, bucket.Actions)
132 if err != nil {
133 return nil, err
134 }
Jonathan Hart60c5d772020-03-30 18:28:40 -0700135 b := &ofp.Bucket{
Jonathan Hart60c5d772020-03-30 18:28:40 -0700136 Weight: uint16(bucket.Weight),
137 WatchPort: ofp.Port(bucket.WatchPort),
138 WatchGroup: bucket.WatchGroup,
139 Actions: actions,
140 }
141 outBuckets[i] = b
142 }
143
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100144 return outBuckets, nil
Jonathan Hart60c5d772020-03-30 18:28:40 -0700145}
146
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100147func volthaActionsToOpenflow(ctx context.Context, actions []*openflow_13.OfpAction) ([]goloxi.IAction, error) {
Jonathan Hart60c5d772020-03-30 18:28:40 -0700148 outActions := make([]goloxi.IAction, len(actions))
149
Jonathan Hart60c5d772020-03-30 18:28:40 -0700150 for i, action := range actions {
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100151 outAction, err := parseAction(ctx, action)
152 if err == nil {
153 outActions[i] = outAction
154 } else {
155 return nil, fmt.Errorf("can't-parse-action %v", err)
156 }
157
Jonathan Hart60c5d772020-03-30 18:28:40 -0700158 }
159
Andrea Campanella22aa3ed2021-03-04 15:58:55 +0100160 return outActions, nil
Jonathan Hart60c5d772020-03-30 18:28:40 -0700161}