blob: 73258aca90c6127767743e1a14b2904cc2749173 [file] [log] [blame]
Jian Li6bd35102018-06-09 00:18:47 +09001/*
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 org.onosproject.openstacktelemetry.codec;
17
18import org.onlab.packet.IpAddress;
19import org.onlab.packet.IpAddress.Version;
20import org.onlab.packet.IpPrefix;
21import org.onlab.packet.MacAddress;
22import org.onlab.packet.TpPort;
23import org.onlab.packet.VlanId;
24import org.onosproject.net.DeviceId;
25import org.onosproject.openstacktelemetry.api.ByteBufferCodec;
26import org.onosproject.openstacktelemetry.api.FlowInfo;
27import org.onosproject.openstacktelemetry.api.StatsInfo;
28import org.onosproject.openstacktelemetry.impl.DefaultFlowInfo;
29
30import java.nio.ByteBuffer;
31
32/**
33 * FlowInfo ByteBuffer Codec.
34 */
35public class TinaFlowInfoByteBufferCodec extends ByteBufferCodec<FlowInfo> {
36
37 private static final int MESSAGE_SIZE = 88;
Jian Li0bbbb1c2018-06-22 22:01:17 +090038 private static final String OF_PREFIX = "of:";
Jian Li6bd35102018-06-09 00:18:47 +090039
40 @Override
41 public ByteBuffer encode(FlowInfo flowInfo) {
42
43 ByteBuffer byteBuffer = ByteBuffer.allocate(MESSAGE_SIZE);
Jian Li85573f42018-06-27 22:29:14 +090044 int srcPort = 0;
45 int dstPort = 0;
Jian Li6bd35102018-06-09 00:18:47 +090046
Jian Li0bbbb1c2018-06-22 22:01:17 +090047 String deviceId = flowInfo.deviceId().toString();
48 short switchId = (short) Integer.parseInt(deviceId.substring(3,
49 deviceId.length()), 16);
50
Jian Li85573f42018-06-27 22:29:14 +090051 if (flowInfo.srcPort() != null) {
52 srcPort = flowInfo.srcPort().toInt();
53 }
54
55 if (flowInfo.dstPort() != null) {
56 dstPort = flowInfo.dstPort().toInt();
57 }
58
Jian Li6bd35102018-06-09 00:18:47 +090059 byteBuffer.put(flowInfo.flowType())
Jian Li0bbbb1c2018-06-22 22:01:17 +090060 .putShort(switchId)
Jian Li6bd35102018-06-09 00:18:47 +090061 .putInt(flowInfo.inputInterfaceId())
62 .putInt(flowInfo.outputInterfaceId())
63 .putShort(flowInfo.vlanId().toShort())
64 .put(flowInfo.srcIp().address().toOctets())
65 .put((byte) flowInfo.srcIp().prefixLength())
Jian Li85573f42018-06-27 22:29:14 +090066 .putShort((short) srcPort)
Jian Li6bd35102018-06-09 00:18:47 +090067 .put(flowInfo.dstIp().address().toOctets())
68 .put((byte) flowInfo.dstIp().prefixLength())
Jian Li85573f42018-06-27 22:29:14 +090069 .putShort((short) dstPort)
Jian Li6bd35102018-06-09 00:18:47 +090070 .put(flowInfo.protocol())
71 .put(flowInfo.srcMac().toBytes())
72 .put(flowInfo.dstMac().toBytes());
73
74 TinaStatsInfoByteBufferCodec statsInfoByteBufferCodec =
75 new TinaStatsInfoByteBufferCodec();
76 byteBuffer.put(statsInfoByteBufferCodec.encode(flowInfo.statsInfo()).array());
77
78 return byteBuffer;
79 }
80
81 @Override
82 public FlowInfo decode(ByteBuffer byteBuffer) {
83
84 byte flowType = byteBuffer.get();
Jian Li0bbbb1c2018-06-22 22:01:17 +090085 String deviceIdStr = String.format("%016x", byteBuffer.getShort());
86 DeviceId deviceId = DeviceId.deviceId(OF_PREFIX + deviceIdStr);
Jian Li6bd35102018-06-09 00:18:47 +090087 int inputInterfaceId = byteBuffer.getInt();
88 int outputInterfaceId = byteBuffer.getInt();
89 VlanId vlanId = VlanId.vlanId(byteBuffer.getShort());
90 IpAddress srcIp = IpAddress.valueOf(Version.INET, getIpv4Octets(byteBuffer));
91 int srcPrefixLen = byteBuffer.get();
92 TpPort srcPort = TpPort.tpPort((int) byteBuffer.getShort());
93 IpAddress dstIp = IpAddress.valueOf(Version.INET, getIpv4Octets(byteBuffer));
94 int dstPrefixLen = byteBuffer.get();
95 TpPort dstPort = TpPort.tpPort((int) byteBuffer.getShort());
96
97 byte protocol = byteBuffer.get();
98 MacAddress srcMac = MacAddress.valueOf(getMacByteArray(byteBuffer));
99 MacAddress dstMac = MacAddress.valueOf(getMacByteArray(byteBuffer));
100
101 TinaStatsInfoByteBufferCodec statsInfoByteBufferCodec =
102 new TinaStatsInfoByteBufferCodec();
103 StatsInfo statsInfo = statsInfoByteBufferCodec.decode(byteBuffer);
104
105 return new DefaultFlowInfo.DefaultBuilder()
106 .withFlowType(flowType)
107 .withDeviceId(deviceId)
108 .withInputInterfaceId(inputInterfaceId)
109 .withOutputInterfaceId(outputInterfaceId)
110 .withVlanId(vlanId)
111 .withSrcIp(IpPrefix.valueOf(srcIp, srcPrefixLen))
112 .withSrcPort(srcPort)
113 .withDstIp(IpPrefix.valueOf(dstIp, dstPrefixLen))
114 .withDstPort(dstPort)
115 .withProtocol(protocol)
116 .withSrcMac(srcMac)
117 .withDstMac(dstMac)
118 .withStatsInfo(statsInfo)
119 .build();
120 }
121
122 /**
123 * Obtains IPv4 Octets from ByteBuffer.
124 *
125 * @param buffer byte buffer
126 * @return Ipv4 Octets
127 */
128 private byte[] getIpv4Octets(ByteBuffer buffer) {
129 byte[] octets = new byte[4];
130 for (int i = 0; i < octets.length; i++) {
131 octets[i] = buffer.get();
132 }
133 return octets;
134 }
135
136 /**
137 * Obtains MAC address byte array from ByteBuffer.
138 *
139 * @param buffer byte buffer
140 * @return MAC address byte array
141 */
142 private byte[] getMacByteArray(ByteBuffer buffer) {
143 byte[] array = new byte[6];
144 for (int i = 0; i < array.length; i++) {
145 array[i] = buffer.get();
146 }
147 return array;
148 }
149}