Merge "Topology Manager changes for cross checking Production switches"
[controller.git] / opendaylight / forwardingrulesmanager_mdsal / openflow / src / main / java / org / opendaylight / controller / forwardingrulesmanager_mdsal / consumer / impl / FRMUtil.java
1 package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.regex.Matcher;
6 import java.util.regex.Pattern;
7
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.service.rev130819.NodeFlow;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActions;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActions;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTable;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.Meter;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActions;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
41
42 public class FRMUtil {
43     protected static final Logger logger = LoggerFactory.getLogger(FRMUtil.class);
44     private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
45
46     public static enum operation {
47         ADD, DELETE, UPDATE, GET
48     };
49
50     public static boolean isNameValid(String name) {
51
52         // Name validation
53         if (name == null || name.trim().isEmpty() || !name.matches(NAMEREGEX)) {
54             return false;
55         }
56         return true;
57
58     }
59
60     public static boolean validateMatch(NodeFlow flow) {
61         Match match = flow.getMatch();
62         if (match != null) {
63             EthernetMatch ethernetmatch = match.getEthernetMatch();
64             IpMatch ipmatch = match.getIpMatch();
65             VlanMatch vlanmatch = match.getVlanMatch();
66             match.getIcmpv4Match();
67
68             if (ethernetmatch != null) {
69                 if ((ethernetmatch.getEthernetSource() != null)
70                         && !isL2AddressValid(ethernetmatch.getEthernetSource().toString())) {
71
72                     logger.error("Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
73                             ethernetmatch.getEthernetSource());
74                     return false;
75                 }
76
77                 if ((ethernetmatch.getEthernetDestination() != null)
78                         && !isL2AddressValid(ethernetmatch.getEthernetDestination().toString())) {
79                     logger.error("Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
80                             ethernetmatch.getEthernetDestination());
81                     return false;
82                 }
83
84                 if (ethernetmatch.getEthernetType() != null) {
85                     int type = Integer.decode(ethernetmatch.getEthernetType().toString());
86                     if ((type < 0) || (type > 0xffff)) {
87                         logger.error("Ethernet type is not valid");
88                         return false;
89                     }
90                 }
91             } else if (ipmatch != null) {
92                 if (ipmatch.getIpProtocol() != null && isProtocolValid(ipmatch.getIpProtocol().toString())) {
93                     logger.error("Protocol is not valid");
94                     return false;
95                 }
96             } else if (vlanmatch != null) {
97                 if (vlanmatch.getVlanId() != null && isVlanIdValid(vlanmatch.getVlanId().toString())) {
98                     logger.error("Vlan ID is not in the range 0 - 4095");
99                     return false;
100                 }
101
102                 if (vlanmatch.getVlanPcp() != null && isVlanPriorityValid(vlanmatch.getVlanPcp().toString())) {
103                     logger.error("Vlan priority is not in the range 0 - 7");
104                     return false;
105                 }
106             }
107         }
108
109         return true;
110     }
111
112     public static boolean validateActions(List<Action> actions) {
113
114         if (actions == null || actions.isEmpty()) {
115             logger.error("Actions value is null or empty");
116             return false;
117         }
118
119         for (Action curaction : actions) {
120             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action = curaction
121                     .getAction();
122             if (action instanceof ControllerAction) {
123                 Integer length = ((ControllerAction) action).getMaxLength();
124                 if (length < 0 || length > 65294) {
125                     logger.error("Controller: MaxLength is not valid");
126                     return false;
127                 }
128             } else if (action instanceof OutputAction) {
129                 Integer length = ((OutputAction) action).getMaxLength();
130                 Uri outputnodeconnector = ((OutputAction) action).getOutputNodeConnector();
131                 if (length < 0 || length > 65294) {
132                     logger.error("OutputAction: MaxLength is not valid");
133                     return false;
134                 }
135                 if (outputnodeconnector != null) {
136                     // TODO
137                 }
138             } else if (action instanceof PushMplsAction) {
139                 Integer ethertype = ((PushMplsAction) action).getEthernetType();
140                 if (ethertype != null && ethertype != 0x8847 && ethertype != 0x8848) {
141                     logger.error("Ether Type is not valid for PushMplsAction");
142                     return false;
143                 }
144             } else if (action instanceof PushPbbAction) {
145                 Integer ethertype = ((PushPbbAction) action).getEthernetType();
146                 if (ethertype != null && ethertype != 0x88E7) {
147                     logger.error("Ether type is not valid for PushPbbAction");
148                     return false;
149                 }
150             } else if (action instanceof PushVlanAction) {
151                 Integer ethertype = ((PushVlanAction) action).getEthernetType();
152                 if (ethertype != null && ethertype != 0x8100 && ethertype != 0x88a8) {
153                     logger.error("Ether Type is not valid for PushVlanAction");
154                     return false;
155                 }
156             } else if (action instanceof SetDlDstAction || action instanceof SetDlSrcAction) {
157                 MacAddress address = ((SetDlDstAction) action).getAddress();
158                 if (address != null && !isL2AddressValid(address.toString())) {
159                     logger.error("SetDlDstAction: Address not valid");
160                     return false;
161                 }
162             } else if (action instanceof SetDlSrcAction) {
163                 MacAddress address = ((SetDlSrcAction) action).getAddress();
164                 if (address != null && !isL2AddressValid(address.toString())) {
165                     logger.error("SetDlSrcAction: Address not valid");
166                     return false;
167                 }
168             } else if (action instanceof SetQueueAction) {
169                 String queue = ((SetQueueAction) action).getQueue();
170                 if (queue != null && !isQueueValid(queue)) {
171                     logger.error("Queue Id not valid");
172                     return false;
173                 }
174             } else if (action instanceof SetTpDstAction) {
175                 PortNumber port = ((SetTpDstAction) action).getPort();
176                 if (port != null && !isPortValid(port)) {
177                     logger.error("Port not valid");
178                 }
179             } else if (action instanceof SetTpSrcAction) {
180                 PortNumber port = ((SetTpSrcAction) action).getPort();
181                 if (port != null && !isPortValid(port)) {
182                     logger.error("Port not valid");
183                 }
184             } else if (action instanceof SetVlanIdAction) {
185                 VlanId vlanid = ((SetVlanIdAction) action).getVlanId();
186                 if (vlanid != null && !isVlanIdValid(vlanid.toString())) {
187                     logger.error("Vlan ID %s is not in the range 0 - 4095");
188                     return false;
189                 }
190             } else if (action instanceof SetVlanPcpAction) {
191                 VlanPcp vlanpcp = ((SetVlanPcpAction) action).getVlanPcp();
192                 if (vlanpcp != null && !isVlanPriorityValid(vlanpcp.toString())) {
193                     logger.error("Vlan priority %s is not in the range 0 - 7");
194                     return false;
195                 }
196             }
197         }
198         return true;
199     }
200
201     public static boolean validateInstructions(NodeFlow flow) {
202         List<Instruction> instructionsList = new ArrayList<>();
203         Instructions instructions = flow.getInstructions();
204         instructionsList = instructions.getInstruction();
205
206         for (Instruction instruction : instructionsList) {
207             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
208                     .getInstruction();
209             if (curInstruction instanceof GoToTable) {
210
211                 Short tableid = ((GoToTable) curInstruction).getTableId();
212                 if (tableid < 0) {
213                     logger.error("table id is not valid");
214                     return false;
215                 }
216             }
217
218             else if (curInstruction instanceof WriteActions) {
219
220                 List<Action> action = ((WriteActions) curInstruction).getAction();
221                 validateActions(action);
222
223             }
224
225             else if (curInstruction instanceof ApplyActions) {
226                 List<Action> action = ((ApplyActions) curInstruction).getAction();
227                 validateActions(action);
228             }
229
230             else if (curInstruction instanceof ClearActions) {
231                 List<Action> action = ((ClearActions) curInstruction).getAction();
232                 validateActions(action);
233             }
234
235             else if (curInstruction instanceof Meter) {
236
237                 String meter = ((Meter) curInstruction).getMeter();
238                 if (meter != null && !isValidMeter(meter)) {
239                     logger.error("Meter Id is not valid");
240                     return false;
241                 }
242             }
243
244         }
245
246         return true;
247     }
248
249     public static boolean isValidMeter(String meter) {
250         // TODO
251         return true;
252     }
253
254     public static boolean isQueueValid(String queue) {
255         // TODO
256         return true;
257     }
258
259     public static boolean isPortValid(PortNumber port) {
260         // TODO
261         return true;
262     }
263
264     public static boolean isL2AddressValid(String mac) {
265         if (mac == null) {
266             return false;
267         }
268
269         Pattern macPattern = Pattern.compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
270         Matcher mm = macPattern.matcher(mac);
271         if (!mm.matches()) {
272             logger.debug("Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f", mac);
273             return false;
274         }
275         return true;
276     }
277
278     public static boolean isProtocolValid(String protocol) {
279         IPProtocols proto = IPProtocols.fromString(protocol);
280         return (proto != null);
281     }
282
283     public static boolean isVlanIdValid(String vlanId) {
284         int vlan = Integer.decode(vlanId);
285         return ((vlan >= 0) && (vlan < 4096));
286     }
287
288     public static boolean isVlanPriorityValid(String vlanPriority) {
289         int pri = Integer.decode(vlanPriority);
290         return ((pri >= 0) && (pri < 8));
291     }
292 }