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;
15 import java.util.ArrayList;
16 import java.util.List;
18 import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
19 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
20 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
21 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.ActionChoice;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.AllowActionCase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.SfcActionCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef.ConnectionTracking;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraints;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraint;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValueBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionBase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionEgress;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionIngress;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeBase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV6;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmp;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmpV6;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
62 public class SecRuleEntityDecoder {
64 private SecRuleEntityDecoder() {
65 throw new UnsupportedOperationException("Cannot create an instance.");
68 public static ContractId getContractId(SecurityRule secRule) {
69 return new ContractId(secRule.getUuid().getValue());
72 public static ClassifierInstance getClassifierInstance(SecurityRule secRule) {
73 ClassifierInstanceBuilder classifierBuilder = new ClassifierInstanceBuilder();
74 List<ParameterValue> params = new ArrayList<>();
75 Integer portMin = secRule.getPortRangeMin();
76 Integer portMax = secRule.getPortRangeMax();
77 if (portMin != null && portMax != null) {
78 classifierBuilder.setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId());
79 if (portMin.equals(portMax)) {
80 params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM))
81 .setIntValue(portMin.longValue())
84 params.add(new ParameterValueBuilder()
85 .setName(new ParameterName(L4ClassifierDefinition.DST_PORT_RANGE_PARAM))
87 new RangeValueBuilder().setMin(portMin.longValue()).setMax(portMax.longValue()).build())
91 Long protocol = getProtocol(secRule);
92 if (protocol != null) {
93 if (classifierBuilder.getClassifierDefinitionId() == null) {
94 classifierBuilder.setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId());
96 params.add(new ParameterValueBuilder()
97 .setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM))
98 .setIntValue(protocol)
101 Long ethertype = getEtherType(secRule);
102 if (ethertype != null) {
103 if (classifierBuilder.getClassifierDefinitionId() == null) {
104 classifierBuilder.setClassifierDefinitionId(EtherTypeClassifierDefinition.DEFINITION.getId());
106 params.add(new ParameterValueBuilder()
107 .setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))
108 .setIntValue(ethertype)
111 ClassifierName classifierName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
112 return classifierBuilder.setParameterValue(params).setName(new ClassifierName(classifierName)).build();
115 public static ActionRef createActionRefFromActionChoice(ActionChoice action) {
116 if (action instanceof SfcActionCase) {
117 return MappingUtils.createSfcActionRef(((SfcActionCase) action).getSfcChainName());
118 } else if (action instanceof AllowActionCase) {
119 return MappingUtils.ACTION_REF_ALLOW;
124 public static ClassifierRef getClassifierRef(SecurityRule secRule) {
125 checkNotNull(secRule);
126 ClassifierName classifierInstanceName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
127 ClassifierRefBuilder classifierRefBuilder = new ClassifierRefBuilder()
128 .setConnectionTracking(ConnectionTracking.Reflexive).setInstanceName(classifierInstanceName);
129 Direction direction = getDirection(secRule);
130 classifierRefBuilder.setDirection(direction);
131 ClassifierName classifierRefName = SecRuleNameDecoder.getClassifierRefName(secRule);
132 return classifierRefBuilder.setName(classifierRefName).build();
136 * Resolves Direction for provided secRule.
138 * @param secRule rule for which Direction is resolved.
139 * @return direction resolved from {@link SecurityRule#getDirection()}
140 * @throws IllegalArgumentException if return value of
141 * {@link SecurityRule#getDirection()} is other than {@link DirectionIngress} or
142 * {@link DirectionEgress}
144 public static Direction getDirection(SecurityRule secRule) {
145 Class<? extends DirectionBase> direction = secRule.getDirection();
146 if (direction == null) {
147 throw new IllegalArgumentException("Direction cannot be null.");
149 if (direction.isAssignableFrom(DirectionIngress.class)) {
152 if (direction.isAssignableFrom(DirectionEgress.class)) {
153 return Direction.Out;
155 throw new IllegalArgumentException("Direction " + direction + " from security group rule "
156 + secRule + " is not supported. Direction can be only 'ingress' or 'egress'.");
160 * Resolves Clause for provided secRule.
162 * @param secRule {@link SecurityRule#getRemoteIpPrefix()} is used for EIC
163 * and subject selection
164 * @return clause with the subject and with a consumer matcher containing EIC
166 public static Clause getClause(SecurityRule secRule) {
167 checkNotNull(secRule);
168 SubjectName subjectName = SecRuleNameDecoder.getSubjectName(secRule);
169 ClauseBuilder clauseBuilder = new ClauseBuilder()
170 .setSubjectRefs(ImmutableList.of(subjectName))
171 .setName(SecRuleNameDecoder
172 .getClauseName(secRule));
173 IpPrefix remoteIpPrefix = secRule.getRemoteIpPrefix();
174 if (remoteIpPrefix != null) {
175 clauseBuilder.setConsumerMatchers(createConsumerMatchersWithEic(remoteIpPrefix));
177 return clauseBuilder.build();
180 private static ConsumerMatchers createConsumerMatchersWithEic(IpPrefix ipPrefix) {
181 PrefixConstraint consumerPrefixConstraint = new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build();
182 EndpointIdentificationConstraints eic =
183 new EndpointIdentificationConstraintsBuilder()
184 .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
185 .setPrefixConstraint(ImmutableList.<PrefixConstraint>of(consumerPrefixConstraint)).build())
187 return new ConsumerMatchersBuilder().setEndpointIdentificationConstraints(eic).build();
190 public static boolean isEtherTypeOfOneWithinTwo(SecurityRule one, SecurityRule two) {
191 Long oneEtherType = getEtherType(one);
192 Long twoEtherType = getEtherType(two);
193 return twoIsNullOrEqualsOne(oneEtherType, twoEtherType);
196 public static boolean isProtocolOfOneWithinTwo(SecurityRule one, SecurityRule two) {
197 Long oneProtocol = getProtocol(one);
198 Long twoProtocol = getProtocol(two);
199 return twoIsNullOrEqualsOne(oneProtocol, twoProtocol);
202 private static <T> boolean twoIsNullOrEqualsOne(T one, T two) {
206 if (two.equals(one)) {
212 public static boolean isPortsOfOneWithinTwo(SecurityRule one, SecurityRule two) {
213 Integer onePortMin = one.getPortRangeMin();
214 Integer onePortMax = one.getPortRangeMax();
215 Integer twoPortMin = two.getPortRangeMin();
216 Integer twoPortMax = two.getPortRangeMax();
217 if (twoPortMin == null && twoPortMax == null) {
220 if ((onePortMin != null && twoPortMin != null && onePortMin >= twoPortMin)
221 && (onePortMax != null && twoPortMax != null && onePortMax <= twoPortMax)) {
228 * Resolves EtherType for provided secRule.
230 * @param secRule rule for which EtherType is resolved.
231 * @return {@code null} if {@link SecurityRule#getEthertype()} is null; Otherwise ethertype
233 * @throws IllegalArgumentException if return value of
234 * {@link SecurityRule#getEthertype()} is other {@link EthertypeV4} or
235 * {@link EthertypeV6}
237 public static Long getEtherType(SecurityRule secRule) {
238 Class<? extends EthertypeBase> ethertype = secRule.getEthertype();
239 if (ethertype == null) {
242 if (ethertype.isAssignableFrom(EthertypeV4.class)) {
243 return EtherTypeClassifierDefinition.IPv4_VALUE;
245 if (ethertype.isAssignableFrom(EthertypeV6.class)) {
246 return EtherTypeClassifierDefinition.IPv6_VALUE;
248 throw new IllegalArgumentException("Ethertype " + ethertype + " is not supported.");
252 * Resolves Protocol for provided secRule.
254 * @param secRule rule for which Protocol is resolved.
255 * @return {@code null} if {@link SecurityRule#getProtocol()} is null; Otherwise protocol number
256 * @throws IllegalArgumentException if return value of
257 * {@link SecurityRule#getProtocol()} is other than {@link ProtocolTcp},
258 * {@link ProtocolUdp}, {@link ProtocolIcmp}, {@link ProtocolIcmpV6}
260 public static Long getProtocol(SecurityRule secRule) {
261 SecurityRuleAttributes.Protocol protocol = secRule.getProtocol();
262 if (protocol == null) {
265 if (protocol.getUint8() != null) {
266 return protocol.getUint8().longValue();
268 if (protocol.getIdentityref() != null) {
269 if (protocol.getIdentityref().equals(ProtocolTcp.class)) {
270 return IpProtoClassifierDefinition.TCP_VALUE;
272 if (protocol.getIdentityref().equals(ProtocolUdp.class)) {
273 return IpProtoClassifierDefinition.UDP_VALUE;
275 if (protocol.getIdentityref().equals(ProtocolIcmp.class)) {
276 return IpProtoClassifierDefinition.ICMP_VALUE;
278 if (protocol.getIdentityref().equals(ProtocolIcmpV6.class)) {
279 return IpProtoClassifierDefinition.ICMPv6_VALUE;
282 throw new IllegalArgumentException("Neutron Security Rule Protocol value " + protocol + " is not supported.");