2 * Copyright (c) 2014 Cisco Systems, Inc. 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.groupbasedpolicy.neutron.mapper.mapping.rule;
11 import static com.google.common.base.Preconditions.checkNotNull;
13 import com.google.common.collect.ImmutableList;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
17 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
18 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
19 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.ActionChoice;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.AllowActionCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.SfcActionCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef.ConnectionTracking;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraints;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraint;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValueBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionBase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionEgress;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionIngress;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeBase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV6;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmp;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmpV6;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
60 public final class SecRuleEntityDecoder {
62 private SecRuleEntityDecoder() {
63 throw new UnsupportedOperationException("Cannot create an instance.");
66 public static ContractId getContractId(SecurityRule secRule) {
67 return new ContractId(secRule.getUuid().getValue());
70 public static ClassifierInstance getClassifierInstance(SecurityRule secRule) {
71 ClassifierInstanceBuilder classifierBuilder = new ClassifierInstanceBuilder();
72 List<ParameterValue> params = new ArrayList<>();
73 Integer portMin = secRule.getPortRangeMin();
74 Integer portMax = secRule.getPortRangeMax();
75 if (portMin != null && portMax != null) {
76 classifierBuilder.setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId());
77 if (portMin.equals(portMax)) {
78 params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM))
79 .setIntValue(portMin.longValue())
82 params.add(new ParameterValueBuilder()
83 .setName(new ParameterName(L4ClassifierDefinition.DST_PORT_RANGE_PARAM))
85 new RangeValueBuilder().setMin(portMin.longValue()).setMax(portMax.longValue()).build())
89 Long protocol = getProtocol(secRule);
90 if (protocol != null) {
91 if (classifierBuilder.getClassifierDefinitionId() == null) {
92 classifierBuilder.setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId());
94 params.add(new ParameterValueBuilder()
95 .setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM))
96 .setIntValue(protocol)
99 Long ethertype = getEtherType(secRule);
100 if (ethertype != null) {
101 if (classifierBuilder.getClassifierDefinitionId() == null) {
102 classifierBuilder.setClassifierDefinitionId(EtherTypeClassifierDefinition.DEFINITION.getId());
104 params.add(new ParameterValueBuilder()
105 .setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))
106 .setIntValue(ethertype)
109 ClassifierName classifierName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
110 return classifierBuilder.setParameterValue(params).setName(new ClassifierName(classifierName)).build();
113 public static ActionRef createActionRefFromActionChoice(ActionChoice action) {
114 if (action instanceof SfcActionCase) {
115 return MappingUtils.createSfcActionRef(((SfcActionCase) action).getSfcChainName());
116 } else if (action instanceof AllowActionCase) {
117 return MappingUtils.ACTION_REF_ALLOW;
122 public static ClassifierRef getClassifierRef(SecurityRule secRule) {
123 checkNotNull(secRule);
124 ClassifierName classifierInstanceName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
125 ClassifierRefBuilder classifierRefBuilder = new ClassifierRefBuilder()
126 .setConnectionTracking(ConnectionTracking.Reflexive).setInstanceName(classifierInstanceName);
127 Direction direction = getDirection(secRule);
128 classifierRefBuilder.setDirection(direction);
129 ClassifierName classifierRefName = SecRuleNameDecoder.getClassifierRefName(secRule);
130 return classifierRefBuilder.setName(classifierRefName).build();
134 * Resolves Direction for provided secRule.
136 * @param secRule rule for which Direction is resolved.
137 * @return direction resolved from {@link SecurityRule#getDirection()}
138 * @throws IllegalArgumentException if return value of
139 * {@link SecurityRule#getDirection()} is other than {@link DirectionIngress} or
140 * {@link DirectionEgress}
142 public static Direction getDirection(SecurityRule secRule) {
143 Class<? extends DirectionBase> direction = secRule.getDirection();
144 if (direction == null) {
145 throw new IllegalArgumentException("Direction cannot be null.");
147 if (direction.isAssignableFrom(DirectionIngress.class)) {
150 if (direction.isAssignableFrom(DirectionEgress.class)) {
151 return Direction.Out;
153 throw new IllegalArgumentException("Direction " + direction + " from security group rule "
154 + secRule + " is not supported. Direction can be only 'ingress' or 'egress'.");
158 * Resolves Clause for provided secRule.
160 * @param secRule {@link SecurityRule#getRemoteIpPrefix()} is used for EIC
161 * and subject selection
162 * @return clause with the subject and with a consumer matcher containing EIC
164 public static Clause getClause(SecurityRule secRule) {
165 checkNotNull(secRule);
166 SubjectName subjectName = SecRuleNameDecoder.getSubjectName(secRule);
167 ClauseBuilder clauseBuilder = new ClauseBuilder()
168 .setSubjectRefs(ImmutableList.of(subjectName))
169 .setName(SecRuleNameDecoder
170 .getClauseName(secRule));
171 IpPrefix remoteIpPrefix = secRule.getRemoteIpPrefix();
172 if (remoteIpPrefix != null) {
173 clauseBuilder.setConsumerMatchers(createConsumerMatchersWithEic(remoteIpPrefix));
175 return clauseBuilder.build();
178 private static ConsumerMatchers createConsumerMatchersWithEic(IpPrefix ipPrefix) {
179 PrefixConstraint consumerPrefixConstraint = new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build();
180 EndpointIdentificationConstraints eic =
181 new EndpointIdentificationConstraintsBuilder()
182 .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
183 .setPrefixConstraint(ImmutableList.<PrefixConstraint>of(consumerPrefixConstraint)).build())
185 return new ConsumerMatchersBuilder().setEndpointIdentificationConstraints(eic).build();
188 public static boolean isEtherTypeOfOneWithinTwo(SecurityRule one, SecurityRule two) {
189 Long oneEtherType = getEtherType(one);
190 Long twoEtherType = getEtherType(two);
191 return twoIsNullOrEqualsOne(oneEtherType, twoEtherType);
194 public static boolean isProtocolOfOneWithinTwo(SecurityRule one, SecurityRule two) {
195 Long oneProtocol = getProtocol(one);
196 Long twoProtocol = getProtocol(two);
197 return twoIsNullOrEqualsOne(oneProtocol, twoProtocol);
200 private static <T> boolean twoIsNullOrEqualsOne(T one, T two) {
204 if (two.equals(one)) {
210 public static boolean isPortsOfOneWithinTwo(SecurityRule one, SecurityRule two) {
211 Integer onePortMin = one.getPortRangeMin();
212 Integer onePortMax = one.getPortRangeMax();
213 Integer twoPortMin = two.getPortRangeMin();
214 Integer twoPortMax = two.getPortRangeMax();
215 if (twoPortMin == null && twoPortMax == null) {
218 if (onePortMin != null && twoPortMin != null && onePortMin >= twoPortMin
219 && onePortMax != null && twoPortMax != null && onePortMax <= twoPortMax) {
226 * Resolves EtherType for provided secRule.
228 * @param secRule rule for which EtherType is resolved.
229 * @return {@code null} if {@link SecurityRule#getEthertype()} is null; Otherwise ethertype
231 * @throws IllegalArgumentException if return value of
232 * {@link SecurityRule#getEthertype()} is other {@link EthertypeV4} or
233 * {@link EthertypeV6}
235 public static Long getEtherType(SecurityRule secRule) {
236 Class<? extends EthertypeBase> ethertype = secRule.getEthertype();
237 if (ethertype == null) {
240 if (ethertype.isAssignableFrom(EthertypeV4.class)) {
241 return EtherTypeClassifierDefinition.IPv4_VALUE;
243 if (ethertype.isAssignableFrom(EthertypeV6.class)) {
244 return EtherTypeClassifierDefinition.IPv6_VALUE;
246 throw new IllegalArgumentException("Ethertype " + ethertype + " is not supported.");
250 * Resolves Protocol for provided secRule.
252 * @param secRule rule for which Protocol is resolved.
253 * @return {@code null} if {@link SecurityRule#getProtocol()} is null; Otherwise protocol number
254 * @throws IllegalArgumentException if return value of
255 * {@link SecurityRule#getProtocol()} is other than {@link ProtocolTcp},
256 * {@link ProtocolUdp}, {@link ProtocolIcmp}, {@link ProtocolIcmpV6}
258 public static Long getProtocol(SecurityRule secRule) {
259 SecurityRuleAttributes.Protocol protocol = secRule.getProtocol();
260 if (protocol == null) {
263 if (protocol.getUint8() != null) {
264 return protocol.getUint8().longValue();
266 if (protocol.getIdentityref() != null) {
267 if (protocol.getIdentityref().equals(ProtocolTcp.class)) {
268 return IpProtoClassifierDefinition.TCP_VALUE;
270 if (protocol.getIdentityref().equals(ProtocolUdp.class)) {
271 return IpProtoClassifierDefinition.UDP_VALUE;
273 if (protocol.getIdentityref().equals(ProtocolIcmp.class)) {
274 return IpProtoClassifierDefinition.ICMP_VALUE;
276 if (protocol.getIdentityref().equals(ProtocolIcmpV6.class)) {
277 return IpProtoClassifierDefinition.ICMPv6_VALUE;
280 throw new IllegalArgumentException("Neutron Security Rule Protocol value " + protocol + " is not supported.");