blob: 6907d4ba198b22c1802d2b14a9b96f1922570881 [file] [log] [blame]
Jian Li26ef1302018-07-04 14:37:06 +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.openstackvtap.util;
17
18import org.onlab.packet.IPv4;
Jimo Jung14e87bf2018-09-03 16:28:13 +090019import org.onlab.packet.IpAddress;
20import org.onlab.packet.IpPrefix;
Jian Li516c0e32019-10-23 14:05:32 +090021import org.onlab.packet.TpPort;
Jimo Jung14e87bf2018-09-03 16:28:13 +090022import org.onosproject.net.Host;
23import org.onosproject.net.behaviour.TunnelDescription;
Jian Li26ef1302018-07-04 14:37:06 +090024import org.onosproject.net.group.DefaultGroupKey;
25import org.onosproject.net.group.GroupKey;
26import org.onosproject.openstackvtap.api.OpenstackVtap;
Jimo Jung14e87bf2018-09-03 16:28:13 +090027import org.onosproject.openstackvtap.api.OpenstackVtapCriterion;
28import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
Jian Li516c0e32019-10-23 14:05:32 +090029import org.onosproject.openstackvtap.impl.DefaultOpenstackVtapCriterion;
Jimo Jung14e87bf2018-09-03 16:28:13 +090030import org.slf4j.Logger;
Jian Li516c0e32019-10-23 14:05:32 +090031import org.slf4j.LoggerFactory;
Jimo Jung14e87bf2018-09-03 16:28:13 +090032
33import java.io.ByteArrayOutputStream;
Jimo Jung14e87bf2018-09-03 16:28:13 +090034import java.nio.charset.StandardCharsets;
35
36import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_NETWORK_ID;
37import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_PORT_ID;
Jian Li26ef1302018-07-04 14:37:06 +090038
39/**
Jimo Jung14e87bf2018-09-03 16:28:13 +090040 * An utilities that used in openstack vtap app.
Jian Li26ef1302018-07-04 14:37:06 +090041 */
42public final class OpenstackVtapUtil {
43
Jian Li516c0e32019-10-23 14:05:32 +090044 private static final Logger log = LoggerFactory.getLogger(OpenstackVtapUtil.class);
45
Jimo Jung14e87bf2018-09-03 16:28:13 +090046 private static final String VTAP_TUNNEL_GRE = "vtap_gre";
47 private static final String VTAP_TUNNEL_VXLAN = "vtap_vxlan";
Jian Li26ef1302018-07-04 14:37:06 +090048 private static final String VTAP_GROUP_KEY = "VTAP_GROUP_KEY";
49
50 /**
51 * Prevents object instantiation from external.
52 */
53 private OpenstackVtapUtil() {
54 }
55
56 /**
Jian Li26ef1302018-07-04 14:37:06 +090057 * Obtains IP protocol type from the given string.
58 *
Jimo Jung14e87bf2018-09-03 16:28:13 +090059 * @param str protocol string
60 * @return IP protocol number
Jian Li26ef1302018-07-04 14:37:06 +090061 */
62 public static byte getProtocolTypeFromString(String str) {
63 switch (str) {
64 case "tcp":
65 return IPv4.PROTOCOL_TCP;
66 case "udp":
67 return IPv4.PROTOCOL_UDP;
68 case "icmp":
69 return IPv4.PROTOCOL_ICMP;
Jimo Jung14e87bf2018-09-03 16:28:13 +090070 case "any":
Jian Li26ef1302018-07-04 14:37:06 +090071 return 0;
Jimo Jung14e87bf2018-09-03 16:28:13 +090072 default:
73 throw new IllegalArgumentException("Invalid vtap protocol string");
Jian Li26ef1302018-07-04 14:37:06 +090074 }
75 }
76
Jimo Jung14e87bf2018-09-03 16:28:13 +090077 /**
Jian Li516c0e32019-10-23 14:05:32 +090078 * Obtains IP protocol string from the given type.
79 *
80 * @param type protocol type
81 * @return IP protocol string
82 */
83 public static String getProtocolStringFromType(byte type) {
84 switch (type) {
85 case IPv4.PROTOCOL_TCP:
86 return "tcp";
87 case IPv4.PROTOCOL_UDP:
88 return "udp";
89 case IPv4.PROTOCOL_ICMP:
90 return "icmp";
91 case 0:
92 return "any";
93 default:
94 throw new IllegalArgumentException("Invalid vtap protocol type");
95 }
96 }
97
98 /**
Jimo Jung14e87bf2018-09-03 16:28:13 +090099 * Obtains openstack vtap type from the given string.
100 *
101 * @param str vtap type string
102 * @return vtap type
103 */
104 public static OpenstackVtap.Type getVtapTypeFromString(String str) {
105 switch (str) {
106 case "all":
107 return OpenstackVtap.Type.VTAP_ALL;
108 case "rx":
109 return OpenstackVtap.Type.VTAP_RX;
110 case "tx":
111 return OpenstackVtap.Type.VTAP_TX;
112 case "any":
113 return OpenstackVtap.Type.VTAP_ANY;
114 default:
115 throw new IllegalArgumentException("Invalid vtap type string");
116 }
117 }
118
119 /**
120 * Checks whether the given IP address is included in vtap criterion with
121 * TX and RX directions by given vtap type.
122 *
123 * @param type vtap type
124 * @param criterion vtap criterion
125 * @param ip IP address to check
126 * @return true on match address, false otherwise
127 */
128 public static boolean containsIp(OpenstackVtap.Type type, OpenstackVtapCriterion criterion, IpAddress ip) {
129 boolean isTxEdge = type.isValid(OpenstackVtap.Type.VTAP_TX) &&
130 criterion.srcIpPrefix().contains(ip);
131 boolean isRxEdge = type.isValid(OpenstackVtap.Type.VTAP_RX) &&
132 criterion.dstIpPrefix().contains(ip);
133 return isTxEdge || isRxEdge;
134 }
135
136 /**
137 * Checks the host validation from annotation information.
138 *
139 * @param host host to check
140 * @return true on validate, false otherwise
141 */
142 public static boolean isValidHost(Host host) {
143 return !host.ipAddresses().isEmpty() &&
144 host.annotations().value(ANNOTATION_NETWORK_ID) != null &&
145 host.annotations().value(ANNOTATION_PORT_ID) != null;
146 }
147
148 /**
149 * Checks whether the given IP prefix is contained in the first host rather
150 * than in the second host.
151 *
152 * @param host1 first host instance
153 * @param host2 second host instance
154 * @param ipPrefix IP prefix to be looked up
155 * @return a negative integer, zero, or a positive integer as the
156 * first argument is less than, equal to, or greater than the
157 * second.
158 */
159 public static int hostCompareIp(Host host1, Host host2, IpPrefix ipPrefix) {
160 if ((host1 == null || host1.ipAddresses().stream().noneMatch(ipPrefix::contains)) &&
Ray Milkey90ca2972019-01-25 09:50:16 -0800161 (host2 == null || host2.ipAddresses().stream().anyMatch(ipPrefix::contains))) {
Jimo Jung14e87bf2018-09-03 16:28:13 +0900162 return -1;
163 } else if ((host1 != null && host1.ipAddresses().stream().anyMatch(ipPrefix::contains)) &&
164 (host2 == null || host2.ipAddresses().stream().noneMatch(ipPrefix::contains))) {
165 return 1;
166 }
167 return 0;
168 }
169
170 /**
171 * Obtains flow group key from the given id.
172 *
173 * @param groupId flow group identifier
174 * @return flow group key
175 */
Jian Li26ef1302018-07-04 14:37:06 +0900176 public static GroupKey getGroupKey(int groupId) {
177 return new DefaultGroupKey((VTAP_GROUP_KEY + Integer.toString(groupId)).getBytes());
178 }
Jimo Jung14e87bf2018-09-03 16:28:13 +0900179
180 /**
181 * Obtains tunnel interface name from the given openstack vtap network mode.
182 *
183 * @param mode vtap network mode
184 * @return tunnel interface name
185 */
186 public static String getTunnelName(OpenstackVtapNetwork.Mode mode) {
187 switch (mode) {
188 case GRE:
189 return VTAP_TUNNEL_GRE;
190 case VXLAN:
191 return VTAP_TUNNEL_VXLAN;
192 default:
193 return null;
194 }
195 }
196
197 /**
198 * Obtains tunnel description type from the given openstack vtap network mode.
199 *
200 * @param mode vtap network mode
201 * @return tunnel description type
202 */
203 public static TunnelDescription.Type getTunnelType(OpenstackVtapNetwork.Mode mode) {
204 return TunnelDescription.Type.valueOf(mode.toString());
205 }
206
207 /**
Jian Li516c0e32019-10-23 14:05:32 +0900208 * Makes Openstack vTap criterion from the given src, dst IP and port.
209 *
210 * @param srcIp source IP address
211 * @param dstIp destination IP address
212 * @param ipProto IP protocol
213 * @param srcPort source port
214 * @param dstPort destination port
215 * @return openstack vTap criterion
216 */
217 public static OpenstackVtapCriterion makeVtapCriterion(String srcIp,
218 String dstIp,
219 String ipProto,
220 int srcPort,
221 int dstPort) {
222 OpenstackVtapCriterion.Builder cBuilder = DefaultOpenstackVtapCriterion.builder();
223
224 try {
225 cBuilder.srcIpPrefix(IpPrefix.valueOf(srcIp));
226 cBuilder.dstIpPrefix(IpPrefix.valueOf(dstIp));
227 } catch (Exception e) {
228 log.error("The given IP addresses are invalid");
229 }
230
231 cBuilder.ipProtocol(getProtocolTypeFromString(ipProto.toLowerCase()));
232
233 cBuilder.srcTpPort(TpPort.tpPort(srcPort));
234 cBuilder.dstTpPort(TpPort.tpPort(dstPort));
235
236 return cBuilder.build();
237 }
238
239 /**
Jimo Jung14e87bf2018-09-03 16:28:13 +0900240 * Print stack trace of given exception.
241 *
242 * @param log logger for using print
243 * @param e exception to print
244 */
245 public static void dumpStackTrace(Logger log, Exception e) {
246 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Jimo Jung14e87bf2018-09-03 16:28:13 +0900247 log.error("\n{}", new String(outputStream.toByteArray(), StandardCharsets.UTF_8));
248 }
249
Jian Li26ef1302018-07-04 14:37:06 +0900250}