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.renderer.ofoverlay.sf;
12 import java.util.ArrayList;
13 import java.util.HashSet;
14 import java.util.List;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.IsRequired;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.Type;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.ParameterBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValue;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 import com.google.common.collect.ImmutableList;
40 import com.google.common.collect.ImmutableMap;
43 * Match against TCP or UDP, and source and/or destination ports
45 public class L4Classifier extends IpProtoClassifier {
46 private static final Logger LOG = LoggerFactory.getLogger(L4Classifier.class);
47 public static final ClassifierDefinitionId ID =
48 new ClassifierDefinitionId("4250ab32-e8b8-445a-aebb-e1bd2cdd291f");
49 private static final String SPORT = "sourceport";
50 private static final String SPORT_RANGE = "sourceport_range";
51 private static final String DPORT = "destport";
52 private static final String DPORT_RANGE = "destport_range";
53 private static final ClassifierDefinition DEF =
54 new ClassifierDefinitionBuilder()
55 .setId(new ClassifierDefinitionId("4250ab32-e8b8-445a-aebb-e1bd2cdd291f"))
56 .setParent(IpProtoClassifier.ID)
57 .setName(new ClassifierName("l4"))
58 .setDescription(new Description("Match on the port number of UDP or TCP traffic"))
59 .setParameter(ImmutableList.of(new ParameterBuilder()
60 .setName(new ParameterName(SPORT))
61 .setDescription(new Description("The source port number to match against"))
64 new ParameterBuilder()
65 .setName(new ParameterName(SPORT_RANGE))
66 .setDescription(new Description("The source port range to match against"))
69 new ParameterBuilder()
70 .setName(new ParameterName(DPORT))
71 .setDescription(new Description("The destination port number to match against"))
74 new ParameterBuilder()
75 .setName(new ParameterName(DPORT_RANGE))
76 .setDescription(new Description("The destination port range to match against"))
79 new ParameterBuilder()
80 .setName(new ParameterName(TYPE))
81 .setDescription(new Description("TCP or UDP"))
82 .setIsRequired(IsRequired.Required)
87 private static final Map<String, Object> tcp =
88 ImmutableMap.<String,Object>of(PROTO, Long.valueOf(6));
89 private static final Map<String, Object> udp =
90 ImmutableMap.<String,Object>of(PROTO, Long.valueOf(17));
93 public ClassifierDefinitionId getId() {
98 public ClassifierDefinition getClassDef() {
103 public List<MatchBuilder> updateMatch(List<MatchBuilder> matches,
104 Map<String, Object> params) {
105 Object param = params.get(TYPE);
106 // XXX TODO generate exception and fail the match
107 if (param == null || !(param instanceof String)) return matches;
108 String type = (String) param;
110 if ("UDP".equals(type))
111 matches = super.updateMatch(matches, udp);
113 matches = super.updateMatch(matches, tcp);
115 Set<Long> sPorts = new HashSet<>();
116 Set<Long> dPorts = new HashSet<>();
117 // int-value and range parameters
118 param = params.get(SPORT);
119 if (param != null && (param instanceof Long))
120 sPorts.add((long) param);
121 param = params.get(DPORT);
122 if (param != null && (param instanceof Long))
123 dPorts.add((long) param);
124 param = params.get(SPORT_RANGE);
125 if (param != null && param instanceof RangeValue) {
126 sPorts.addAll(createSetFromRange((RangeValue) param));
128 param = params.get(DPORT_RANGE);
129 if (param != null && param instanceof RangeValue) {
130 dPorts.addAll(createSetFromRange((RangeValue) param));
133 Set<? extends Layer4Match> l4Matches = null;
134 if ("UDP".equals(type)) {
135 l4Matches = createUdpMatches(sPorts, dPorts);
137 l4Matches = createTcpMatches(sPorts, dPorts);
139 List<MatchBuilder> newMatches = new ArrayList<>();
140 for (MatchBuilder matchBuilder : matches) {
141 Match baseMatch = matchBuilder.build();
142 for (Layer4Match l4Match : l4Matches) {
143 newMatches.add(new MatchBuilder(baseMatch).setLayer4Match(l4Match));
149 private Set<Long> createSetFromRange(RangeValue rangeValueParam){
150 Set<Long> res = new HashSet<>();
151 if (rangeValueParam != null) {
152 final Long min = rangeValueParam.getMin();
153 final Long max = rangeValueParam.getMax();
155 for (long val = min; val <= max; val++) {
159 LOG.warn("Range value mismatch. MIN {} is greater than MAX {}.", min, max);
165 private Set<UdpMatch> createUdpMatches(Set<Long> sPorts, Set<Long> dPorts) {
166 Set<UdpMatch> udpMatches = new HashSet<>();
167 if (!sPorts.isEmpty() && dPorts.isEmpty()) {
168 for (Long srcPort : sPorts) {
169 udpMatches.add(new UdpMatchBuilder().setUdpSourcePort(new PortNumber(srcPort.intValue())).build());
171 } else if (sPorts.isEmpty() && !dPorts.isEmpty()) {
172 for (Long dstPort : dPorts) {
173 udpMatches.add(new UdpMatchBuilder().setUdpDestinationPort(new PortNumber(dstPort.intValue())).build());
175 } else if (!sPorts.isEmpty() && !dPorts.isEmpty()) {
176 for (Long srcPort : sPorts) {
177 for (Long dstPort : dPorts) {
178 udpMatches.add(new UdpMatchBuilder().setUdpSourcePort(new PortNumber(srcPort.intValue()))
179 .setUdpDestinationPort(new PortNumber(dstPort.intValue())).build());
186 private Set<TcpMatch> createTcpMatches(Set<Long> sPorts, Set<Long> dPorts) {
187 Set<TcpMatch> tcpMatches = new HashSet<>();
188 if (!sPorts.isEmpty() && dPorts.isEmpty()) {
189 for (Long srcPort : sPorts) {
190 tcpMatches.add(new TcpMatchBuilder().setTcpSourcePort(new PortNumber(srcPort.intValue())).build());
192 } else if (sPorts.isEmpty() && !dPorts.isEmpty()) {
193 for (Long dstPort : dPorts) {
195 .add(new TcpMatchBuilder().setTcpDestinationPort(new PortNumber(dstPort.intValue())).build());
197 } else if (!sPorts.isEmpty() && !dPorts.isEmpty()) {
198 for (Long srcPort : sPorts) {
199 for (Long dstPort : dPorts) {
200 tcpMatches.add(new TcpMatchBuilder().setTcpSourcePort(new PortNumber(srcPort.intValue()))
201 .setTcpDestinationPort(new PortNumber(dstPort.intValue())).build());