2 * Copyright (c) 2013, 2015 IBM Corporation and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowplugin.openflow.md.util;
11 import java.math.BigInteger;
12 import java.util.Objects;
13 import org.opendaylight.openflowplugin.api.OFConstants;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
16 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flow.FlowConvertor;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
30 public final class FlowCreatorUtil {
32 * Default FLOW_MOD flags.
34 public static final FlowModFlags DEFAULT_FLOW_MOD_FLAGS =
35 new FlowModFlags(FlowConvertor.DEFAULT_OFPFF_CHECK_OVERLAP,
36 FlowConvertor.DEFAULT_OFPFF_NO_BYT_COUNTS,
37 FlowConvertor.DEFAULT_OFPFF_NO_PKT_COUNTS,
38 FlowConvertor.DEFAULT_OFPFF_RESET_COUNTS,
39 FlowConvertor.DEFAULT_OFPFF_FLOW_REM);
41 private FlowCreatorUtil() {
42 throw new AssertionError("FlowCreatorUtil is not expected to be instantiated.");
45 public static void setWildcardedFlowMatch(short version, MultipartRequestFlowBuilder flowBuilder) {
46 if (version == OFConstants.OFP_VERSION_1_0) {
47 flowBuilder.setMatchV10(createWildcardedMatchV10());
49 if (version == OFConstants.OFP_VERSION_1_3) {
50 flowBuilder.setMatch(createWildcardedMatch());
54 public static void setWildcardedFlowMatch(short version, MultipartRequestAggregateBuilder aggregateBuilder) {
55 if (version == OFConstants.OFP_VERSION_1_0) {
56 aggregateBuilder.setMatchV10(createWildcardedMatchV10());
58 if (version == OFConstants.OFP_VERSION_1_3) {
59 aggregateBuilder.setMatch(createWildcardedMatch());
64 * Method creates openflow 1.0 format match, that can match all the flow entries.
66 * @return V10 Match object
68 public static MatchV10 createWildcardedMatchV10() {
69 MatchV10Builder builder = new MatchV10Builder();
70 builder.setWildcards(new FlowWildcardsV10(true, true, true, true,
71 true, true, true, true, true, true));
72 builder.setNwSrcMask((short) 0);
73 builder.setNwDstMask((short) 0);
75 builder.setDlSrc(new MacAddress("00:00:00:00:00:00"));
76 builder.setDlDst(new MacAddress("00:00:00:00:00:00"));
78 builder.setDlVlanPcp((short) 0);
80 builder.setNwTos((short) 0);
81 builder.setNwProto((short) 0);
82 builder.setNwSrc(new Ipv4Address("0.0.0.0"));
83 builder.setNwDst(new Ipv4Address("0.0.0.0"));
86 return builder.build();
89 public static Match createWildcardedMatch() {
90 return new MatchBuilder().setType(OxmMatchType.class).build();
94 * Determine whether a flow entry can be modified or not.
96 * @param original An original flow entry.
97 * @param updated An updated flow entry.
98 * @param version Protocol version.
99 * @return {@code true} only if a flow entry can be modified.
101 public static boolean canModifyFlow(OriginalFlow original,
102 UpdatedFlow updated, Short version) {
103 // FLOW_MOD does not change match, priority, idle_timeout, hard_timeout,
104 // flags, and cookie.
105 if (!Objects.equals(original.getMatch(), updated.getMatch()) ||
106 !equalsWithDefault(original.getPriority(), updated.getPriority(),
107 FlowConvertor.DEFAULT_PRIORITY) ||
108 !equalsWithDefault(original.getIdleTimeout(),
109 updated.getIdleTimeout(),
110 FlowConvertor.DEFAULT_IDLE_TIMEOUT) ||
111 !equalsWithDefault(original.getHardTimeout(),
112 updated.getHardTimeout(),
113 FlowConvertor.DEFAULT_HARD_TIMEOUT) ||
114 !equalsFlowModFlags(original.getFlags(), updated.getFlags())) {
118 if (!Boolean.TRUE.equals(updated.isStrict()) &&
120 version.shortValue() != OFConstants.OFP_VERSION_1_0) {
121 FlowCookie cookieMask = updated.getCookieMask();
122 if (cookieMask != null) {
123 BigInteger mask = cookieMask.getValue();
124 if (mask != null && !mask.equals(BigInteger.ZERO)) {
125 // Allow FLOW_MOD with filtering by cookie.
131 FlowCookie oc = original.getCookie();
132 FlowCookie uc = updated.getCookie();
133 BigInteger orgCookie;
134 BigInteger updCookie;
140 orgCookie = OFConstants.DEFAULT_COOKIE;
141 updCookie = uc.getValue();
143 orgCookie = oc.getValue();
144 updCookie = (uc == null)
145 ? OFConstants.DEFAULT_COOKIE : uc.getValue();
148 return equalsWithDefault(orgCookie, updCookie,
149 OFConstants.DEFAULT_COOKIE);
153 * Return {@code true} only if given two FLOW_MOD flags are identical.
155 * @param flags1 A value to be compared.
156 * @param flags2 A value to be compared.
158 * {@code true} only if {@code flags1} and {@code flags2} are identical.
160 public static boolean equalsFlowModFlags(FlowModFlags flags1,
161 FlowModFlags flags2) {
164 if (flags1 == null) {
165 if (flags2 == null) {
169 f1 = DEFAULT_FLOW_MOD_FLAGS;
173 f2 = (flags2 == null) ? DEFAULT_FLOW_MOD_FLAGS : flags2;
176 return equalsWithDefault(f1.isCHECKOVERLAP(), f2.isCHECKOVERLAP(),
178 equalsWithDefault(f1.isNOBYTCOUNTS(), f2.isNOBYTCOUNTS(),
180 equalsWithDefault(f1.isNOPKTCOUNTS(), f2.isNOPKTCOUNTS(),
182 equalsWithDefault(f1.isRESETCOUNTS(), f2.isRESETCOUNTS(),
184 equalsWithDefault(f1.isSENDFLOWREM(), f2.isSENDFLOWREM(),
189 * Return {@code true} only if given two values are identical.
191 * @param value1 A value to be compared.
192 * @param value2 A value to be compared.
194 * Default value. This value is used if {@code null} is passed to
195 * {@code value1} or {@code value2}.
196 * @param <T> Type of values.
198 * {@code true} only if {@code value1} and {@code value2} are identical.
200 public static <T> boolean equalsWithDefault(T value1, T value2, T def) {
201 if (value1 == null) {
202 return value2 == null || value2.equals(def);
203 } else if (value2 == null) {
204 return value1.equals(def);
207 return value1.equals(value2);