579e858f8843ce5cafd84596523bf4ec029408de
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / rule / SecRuleEntityDecoder.java
1 /*\r
2  * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
3  *\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
7  */\r
8 \r
9 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;\r
10 \r
11 import static com.google.common.base.Preconditions.checkNotNull;\r
12 \r
13 import java.util.ArrayList;\r
14 import java.util.List;\r
15 \r
16 import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;\r
17 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;\r
18 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;\r
19 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;\r
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.ActionChoice;\r
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;\r
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;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef.ConnectionTracking;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraints;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraint;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValueBuilder;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionBase;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionEgress;\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionIngress;\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeBase;\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV6;\r
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolBase;\r
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmp;\r
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmpV6;\r
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;\r
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;\r
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;\r
59 \r
60 import com.google.common.collect.ImmutableList;\r
61 \r
62 public class SecRuleEntityDecoder {\r
63 \r
64     private SecRuleEntityDecoder() {\r
65         throw new UnsupportedOperationException("Cannot create an instace.");\r
66     }\r
67 \r
68     public static ContractId getContractId(SecurityRule secRule) {\r
69         return new ContractId(secRule.getId().getValue());\r
70     }\r
71 \r
72     public static ClassifierInstance getClassifierInstance(SecurityRule secRule) {\r
73         ClassifierInstanceBuilder classifierBuilder = new ClassifierInstanceBuilder();\r
74         List<ParameterValue> params = new ArrayList<>();\r
75         Integer portMin = secRule.getPortRangeMin();\r
76         Integer portMax = secRule.getPortRangeMax();\r
77         if (portMin != null && portMax != null) {\r
78             classifierBuilder.setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId());\r
79             if (portMin.equals(portMax)) {\r
80                 params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM))\r
81                     .setIntValue(portMin.longValue())\r
82                     .build());\r
83             } else {\r
84                 params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_RANGE_PARAM))\r
85                     .setRangeValue(\r
86                             new RangeValueBuilder().setMin(portMin.longValue()).setMax(portMax.longValue()).build())\r
87                     .build());\r
88             }\r
89         }\r
90         Long protocol = getProtocol(secRule);\r
91         if (protocol != null) {\r
92             if (classifierBuilder.getClassifierDefinitionId() == null) {\r
93                 classifierBuilder.setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId());\r
94             }\r
95             params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM))\r
96                 .setIntValue(protocol)\r
97                 .build());\r
98         }\r
99         Long ethertype = getEtherType(secRule);\r
100         if (ethertype != null) {\r
101             if (classifierBuilder.getClassifierDefinitionId() == null) {\r
102                 classifierBuilder.setClassifierDefinitionId(EtherTypeClassifierDefinition.DEFINITION.getId());\r
103             }\r
104             params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))\r
105                 .setIntValue(ethertype)\r
106                 .build());\r
107         }\r
108         ClassifierName classifierName = SecRuleNameDecoder.getClassifierInstanceName(secRule);\r
109         return classifierBuilder.setParameterValue(params).setName(new ClassifierName(classifierName)).build();\r
110     }\r
111 \r
112     public static ActionRef createActionRefFromActionChoice(ActionChoice action) {\r
113         if(action instanceof SfcActionCase){\r
114             return MappingUtils.createSfcActionRef(((SfcActionCase) action).getSfcChainName());\r
115         } else if (action instanceof AllowActionCase) {\r
116             return MappingUtils.ACTION_REF_ALLOW;\r
117         }\r
118         return null;\r
119     }\r
120 \r
121     public static ClassifierRef getClassifierRef(SecurityRule 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
130     }\r
131 \r
132     /**\r
133      * @param secRule\r
134      * @return direction resolved from {@link SecurityRule#getDirection()}\r
135      * @throws IllegalArgumentException if return value of\r
136      *         {@link SecurityRule#getDirection()} is other than {@link DirectionIngress} or\r
137      *         {@link DirectionEgress}\r
138      */\r
139     public static Direction getDirection(SecurityRule secRule) {\r
140         Class<? extends DirectionBase> direction = secRule.getDirection();\r
141         if (direction == null) {\r
142             throw new IllegalArgumentException("Direction cannot be null.");\r
143         }\r
144         if (direction.isAssignableFrom(DirectionIngress.class)) {\r
145             return Direction.In;\r
146         }\r
147         if (direction.isAssignableFrom(DirectionEgress.class)) {\r
148             return Direction.Out;\r
149         }\r
150         throw new IllegalArgumentException("Direction " + direction + " from security group rule "\r
151                 + secRule + " is not supported. Direction can be only 'ingress' or 'egress'.");\r
152     }\r
153 \r
154     /**\r
155      * @param secRule {@link SecurityRule#getRemoteIpPrefix()} is used for EIC\r
156      *        and subject selection\r
157      * @return clause with the subject and with a consumer matcher containing EIC\r
158      */\r
159     public static Clause getClause(SecurityRule secRule) {\r
160         checkNotNull(secRule);\r
161         SubjectName subjectName = SecRuleNameDecoder.getSubjectName(secRule);\r
162         ClauseBuilder clauseBuilder =\r
163                 new ClauseBuilder().setSubjectRefs(ImmutableList.of(subjectName)).setName(SecRuleNameDecoder.getClauseName(secRule));\r
164         IpPrefix remoteIpPrefix = secRule.getRemoteIpPrefix();\r
165         if (remoteIpPrefix != null) {\r
166             clauseBuilder.setConsumerMatchers(createConsumerMatchersWithEic(remoteIpPrefix));\r
167         }\r
168         return clauseBuilder.build();\r
169     }\r
170 \r
171     private static ConsumerMatchers createConsumerMatchersWithEic(IpPrefix ipPrefix) {\r
172         PrefixConstraint consumerPrefixConstraint = new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build();\r
173         EndpointIdentificationConstraints eic =\r
174                 new EndpointIdentificationConstraintsBuilder()\r
175                     .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()\r
176                         .setPrefixConstraint(ImmutableList.<PrefixConstraint>of(consumerPrefixConstraint)).build())\r
177                     .build();\r
178         return new ConsumerMatchersBuilder().setEndpointIdentificationConstraints(eic).build();\r
179     }\r
180 \r
181     public static boolean isEtherTypeOfOneWithinTwo(SecurityRule one, SecurityRule two) {\r
182         Long oneEtherType = getEtherType(one);\r
183         Long twoEtherType = getEtherType(two);\r
184         return twoIsNullOrEqualsOne(oneEtherType, twoEtherType);\r
185     }\r
186 \r
187     public static boolean isProtocolOfOneWithinTwo(SecurityRule one, SecurityRule two) {\r
188         Long oneProtocol = getProtocol(one);\r
189         Long twoProtocol = getProtocol(two);\r
190         return twoIsNullOrEqualsOne(oneProtocol, twoProtocol);\r
191     }\r
192 \r
193     private static <T> boolean twoIsNullOrEqualsOne(T one, T two) {\r
194         if (two == null)\r
195             return true;\r
196         if (two.equals(one))\r
197             return true;\r
198         return false;\r
199     }\r
200 \r
201     public static boolean isPortsOfOneWithinTwo(SecurityRule one, SecurityRule two) {\r
202         Integer onePortMin = one.getPortRangeMin();\r
203         Integer onePortMax = one.getPortRangeMax();\r
204         Integer twoPortMin = two.getPortRangeMin();\r
205         Integer twoPortMax = two.getPortRangeMax();\r
206         if (twoPortMin == null && twoPortMax == null) {\r
207             return true;\r
208         }\r
209         if ((onePortMin != null && twoPortMin != null && onePortMin >= twoPortMin)\r
210                 && (onePortMax != null && twoPortMax != null && onePortMax <= twoPortMax)) {\r
211             return true;\r
212         }\r
213         return false;\r
214     }\r
215 \r
216     /**\r
217      * @param secRule\r
218      * @return {@code null} if {@link SecurityRule#getEthertype()} is null; Otherwise ethertype\r
219      *         number\r
220      * @throws IllegalArgumentException if return value of\r
221      *         {@link SecurityRule#getEthertype()} is other {@link EthertypeV4} or\r
222      *         {@link EthertypeV6}\r
223      */\r
224     public static Long getEtherType(SecurityRule secRule) {\r
225         Class<? extends EthertypeBase> ethertype = secRule.getEthertype();\r
226         if (ethertype == null) {\r
227             return null;\r
228         }\r
229         if (ethertype.isAssignableFrom(EthertypeV4.class)) {\r
230             return EtherTypeClassifierDefinition.IPv4_VALUE;\r
231         }\r
232         if (ethertype.isAssignableFrom(EthertypeV6.class)) {\r
233             return EtherTypeClassifierDefinition.IPv6_VALUE;\r
234         }\r
235         throw new IllegalArgumentException("Ethertype " + ethertype + " is not supported.");\r
236     }\r
237 \r
238     /**\r
239      * @param secRule\r
240      * @return {@code null} if {@link SecurityRule#getProtocol()} is null; Otherwise protocol number\r
241      * @throws IllegalArgumentException if return value of\r
242      *         {@link SecurityRule#getProtocol()} is other than {@link ProtocolTcp},\r
243      *         {@link ProtocolUdp}, {@link ProtocolIcmp}, {@link ProtocolIcmpV6}\r
244      */\r
245     public static Long getProtocol(SecurityRule secRule) {\r
246         Class<? extends ProtocolBase> protocol = secRule.getProtocol();\r
247         if (protocol == null) {\r
248             return null;\r
249         }\r
250         if (protocol.isAssignableFrom(ProtocolTcp.class)) {\r
251             return IpProtoClassifierDefinition.TCP_VALUE;\r
252         }\r
253         if (protocol.isAssignableFrom(ProtocolUdp.class)) {\r
254             return IpProtoClassifierDefinition.UDP_VALUE;\r
255         }\r
256         if (protocol.isAssignableFrom(ProtocolIcmp.class)) {\r
257             return IpProtoClassifierDefinition.ICMP_VALUE;\r
258         }\r
259         if (protocol.isAssignableFrom(ProtocolIcmpV6.class)) {\r
260             return IpProtoClassifierDefinition.ICMPv6_VALUE;\r
261         }\r
262         throw new IllegalArgumentException("Neutron Security Rule Protocol value " + protocol + " is not supported.");\r
263     }\r
264 }\r