1 package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
3 import java.util.ArrayList;
5 import java.util.regex.Matcher;
6 import java.util.regex.Pattern;
8 import org.opendaylight.controller.sal.utils.IPProtocols;
9 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
10 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
11 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerAction;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputAction;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsAction;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbAction;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanAction;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstAction;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcAction;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueAction;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstAction;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcAction;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdAction;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpAction;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActions;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActions;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTable;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.Meter;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActions;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
43 public class FRMUtil {
44 protected static final Logger logger = LoggerFactory.getLogger(FRMUtil.class);
45 private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
47 public static enum operation {
48 ADD, DELETE, UPDATE, GET
51 public static boolean isNameValid(String name) {
54 if (name == null || name.trim().isEmpty() || !name.matches(NAMEREGEX)) {
61 public static boolean validateMatch(Flow flow) {
62 Match match = flow.getMatch();
64 EthernetMatch ethernetmatch = match.getEthernetMatch();
65 IpMatch ipmatch = match.getIpMatch();
66 VlanMatch vlanmatch = match.getVlanMatch();
67 match.getIcmpv4Match();
69 if (ethernetmatch != null) {
70 if ((ethernetmatch.getEthernetSource() != null)
71 && !isL2AddressValid(ethernetmatch.getEthernetSource().toString())) {
73 logger.error("Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
74 ethernetmatch.getEthernetSource());
78 if ((ethernetmatch.getEthernetDestination() != null)
79 && !isL2AddressValid(ethernetmatch.getEthernetDestination().toString())) {
80 logger.error("Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
81 ethernetmatch.getEthernetDestination());
85 if (ethernetmatch.getEthernetType() != null) {
86 int type = Integer.decode(ethernetmatch.getEthernetType().toString());
87 if ((type < 0) || (type > 0xffff)) {
88 logger.error("Ethernet type is not valid");
92 } else if (ipmatch != null) {
93 if (ipmatch.getIpProtocol() != null && isProtocolValid(ipmatch.getIpProtocol().toString())) {
94 logger.error("Protocol is not valid");
97 } else if (vlanmatch != null) {
98 if (vlanmatch.getVlanId() != null && isVlanIdValid(vlanmatch.getVlanId().toString())) {
99 logger.error("Vlan ID is not in the range 0 - 4095");
103 if (vlanmatch.getVlanPcp() != null && isVlanPriorityValid(vlanmatch.getVlanPcp().toString())) {
104 logger.error("Vlan priority is not in the range 0 - 7");
113 public static boolean validateActions(List<Action> actions) {
115 if (actions == null || actions.isEmpty()) {
116 logger.error("Actions value is null or empty");
120 for (Action curaction : actions) {
121 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action = curaction
123 if (action instanceof ControllerAction) {
124 Integer length = ((ControllerAction) action).getMaxLength();
125 if (length < 0 || length > 65294) {
126 logger.error("Controller: MaxLength is not valid");
129 } else if (action instanceof OutputAction) {
130 Integer length = ((OutputAction) action).getMaxLength();
131 Uri outputnodeconnector = ((OutputAction) action).getOutputNodeConnector();
132 if (length < 0 || length > 65294) {
133 logger.error("OutputAction: MaxLength is not valid");
136 if (outputnodeconnector != null) {
139 } else if (action instanceof PushMplsAction) {
140 Integer ethertype = ((PushMplsAction) action).getEthernetType();
141 if (ethertype != null && ethertype != 0x8847 && ethertype != 0x8848) {
142 logger.error("Ether Type is not valid for PushMplsAction");
145 } else if (action instanceof PushPbbAction) {
146 Integer ethertype = ((PushPbbAction) action).getEthernetType();
147 if (ethertype != null && ethertype != 0x88E7) {
148 logger.error("Ether type is not valid for PushPbbAction");
151 } else if (action instanceof PushVlanAction) {
152 Integer ethertype = ((PushVlanAction) action).getEthernetType();
153 if (ethertype != null && ethertype != 0x8100 && ethertype != 0x88a8) {
154 logger.error("Ether Type is not valid for PushVlanAction");
157 } else if (action instanceof SetDlDstAction || action instanceof SetDlSrcAction) {
158 MacAddress address = ((SetDlDstAction) action).getAddress();
159 if (address != null && !isL2AddressValid(address.toString())) {
160 logger.error("SetDlDstAction: Address not valid");
163 } else if (action instanceof SetDlSrcAction) {
164 MacAddress address = ((SetDlSrcAction) action).getAddress();
165 if (address != null && !isL2AddressValid(address.toString())) {
166 logger.error("SetDlSrcAction: Address not valid");
169 } else if (action instanceof SetQueueAction) {
170 String queue = ((SetQueueAction) action).getQueue();
171 if (queue != null && !isQueueValid(queue)) {
172 logger.error("Queue Id not valid");
175 } else if (action instanceof SetTpDstAction) {
176 PortNumber port = ((SetTpDstAction) action).getPort();
177 if (port != null && !isPortValid(port)) {
178 logger.error("Port not valid");
180 } else if (action instanceof SetTpSrcAction) {
181 PortNumber port = ((SetTpSrcAction) action).getPort();
182 if (port != null && !isPortValid(port)) {
183 logger.error("Port not valid");
185 } else if (action instanceof SetVlanIdAction) {
186 VlanId vlanid = ((SetVlanIdAction) action).getVlanId();
187 if (vlanid != null && !isVlanIdValid(vlanid.toString())) {
188 logger.error("Vlan ID %s is not in the range 0 - 4095");
191 } else if (action instanceof SetVlanPcpAction) {
192 VlanPcp vlanpcp = ((SetVlanPcpAction) action).getVlanPcp();
193 if (vlanpcp != null && !isVlanPriorityValid(vlanpcp.toString())) {
194 logger.error("Vlan priority %s is not in the range 0 - 7");
202 public static boolean validateInstructions(Flow flow) {
203 List<Instruction> instructionsList = new ArrayList<>();
204 Instructions instructions = flow.getInstructions();
205 if( instructions == null ) {
208 instructionsList = instructions.getInstruction();
210 for (Instruction instruction : instructionsList) {
211 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
213 if (curInstruction instanceof GoToTable) {
215 Short tableid = ((GoToTable) curInstruction).getTableId();
217 logger.error("table id is not valid");
222 else if (curInstruction instanceof WriteActions) {
224 List<Action> action = ((WriteActions) curInstruction).getAction();
225 validateActions(action);
229 else if (curInstruction instanceof ApplyActions) {
230 List<Action> action = ((ApplyActions) curInstruction).getAction();
231 validateActions(action);
234 else if (curInstruction instanceof ClearActions) {
235 List<Action> action = ((ClearActions) curInstruction).getAction();
236 validateActions(action);
239 else if (curInstruction instanceof Meter) {
241 String meter = ((Meter) curInstruction).getMeter();
242 if (meter != null && !isValidMeter(meter)) {
243 logger.error("Meter Id is not valid");
253 public static boolean isValidMeter(String meter) {
258 public static boolean isQueueValid(String queue) {
263 public static boolean isPortValid(PortNumber port) {
268 public static boolean isL2AddressValid(String mac) {
273 Pattern macPattern = Pattern.compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
274 Matcher mm = macPattern.matcher(mac);
276 logger.debug("Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f", mac);
282 public static boolean isProtocolValid(String protocol) {
283 IPProtocols proto = IPProtocols.fromString(protocol);
284 return (proto != null);
287 public static boolean isVlanIdValid(String vlanId) {
288 int vlan = Integer.decode(vlanId);
289 return ((vlan >= 0) && (vlan < 4096));
292 public static boolean isVlanPriorityValid(String vlanPriority) {
293 int pri = Integer.decode(vlanPriority);
294 return ((pri >= 0) && (pri < 8));