blob: 721d1d72766b7cac6199421a05ac83011d96d603 [file] [log] [blame]
David K. Bainbridge157bdab2020-01-16 14:38:05 -08001/*
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 ofagent
18
19import (
20 "context"
21 "encoding/json"
22 "github.com/donNewtonAlpha/goloxi"
23 ofp "github.com/donNewtonAlpha/goloxi/of13"
24 "github.com/golang/protobuf/ptypes/empty"
25 "github.com/opencord/ofagent-go/internal/pkg/openflow"
26 "github.com/opencord/voltha-lib-go/v2/pkg/log"
27 "github.com/opencord/voltha-protos/v2/go/openflow_13"
28 "github.com/opencord/voltha-protos/v2/go/voltha"
29 "google.golang.org/grpc"
30)
31
32func (ofa *OFAgent) receivePacketsIn(ctx context.Context) {
33 logger.Debug("receive-packets-in-started")
34 opt := grpc.EmptyCallOption{}
35 streamCtx, streamDone := context.WithCancel(context.Background())
36 stream, err := ofa.volthaClient.ReceivePacketsIn(streamCtx, &empty.Empty{}, opt)
37 if err != nil {
38 logger.Errorw("Unable to establish Receive PacketIn Stream",
39 log.Fields{"error": err})
40 }
41 defer streamDone()
42
43 for {
44 select {
45 case <-ctx.Done():
46 return
47 default:
48 if pkt, err := stream.Recv(); err != nil {
49 logger.Errorw("error receiving packet",
50 log.Fields{"error": err})
51 ofa.events <- ofaEventVolthaDisconnected
52 } else {
53 ofa.packetInChannel <- pkt
54 }
55 }
56 }
57}
58
59func (ofa *OFAgent) handlePacketsIn(ctx context.Context) {
60 logger.Debug("handle-packets-in-started")
61 for {
62 select {
63 case <-ctx.Done():
64 return
65 case packet := <-ofa.packetInChannel:
66 packetIn := packet.GetPacketIn()
67
68 if logger.V(log.DebugLevel) {
69 js, _ := json.Marshal(packetIn)
70 logger.Debugw("packet-in recieved", log.Fields{"packet-in": js})
71 }
72 deviceID := packet.GetId()
73 ofPacketIn := ofp.NewPacketIn()
74 ofPacketIn.SetVersion(uint8(4))
75 ofPacketIn.SetXid(openflow.GetXid())
76 ofPacketIn.SetBufferId(packetIn.GetBufferId())
77 ofPacketIn.SetCookie(packetIn.GetCookie())
78 ofPacketIn.SetData(packetIn.GetData())
79 match := ofp.NewMatchV3()
80 inMatch := packetIn.GetMatch()
81 match.SetType(uint16(inMatch.GetType()))
82 //oxFields := inMatch.GetOxmFields()
83 var fields []goloxi.IOxm
84 size := uint16(4)
85 for _, oxmField := range inMatch.GetOxmFields() {
86 /*
87 for i := 0; i < len(oxFields); i++ {
88 oxmField := oxFields[i]
89 */
90 field := oxmField.GetField()
91 ofbField := field.(*openflow_13.OfpOxmField_OfbField).OfbField
92 size += 4 //header for oxm
93 switch ofbField.Type {
94 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
95 ofpInPort := ofp.NewOxmInPort()
96 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_Port)
97 ofpInPort.Value = ofp.Port(val.Port)
98 size += 4
99 fields = append(fields, ofpInPort)
100 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
101 ofpEthType := ofp.NewOxmEthType()
102 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_EthType)
103 ofpEthType.Value = ofp.EthernetType(val.EthType)
104 size += 2
105 fields = append(fields, ofpEthType)
106 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
107 ofpInPhyPort := ofp.NewOxmInPhyPort()
108 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_PhysicalPort)
109 ofpInPhyPort.Value = ofp.Port(val.PhysicalPort)
110 size += 4
111 fields = append(fields, ofpInPhyPort)
112 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
113 ofpIpProto := ofp.NewOxmIpProto()
114 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_IpProto)
115 ofpIpProto.Value = ofp.IpPrototype(val.IpProto)
116 size += 1
117 fields = append(fields, ofpIpProto)
118 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
119 ofpUdpSrc := ofp.NewOxmUdpSrc()
120 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpSrc)
121 ofpUdpSrc.Value = uint16(val.UdpSrc)
122 size += 2
123 fields = append(fields, ofpUdpSrc)
124 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
125 ofpUdpDst := ofp.NewOxmUdpDst()
126 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpDst)
127 ofpUdpDst.Value = uint16(val.UdpDst)
128 size += 2
129 fields = append(fields, ofpUdpDst)
130 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
131 ofpVlanVid := ofp.NewOxmVlanVid()
132 val := ofbField.GetValue()
133 if val != nil {
134 vlanId := val.(*openflow_13.OfpOxmOfbField_VlanVid)
135 ofpVlanVid.Value = uint16(vlanId.VlanVid) + 0x1000
136 size += 2
137 } else {
138 ofpVlanVid.Value = uint16(0)
139 }
140
141 fields = append(fields, ofpVlanVid)
142 default:
143 logger.Warnw("receive-packet-in:unhandled-oxm-field",
144 log.Fields{"field": ofbField.Type})
145 }
146 }
147 match.SetLength(size)
148
149 match.SetOxmList(fields)
150
151 ofPacketIn.SetMatch(*match)
152 ofPacketIn.SetReason(uint8(packetIn.GetReason()))
153 ofPacketIn.SetTableId(uint8(packetIn.GetTableId()))
154 ofPacketIn.SetTotalLen(uint16(len(ofPacketIn.GetData())))
155 ofc := ofa.getOFClient(deviceID)
156 ofc.SendMessage(ofPacketIn)
157
158 }
159 }
160}