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.api.sf.EtherTypeClassifierDefinition;
\r
19 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
\r
20 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
\r
21 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
\r
22 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
\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.policy.contract.Clause;
\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;
\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.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
67 public static @Nullable EndpointGroupId getConsumerEpgId(NeutronSecurityRule secRule) {
\r
68 if (Strings.isNullOrEmpty(secRule.getSecurityRemoteGroupID())) {
\r
71 return new EndpointGroupId(Utils.normalizeUuid(secRule.getSecurityRemoteGroupID()));
\r
74 public static ContractId getContractId(NeutronSecurityRule secRule) {
\r
75 return new ContractId(Utils.normalizeUuid(secRule.getSecurityRuleUUID()));
\r
78 public static ClassifierInstance getClassifierInstance(NeutronSecurityRule secRule) {
\r
79 ClassifierInstanceBuilder classifierBuilder = new ClassifierInstanceBuilder();
\r
80 List<ParameterValue> params = new ArrayList<>();
\r
81 Integer portMin = secRule.getSecurityRulePortMin();
\r
82 Integer portMax = secRule.getSecurityRulePortMax();
\r
83 if (portMin != null && portMax != null) {
\r
84 classifierBuilder.setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId());
\r
85 if (portMin.equals(portMax)) {
\r
86 params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM))
\r
87 .setIntValue(portMin.longValue())
\r
90 params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_RANGE_PARAM))
\r
92 new RangeValueBuilder().setMin(portMin.longValue()).setMax(portMax.longValue()).build())
\r
96 Long protocol = getProtocol(secRule);
\r
97 if (protocol != null) {
\r
98 if (classifierBuilder.getClassifierDefinitionId() == null) {
\r
99 classifierBuilder.setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId());
\r
101 params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM))
\r
102 .setIntValue(protocol)
\r
105 Long ethertype = getEtherType(secRule);
\r
106 if (ethertype != null) {
\r
107 if (classifierBuilder.getClassifierDefinitionId() == null) {
\r
108 classifierBuilder.setClassifierDefinitionId(EtherTypeClassifierDefinition.DEFINITION.getId());
\r
110 params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))
\r
111 .setIntValue(ethertype)
\r
114 ClassifierName classifierName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
\r
115 return classifierBuilder.setParameterValue(params).setName(new ClassifierName(classifierName)).build();
\r
118 public static ClassifierRef getClassifierRef(NeutronSecurityRule secRule) {
\r
119 checkNotNull(secRule);
\r
120 ClassifierName classifierInstanceName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
\r
121 ClassifierRefBuilder classifierRefBuilder = new ClassifierRefBuilder()
\r
122 .setConnectionTracking(ConnectionTracking.Reflexive).setInstanceName(classifierInstanceName);
\r
123 Direction direction = getDirection(secRule);
\r
124 classifierRefBuilder.setDirection(direction);
\r
125 ClassifierName classifierRefName = SecRuleNameDecoder.getClassifierRefName(secRule);
\r
126 return classifierRefBuilder.setName(classifierRefName).build();
\r
131 * @return direction resolved from {@link NeutronSecurityRule#getSecurityRuleDirection()}
\r
132 * @throws IllegalArgumentException if return value of
\r
133 * {@link NeutronSecurityRule#getSecurityRuleDirection()} is other than "ingress" or
\r
136 public static Direction getDirection(NeutronSecurityRule secRule) {
\r
137 String direction = secRule.getSecurityRuleDirection();
\r
138 if (NeutronUtils.INGRESS.equals(direction)) {
\r
139 return Direction.In;
\r
141 if (NeutronUtils.EGRESS.equals(direction)) {
\r
142 return Direction.Out;
\r
144 throw new IllegalArgumentException("Direction " + direction + " from security group rule "
\r
145 + secRule.getSecurityRuleUUID() + " is not supported. Direction can be only 'ingress' or 'egress'.");
\r
149 * @param secRule {@link NeutronSecurityRule#getSecurityRuleRemoteIpPrefix()} is used for EIC
\r
150 * and subject selection
\r
151 * @return clause with the subject and with a consumer matcher containing EIC
\r
153 public static Clause getClause(NeutronSecurityRule secRule) {
\r
154 checkNotNull(secRule);
\r
155 SubjectName subjectName = SecRuleNameDecoder.getSubjectName(secRule);
\r
156 ClauseBuilder clauseBuilder =
\r
157 new ClauseBuilder().setSubjectRefs(ImmutableList.of(subjectName)).setName(SecRuleNameDecoder.getClauseName(secRule));
\r
158 String remoteIpPrefix = secRule.getSecurityRuleRemoteIpPrefix();
\r
159 if (!Strings.isNullOrEmpty(remoteIpPrefix)) {
\r
160 clauseBuilder.setConsumerMatchers(createConsumerMatchersWithEic(remoteIpPrefix));
\r
162 return clauseBuilder.build();
\r
165 private static ConsumerMatchers createConsumerMatchersWithEic(String remoteIpPrefix) {
\r
166 IpPrefix ipPrefix = Utils.createIpPrefix(remoteIpPrefix);
\r
167 PrefixConstraint consumerPrefixConstraint = new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build();
\r
168 EndpointIdentificationConstraints eic =
\r
169 new EndpointIdentificationConstraintsBuilder()
\r
170 .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
\r
171 .setPrefixConstraint(ImmutableList.<PrefixConstraint>of(consumerPrefixConstraint)).build())
\r
173 return new ConsumerMatchersBuilder().setEndpointIdentificationConstraints(eic).build();
\r
176 public static boolean isEtherTypeOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {
\r
177 Long oneEtherType = getEtherType(one);
\r
178 Long twoEtherType = getEtherType(two);
\r
179 return twoIsNullOrEqualsOne(oneEtherType, twoEtherType);
\r
182 public static boolean isProtocolOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {
\r
183 Long oneProtocol = getProtocol(one);
\r
184 Long twoProtocol = getProtocol(two);
\r
185 return twoIsNullOrEqualsOne(oneProtocol, twoProtocol);
\r
188 private static <T> boolean twoIsNullOrEqualsOne(T one, T two) {
\r
191 if (two.equals(one))
\r
196 public static boolean isPortsOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {
\r
197 Integer onePortMin = one.getSecurityRulePortMin();
\r
198 Integer onePortMax = one.getSecurityRulePortMax();
\r
199 Integer twoPortMin = two.getSecurityRulePortMin();
\r
200 Integer twoPortMax = two.getSecurityRulePortMax();
\r
201 if (twoPortMin == null && twoPortMax == null) {
\r
204 if ((onePortMin != null && twoPortMin != null && onePortMin >= twoPortMin)
\r
205 && (onePortMax != null && twoPortMax != null && onePortMax <= twoPortMax)) {
\r
213 * @return {@code null} if {@link NeutronSecurityRule#getSecurityRuleEthertype()} is null or
\r
214 * empty; value of {@link EtherTypeClassifierDefinition#IPv4_VALUE} or
\r
215 * {@link EtherTypeClassifierDefinition#IPv6_VALUE}
\r
216 * @throws IllegalArgumentException if return value of
\r
217 * {@link NeutronSecurityRule#getSecurityRuleEthertype()} is not empty/null and is other
\r
218 * than "IPv4" or "IPv6"
\r
220 public static Long getEtherType(NeutronSecurityRule secRule) {
\r
221 String ethertype = secRule.getSecurityRuleEthertype();
\r
222 if (Strings.isNullOrEmpty(ethertype)) {
\r
225 if (NeutronUtils.IPv4.equals(ethertype)) {
\r
226 return EtherTypeClassifierDefinition.IPv4_VALUE;
\r
228 if (NeutronUtils.IPv6.equals(ethertype)) {
\r
229 return EtherTypeClassifierDefinition.IPv6_VALUE;
\r
231 throw new IllegalArgumentException("Ethertype " + ethertype + " is not supported.");
\r
236 * @return {@code null} if {@link NeutronSecurityRule#getSecurityRuleProtocol()} is null or
\r
237 * empty; Otherwise protocol number
\r
238 * @throws IllegalArgumentException if return value of
\r
239 * {@link NeutronSecurityRule#getSecurityRuleProtocol()} is not empty/null and is other
\r
240 * than "tcp", "udp", "icmp", "icmpv6" or string values that can be decoded to {@link Short}.
\r
242 public static Long getProtocol(NeutronSecurityRule secRule) {
\r
243 String protocol = secRule.getSecurityRuleProtocol();
\r
244 if (Strings.isNullOrEmpty(protocol)) {
\r
247 if (NeutronUtils.TCP.equals(protocol)) {
\r
248 return IpProtoClassifierDefinition.TCP_VALUE;
\r
250 if (NeutronUtils.UDP.equals(protocol)) {
\r
251 return IpProtoClassifierDefinition.UDP_VALUE;
\r
253 if (NeutronUtils.ICMP.equals(protocol)) {
\r
254 return IpProtoClassifierDefinition.ICMP_VALUE;
\r
256 if (NeutronUtils.ICMPv6.equals(protocol)) {
\r
257 return IpProtoClassifierDefinition.ICMPv6_VALUE;
\r
261 protocolNum = Long.valueOf(protocol);
\r
262 } catch (NumberFormatException e) {
\r
263 throw new IllegalArgumentException("Neutron Security Rule Protocol value " + protocol
\r
264 + " is not supported.");
\r
266 return protocolNum;
\r