2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
\r
4 * This program and the accompanying materials are made available under the
\r
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
\r
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
\r
9 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
\r
11 import static com.google.common.base.Preconditions.checkNotNull;
\r
13 import java.util.ArrayList;
\r
14 import java.util.List;
\r
16 import javax.annotation.Nullable;
\r
18 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
\r
19 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
\r
20 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.EtherTypeClassifier;
\r
21 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.IpProtoClassifier;
\r
22 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.L4Classifier;
\r
23 import org.opendaylight.neutron.spi.NeutronSecurityRule;
\r
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef.ConnectionTracking;
\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraints;
\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;
\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;
\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraint;
\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;
\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValueBuilder;
\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchers;
\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;
\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstanceBuilder;
\r
50 import com.google.common.base.Strings;
\r
51 import com.google.common.collect.ImmutableList;
\r
53 public class SecRuleEntityDecoder {
\r
55 private SecRuleEntityDecoder() {
\r
56 throw new UnsupportedOperationException("Cannot create an instace.");
\r
59 public static TenantId getTenantId(NeutronSecurityRule secRule) {
\r
60 return new TenantId(Utils.normalizeUuid(secRule.getSecurityRuleTenantID()));
\r
63 public static EndpointGroupId getProviderEpgId(NeutronSecurityRule secRule) {
\r
64 return new EndpointGroupId(Utils.normalizeUuid(secRule.getSecurityRuleGroupID()));
\r
68 * @return {@code null} if {@link NeutronSecurityRule#getSecurityRemoteGroupID()} is null
\r
70 public static @Nullable EndpointGroupId getConsumerEpgId(NeutronSecurityRule secRule) {
\r
71 if (Strings.isNullOrEmpty(secRule.getSecurityRemoteGroupID())) {
\r
74 return new EndpointGroupId(Utils.normalizeUuid(secRule.getSecurityRemoteGroupID()));
\r
77 public static ContractId getContractId(NeutronSecurityRule secRule) {
\r
78 return new ContractId(Utils.normalizeUuid(secRule.getSecurityRuleUUID()));
\r
81 public static ClassifierInstance getClassifierInstance(NeutronSecurityRule secRule) {
\r
82 ClassifierInstanceBuilder classifierBuilder = new ClassifierInstanceBuilder();
\r
83 List<ParameterValue> params = new ArrayList<>();
\r
84 Integer portMin = secRule.getSecurityRulePortMin();
\r
85 Integer portMax = secRule.getSecurityRulePortMax();
\r
86 if (portMin != null && portMax != null) {
\r
87 classifierBuilder.setClassifierDefinitionId(L4Classifier.DEFINITION.getId());
\r
88 if (portMin.equals(portMax)) {
\r
89 params.add(new ParameterValueBuilder().setName(new ParameterName(L4Classifier.DST_PORT_PARAM))
\r
90 .setIntValue(portMin.longValue())
\r
93 params.add(new ParameterValueBuilder().setName(new ParameterName(L4Classifier.DST_PORT_RANGE_PARAM))
\r
95 new RangeValueBuilder().setMin(portMin.longValue()).setMax(portMax.longValue()).build())
\r
99 Long protocol = getProtocol(secRule);
\r
100 if (protocol != null) {
\r
101 if (classifierBuilder.getClassifierDefinitionId() == null) {
\r
102 classifierBuilder.setClassifierDefinitionId(IpProtoClassifier.DEFINITION.getId());
\r
104 params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifier.PROTO_PARAM))
\r
105 .setIntValue(protocol)
\r
108 Long ethertype = getEtherType(secRule);
\r
109 if (ethertype != null) {
\r
110 if (classifierBuilder.getClassifierDefinitionId() == null) {
\r
111 classifierBuilder.setClassifierDefinitionId(EtherTypeClassifier.DEFINITION.getId());
\r
113 params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifier.ETHERTYPE_PARAM))
\r
114 .setIntValue(ethertype)
\r
117 ClassifierName classifierName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
\r
118 return classifierBuilder.setParameterValue(params).setName(new ClassifierName(classifierName)).build();
\r
121 public static ClassifierRef getClassifierRef(NeutronSecurityRule secRule) {
\r
122 checkNotNull(secRule);
\r
123 ClassifierName classifierInstanceName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
\r
124 ClassifierRefBuilder classifierRefBuilder = new ClassifierRefBuilder()
\r
125 .setConnectionTracking(ConnectionTracking.Reflexive).setInstanceName(classifierInstanceName);
\r
126 Direction direction = getDirection(secRule);
\r
127 classifierRefBuilder.setDirection(direction);
\r
128 ClassifierName classifierRefName = SecRuleNameDecoder.getClassifierRefName(secRule);
\r
129 return classifierRefBuilder.setName(classifierRefName).build();
\r
134 * @return direction resolved from {@link NeutronSecurityRule#getSecurityRuleDirection()}
\r
135 * @throws IllegalArgumentException if return value of
\r
136 * {@link NeutronSecurityRule#getSecurityRuleDirection()} is other than "ingress" or
\r
139 public static Direction getDirection(NeutronSecurityRule secRule) {
\r
140 String direction = secRule.getSecurityRuleDirection();
\r
141 if (NeutronUtils.INGRESS.equals(direction)) {
\r
142 return Direction.In;
\r
144 if (NeutronUtils.EGRESS.equals(direction)) {
\r
145 return Direction.Out;
\r
147 throw new IllegalArgumentException("Direction " + direction + " from security group rule "
\r
148 + secRule.getSecurityRuleUUID() + " is not supported. Direction can be only 'ingress' or 'egress'.");
\r
152 * @param secRule {@link NeutronSecurityRule#getSecurityRuleRemoteIpPrefix()} is used for EIC
\r
153 * and subject selection
\r
154 * @return clause with the subject and with a consumer matcher containing EIC
\r
156 public static Clause getClause(NeutronSecurityRule secRule) {
\r
157 checkNotNull(secRule);
\r
158 SubjectName subjectName = SecRuleNameDecoder.getSubjectName(secRule);
\r
159 ClauseBuilder clauseBuilder =
\r
160 new ClauseBuilder().setSubjectRefs(ImmutableList.of(subjectName)).setName(SecRuleNameDecoder.getClauseName(secRule));
\r
161 String remoteIpPrefix = secRule.getSecurityRuleRemoteIpPrefix();
\r
162 if (!Strings.isNullOrEmpty(remoteIpPrefix)) {
\r
163 clauseBuilder.setConsumerMatchers(createConsumerMatchersWithEic(remoteIpPrefix));
\r
165 return clauseBuilder.build();
\r
168 private static ConsumerMatchers createConsumerMatchersWithEic(String remoteIpPrefix) {
\r
169 IpPrefix ipPrefix = Utils.createIpPrefix(remoteIpPrefix);
\r
170 PrefixConstraint consumerPrefixConstraint = new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build();
\r
171 EndpointIdentificationConstraints eic =
\r
172 new EndpointIdentificationConstraintsBuilder()
\r
173 .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
\r
174 .setPrefixConstraint(ImmutableList.<PrefixConstraint>of(consumerPrefixConstraint)).build())
\r
176 return new ConsumerMatchersBuilder().setEndpointIdentificationConstraints(eic).build();
\r
179 public static boolean isEtherTypeOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {
\r
180 Long oneEtherType = getEtherType(one);
\r
181 Long twoEtherType = getEtherType(two);
\r
182 return twoIsNullOrEqualsOne(oneEtherType, twoEtherType);
\r
185 public static boolean isProtocolOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {
\r
186 Long oneProtocol = getProtocol(one);
\r
187 Long twoProtocol = getProtocol(two);
\r
188 return twoIsNullOrEqualsOne(oneProtocol, twoProtocol);
\r
191 private static <T> boolean twoIsNullOrEqualsOne(T one, T two) {
\r
194 if (two.equals(one))
\r
199 public static boolean isPortsOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {
\r
200 Integer onePortMin = one.getSecurityRulePortMin();
\r
201 Integer onePortMax = one.getSecurityRulePortMax();
\r
202 Integer twoPortMin = two.getSecurityRulePortMin();
\r
203 Integer twoPortMax = two.getSecurityRulePortMax();
\r
204 if (twoPortMin == null && twoPortMax == null) {
\r
207 if ((onePortMin != null && twoPortMin != null && onePortMin >= twoPortMin)
\r
208 && (onePortMax != null && twoPortMax != null && onePortMax <= twoPortMax)) {
\r
216 * @return {@code null} if {@link NeutronSecurityRule#getSecurityRuleEthertype()} is null or
\r
217 * empty; value of {@link EtherTypeClassifier#IPv4_VALUE} or
\r
218 * {@link EtherTypeClassifier#IPv6_VALUE}
\r
219 * @throws IllegalArgumentException if return value of
\r
220 * {@link NeutronSecurityRule#getSecurityRuleEthertype()} is not empty/null and is other
\r
221 * than "IPv4" or "IPv6"
\r
223 public static Long getEtherType(NeutronSecurityRule secRule) {
\r
224 String ethertype = secRule.getSecurityRuleEthertype();
\r
225 if (Strings.isNullOrEmpty(ethertype)) {
\r
228 if (NeutronUtils.IPv4.equals(ethertype)) {
\r
229 return EtherTypeClassifier.IPv4_VALUE;
\r
231 if (NeutronUtils.IPv6.equals(ethertype)) {
\r
232 return EtherTypeClassifier.IPv6_VALUE;
\r
234 throw new IllegalArgumentException("Ethertype " + ethertype + " is not supported.");
\r
239 * @return {@code null} if {@link NeutronSecurityRule#getSecurityRuleProtocol()} is null or
\r
240 * empty; Otherwise protocol number
\r
241 * @throws IllegalArgumentException if return value of
\r
242 * {@link NeutronSecurityRule#getSecurityRuleProtocol()} is not empty/null and is other
\r
243 * than "tcp", "udp", "icmp"
\r
245 public static Long getProtocol(NeutronSecurityRule secRule) {
\r
246 String protocol = secRule.getSecurityRuleProtocol();
\r
247 if (Strings.isNullOrEmpty(protocol)) {
\r
250 if (NeutronUtils.TCP.equals(protocol)) {
\r
251 return IpProtoClassifier.TCP_VALUE;
\r
253 if (NeutronUtils.UDP.equals(protocol)) {
\r
254 return IpProtoClassifier.UDP_VALUE;
\r
256 if (NeutronUtils.ICMP.equals(protocol)) {
\r
257 return IpProtoClassifier.ICMP_VALUE;
\r
259 throw new IllegalArgumentException("Protocol " + protocol + " is not supported.");
\r