Add INFO.yaml for GBP
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / statistics / flowcache / FlowCacheFactory.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
3  *
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
7  */
8 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache;
9
10 import java.util.List;
11 import java.util.Objects;
12
13 import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
14 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
15 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
16 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
17 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCache.FlowCacheBuilder;
18 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCacheDefinition.FlowCacheDefinitionBuilder;
19 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.FlowCacheCons;
20 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.IidSflowNameUtil;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 public class FlowCacheFactory {
28
29     private static final Logger LOG = LoggerFactory.getLogger(FlowCacheFactory.class);
30
31     public static FlowCache createFlowCache(InstanceIdentifier<Classifier> classifierIid, Classifier classifier,
32             FlowCacheCons.Value value) {
33         FlowCacheDefinition flowCacheDefinition = createFlowCacheDefinition(classifier, value);
34         if (flowCacheDefinition == null) {
35             LOG.info("Cannot create flow cache for statistics of classifier {}\n{}", classifierIid, classifier);
36             return null;
37         }
38         return new FlowCacheBuilder().setDefinition(flowCacheDefinition)
39             .setName(IidSflowNameUtil.createFlowCacheName(classifierIid, value))
40             .setDirection(classifier.getDirection())
41             .build();
42     }
43
44     public static FlowCacheDefinition createFlowCacheDefinition(Classifier classifier,
45             FlowCacheCons.Value value) {
46         FlowCacheDefinitionBuilder fcdBuilder = new FlowCacheDefinitionBuilder();
47         if (L4ClassifierDefinition.ID.equals(classifier.getClassifierDefinitionId())) {
48             addEthTypeInfoToFlowCache(classifier, fcdBuilder);
49             if (!addIpProtoInfoToFlowCache(classifier, fcdBuilder)) {
50                 return null;
51             }
52             if (!addL4InfoToFlowCache(classifier, fcdBuilder)) {
53                 return null;
54             }
55         } else if (IpProtoClassifierDefinition.ID.equals(classifier.getClassifierDefinitionId())) {
56             addEthTypeInfoToFlowCache(classifier, fcdBuilder);
57             if (!addIpProtoInfoToFlowCache(classifier, fcdBuilder)) {
58                 return null;
59             }
60         } else if (EtherTypeClassifierDefinition.ID.equals(classifier.getClassifierDefinitionId())) {
61             addEthTypeInfoToFlowCache(classifier, fcdBuilder);
62         } else {
63             LOG.warn("Sflow stats will not be pulled because of unknown classifier: {}", classifier);
64             return null;
65         }
66         fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.IP_SOURCE.get()).addValue(FlowCacheCons.Key.IP_DESTINATION.get());
67         fcdBuilder.setValue(value.get());
68         return fcdBuilder.build();
69     }
70
71     private static void addEthTypeInfoToFlowCache(Classifier classifier, FlowCacheDefinitionBuilder fcdBuilder) {
72         List<ParameterValue> parametersAndValues = classifier.getParameterValue();
73         ParameterValue ethTypeParam = getParamVal(parametersAndValues, EtherTypeClassifierDefinition.ETHERTYPE_PARAM);
74         if (ethTypeParam != null) {
75             fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.ETH_PROTOCOL.get());
76             fcdBuilder.getFilterBuilder()
77                 .addValue(FlowCacheCons.Key.ETH_PROTOCOL.get() + FlowCacheCons.EQ + ethTypeParam.getIntValue());
78         } else {
79             fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.ETH_PROTOCOL.get());
80             fcdBuilder.getFilterBuilder()
81                 .addValue(FlowCacheCons.Key.ETH_PROTOCOL.get() + FlowCacheCons.EQ + FlowUtils.IPv4 + FlowCacheCons.OR
82                         + FlowCacheCons.Key.ETH_PROTOCOL.get() + FlowCacheCons.EQ + FlowUtils.IPv6);
83         }
84     }
85
86     private static boolean addIpProtoInfoToFlowCache(Classifier classifier, FlowCacheDefinitionBuilder fcdBuilder) {
87         List<ParameterValue> parametersAndValues = classifier.getParameterValue();
88         ParameterValue ipProtoParam = getParamVal(parametersAndValues, IpProtoClassifierDefinition.PROTO_PARAM);
89         if (ipProtoParam != null) {
90             fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.IP_PROTOCOL.get());
91             fcdBuilder.getFilterBuilder()
92                 .addValue(FlowCacheCons.Key.IP_PROTOCOL.get() + FlowCacheCons.EQ + ipProtoParam.getIntValue());
93             return true;
94         } else {
95             LOG.trace("Cannot add ip-proto information to flow cache for Sflow-RT.");
96             return false;
97         }
98     }
99
100     private static boolean addL4InfoToFlowCache(Classifier classifier, FlowCacheDefinitionBuilder fcdBuilder) {
101         List<ParameterValue> parametersAndValues = classifier.getParameterValue();
102         ParameterValue ipProtoParam = getParamVal(parametersAndValues, IpProtoClassifierDefinition.PROTO_PARAM);
103         ParameterValue dstPortParam = getParamVal(parametersAndValues, L4ClassifierDefinition.DST_PORT_PARAM);
104         ParameterValue srcPortParam = getParamVal(parametersAndValues, L4ClassifierDefinition.SRC_PORT_PARAM);
105         if (ipProtoParam == null || (dstPortParam == null && srcPortParam == null)) {
106             LOG.trace(
107                     "Cannot add L4 information to flow cache for Sflow-RT."
108                             + "\nipProtoParam:{} dstPortParam:{} srcPortParam:{}",
109                     ipProtoParam, dstPortParam, srcPortParam);
110             return false;
111         }
112         if (dstPortParam != null) {
113             if (!addTcpUdpPortKeys(ipProtoParam.getIntValue(), dstPortParam.getIntValue(), true, fcdBuilder)) {
114                 return false;
115             }
116         }
117         if (srcPortParam != null) {
118             if (!addTcpUdpPortKeys(ipProtoParam.getIntValue(), srcPortParam.getIntValue(), false, fcdBuilder)) {
119                 return false;
120             }
121         }
122         return true;
123     }
124
125     private static ParameterValue getParamVal(List<ParameterValue> parametersAndValues, String paramName) {
126         for (ParameterValue paramVal : parametersAndValues) {
127             if (paramName.equals(paramVal.getName().getValue())) {
128                 return paramVal;
129             }
130         }
131         return null;
132     }
133
134     private static boolean addTcpUdpPortKeys(Long ipProto, Long port, boolean isDstPort,
135             FlowCacheDefinitionBuilder fcdBuilder) {
136         if (isDstPort) {
137             if (Objects.equals(ipProto, IpProtoClassifierDefinition.TCP_VALUE)) {
138                 fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.TCP_DST_PORT.get());
139                 fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.TCP_DST_PORT.get() + FlowCacheCons.EQ + port);
140             } else if (Objects.equals(ipProto, IpProtoClassifierDefinition.UDP_VALUE)) {
141                 fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.UDP_DST_PORT.get());
142                 fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.UDP_DST_PORT.get() + FlowCacheCons.EQ + port);
143             } else {
144                 LOG.info("Statistics cannot be collected for ip-proto {} and port {}", ipProto, port);
145                 return false;
146             }
147         } else {
148             if (Objects.equals(ipProto, IpProtoClassifierDefinition.TCP_VALUE)) {
149                 fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.TCP_SRC_PORT.get());
150                 fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.TCP_SRC_PORT.get() + FlowCacheCons.EQ + port);
151             } else if (Objects.equals(ipProto, IpProtoClassifierDefinition.UDP_VALUE)) {
152                 fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.UDP_SRC_PORT.get());
153                 fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.UDP_SRC_PORT.get() + FlowCacheCons.EQ + port);
154             } else {
155                 LOG.info("Statistics cannot be collected for ip-proto {} and port {}", ipProto, port);
156                 return false;
157             }
158         }
159         return true;
160     }
161 }