Merge "Add missing feature dependencies to ovsdb karaf distro"
[ovsdb.git] / utils / mdsal-openflow / src / main / java / org / opendaylight / ovsdb / utils / mdsal / openflow / InstructionUtils.java
1 /*
2  * Copyright (C) 2013 Red Hat, Inc.
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  */
9
10 package org.opendaylight.ovsdb.utils.mdsal.openflow;
11
12 import static org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils.dropAction;
13
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCaseBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCaseBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4MatchBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
69
70 import com.google.common.collect.Lists;
71
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74
75 import java.math.BigInteger;
76 import java.util.ArrayList;
77 import java.util.List;
78
79 public class InstructionUtils {
80     private static final Logger logger = LoggerFactory.getLogger(InstructionUtils.class);
81     private static final int IPV4 = 0x8100;
82     private static final int MAX_LENGTH = 0xffff;
83
84     /**
85      * Create Send to Controller Reserved Port Instruction (packet_in)
86      *
87      * @param ib Map InstructionBuilder without any instructions
88      * @return ib Map InstructionBuilder with instructions
89      */
90     public static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
91
92         List<Action> actionList = Lists.newArrayList();
93         ActionBuilder ab = new ActionBuilder();
94
95         OutputActionBuilder output = new OutputActionBuilder();
96         output.setMaxLength(MAX_LENGTH);
97         Uri value = new Uri("CONTROLLER");
98         output.setOutputNodeConnector(value);
99         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
100         ab.setOrder(0);
101         ab.setKey(new ActionKey(0));
102         actionList.add(ab.build());
103
104         // Create an Apply Action
105         ApplyActionsBuilder aab = new ApplyActionsBuilder();
106         aab.setAction(actionList);
107
108         // Wrap our Apply Action in an Instruction
109         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
110
111         return ib;
112     }
113
114     /**
115      * Create NORMAL Reserved Port Instruction (packet_in)
116      *
117      * @param ib Map InstructionBuilder without any instructions
118      * @return ib Map InstructionBuilder with instructions
119      */
120
121     public static InstructionBuilder createNormalInstructions(InstructionBuilder ib) {
122
123         List<Action> actionList = Lists.newArrayList();
124         ActionBuilder ab = new ActionBuilder();
125
126         OutputActionBuilder output = new OutputActionBuilder();
127         Uri value = new Uri("NORMAL");
128         output.setOutputNodeConnector(value);
129         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
130         ab.setOrder(0);
131         ab.setKey(new ActionKey(0));
132         actionList.add(ab.build());
133
134         // Create an Apply Action
135         ApplyActionsBuilder aab = new ApplyActionsBuilder();
136         aab.setAction(actionList);
137
138         // Wrap our Apply Action in an Instruction
139         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
140
141         return ib;
142     }
143
144     /**
145      * Create Output Port Instruction
146      *
147      * @param ib       Map InstructionBuilder without any instructions
148      * @param dpidLong Long the datapath ID of a switch/node
149      * @param port     Long representing a port on a switch/node
150      * @return ib InstructionBuilder Map with instructions
151      */
152     public static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
153
154         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
155         logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ",
156                 dpidLong, port);
157
158         List<Action> actionList = Lists.newArrayList();
159         ActionBuilder ab = new ActionBuilder();
160         OutputActionBuilder oab = new OutputActionBuilder();
161         oab.setOutputNodeConnector(ncid);
162
163         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
164         ab.setOrder(0);
165         ab.setKey(new ActionKey(0));
166         actionList.add(ab.build());
167
168         // Create an Apply Action
169         ApplyActionsBuilder aab = new ApplyActionsBuilder();
170         aab.setAction(actionList);
171         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
172
173         return ib;
174     }
175
176     /**
177      * add Output Port action to Instruction action list.
178      * This is use for flow with single output port actions.
179      * Flow with mutiple output port actions should use createOutputPortInstructions() method.
180      *
181      * @param ib       Map InstructionBuilder without any instructions
182      * @param dpidLong Long the datapath ID of a switch/node
183      * @param port     Long representing a port on a switch/node
184      * @return ib InstructionBuilder Map with instructions
185      */
186     public static InstructionBuilder addOutputPortInstructions(InstructionBuilder ib,
187             Long dpidLong, Long port,
188             List<Instruction> instructions) {
189         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
190         logger.debug(
191                 "addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}",
192                 dpidLong, port, instructions);
193
194         List<Action> actionList = Lists.newArrayList();
195         ActionBuilder ab = new ActionBuilder();
196
197         List<Action> existingActions;
198         if (instructions != null) {
199             for (Instruction in : instructions) {
200                 if (in.getInstruction() instanceof ApplyActionsCase) {
201                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
202                     actionList.addAll(existingActions);
203                 }
204             }
205         }
206
207         /* Create output action for this port*/
208         OutputActionBuilder oab = new OutputActionBuilder();
209         oab.setOutputNodeConnector(ncid);
210         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
211         ab.setOrder(actionList.size());
212         ab.setKey(new ActionKey(actionList.size()));
213         actionList.add(ab.build());
214
215         // Create an Apply Action
216         ApplyActionsBuilder aab = new ApplyActionsBuilder();
217         aab.setAction(actionList);
218         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
219
220         return ib;
221     }
222
223     /**
224      * Remove Output Port from Instruction
225      *
226      * @param ib       Map InstructionBuilder without any instructions
227      * @param dpidLong Long the datapath ID of a switch/node
228      * @param port     Long representing a port on a switch/node
229      * @return ib InstructionBuilder Map with instructions
230      */
231     public static boolean removeOutputPortFromInstructions(InstructionBuilder ib,
232             Long dpidLong, Long port, List<Instruction> instructions) {
233
234         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
235         logger.debug(
236                 "removeOutputPortFromInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}",
237                 dpidLong, port, instructions);
238
239         List<Action> actionList = Lists.newArrayList();
240         ActionBuilder ab;
241
242         List<Action> existingActions;
243         if (instructions != null) {
244             for (Instruction in : instructions) {
245                 if (in.getInstruction() instanceof ApplyActionsCase) {
246                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
247                     actionList.addAll(existingActions);
248                     break;
249                 }
250             }
251         }
252
253         int index = 0;
254         boolean isPortDeleted = false;
255         boolean removeFlow = true;
256         for (Action action : actionList) {
257             if (action.getAction() instanceof OutputActionCase) {
258                 OutputActionCase opAction = (OutputActionCase) action.getAction();
259                 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
260                     /* Find the output port in action list and remove */
261                     index = actionList.indexOf(action);
262                     actionList.remove(action);
263                     isPortDeleted = true;
264                     break;
265                 }
266                 removeFlow = false;
267             }
268         }
269
270         if (isPortDeleted) {
271             for (int i = index; i < actionList.size(); i++) {
272                 Action action = actionList.get(i);
273                 if (action.getOrder() != i) {
274                     /* Shift the action order */
275                     ab = new ActionBuilder();
276                     ab.setAction(action.getAction());
277                     ab.setOrder(i);
278                     ab.setKey(new ActionKey(i));
279                     Action actionNewOrder = ab.build();
280                     actionList.remove(action);
281                     actionList.add(i, actionNewOrder);
282                 }
283                 if (action.getAction() instanceof OutputActionCase) {
284                     removeFlow = false;
285                 }
286             }
287         }
288
289         /* Put new action list in Apply Action instruction */
290         if (!removeFlow) {
291             ApplyActionsBuilder aab = new ApplyActionsBuilder();
292             aab.setAction(actionList);
293             ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
294             logger.debug("removeOutputPortFromInstructions() : applyAction {}", aab.build());
295             return false;
296         } else {
297             /* if all output port are removed. Return true to indicate flow remove */
298             return true;
299         }
300     }
301
302     /**
303      * Create Set Vlan ID Instruction - This includes push vlan action, and set field -> vlan vid action
304      *
305      * @param ib     Map InstructionBuilder without any instructions
306      * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
307      * @return ib Map InstructionBuilder with instructions
308      */
309     public static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
310
311         List<Action> actionList = Lists.newArrayList();
312         ActionBuilder ab = new ActionBuilder();
313
314         /* First we push vlan header */
315         PushVlanActionBuilder vlan = new PushVlanActionBuilder();
316         vlan.setEthernetType(IPV4);
317         ab.setAction(new PushVlanActionCaseBuilder().setPushVlanAction(vlan.build()).build());
318         ab.setOrder(0);
319         actionList.add(ab.build());
320
321         /* Then we set vlan id value as vlanId */
322         SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
323         vl.setVlanId(vlanId);
324         ab = new ActionBuilder();
325         ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
326         ab.setOrder(1);
327         actionList.add(ab.build());
328         // Create an Apply Action
329         ApplyActionsBuilder aab = new ApplyActionsBuilder();
330         aab.setAction(actionList);
331
332         // Wrap our Apply Action in an Instruction
333         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
334
335         return ib;
336     }
337
338     /**
339      * Create Pop Vlan Instruction - this remove vlan header
340      *
341      * @param ib Map InstructionBuilder without any instructions
342      * @return ib Map InstructionBuilder with instructions
343      */
344     public static InstructionBuilder createPopVlanInstructions(InstructionBuilder ib) {
345
346         List<Action> actionList = Lists.newArrayList();
347         ActionBuilder ab = new ActionBuilder();
348
349         PopVlanActionBuilder popVlanActionBuilder = new PopVlanActionBuilder();
350         ab.setAction(new PopVlanActionCaseBuilder().setPopVlanAction(popVlanActionBuilder.build()).build());
351         ab.setOrder(0);
352         actionList.add(ab.build());
353
354         // Create an Apply Action
355         ApplyActionsBuilder aab = new ApplyActionsBuilder();
356         aab.setAction(actionList);
357
358         // Wrap our Apply Action in an Instruction
359         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
360
361         return ib;
362     }
363
364     /**
365      * Create Set IPv4 Source Instruction
366      *
367      * @param ib        Map InstructionBuilder without any instructions
368      * @param prefixsrc String containing an IPv4 prefix
369      * @return ib Map InstructionBuilder with instructions
370      */
371     public static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
372
373         List<Action> actionList = Lists.newArrayList();
374         ActionBuilder ab = new ActionBuilder();
375
376         SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
377         Ipv4Builder ipsrc = new Ipv4Builder();
378         ipsrc.setIpv4Address(prefixsrc);
379         setNwsrcActionBuilder.setAddress(ipsrc.build());
380         ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
381         ab.setOrder(0);
382         ab.setKey(new ActionKey(0));
383         actionList.add(ab.build());
384
385         // Create an Apply Action
386         ApplyActionsBuilder aab = new ApplyActionsBuilder();
387         aab.setAction(actionList);
388
389         // Wrap our Apply Action in an Instruction
390         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
391
392         return ib;
393     }
394
395     /**
396      * Create Set IPv4 Destination Instruction
397      *
398      * @param ib        Map InstructionBuilder without any instructions
399      * @param prefixdst String containing an IPv4 prefix
400      * @return ib Map InstructionBuilder with instructions
401      */
402     public static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
403
404         List<Action> actionList = Lists.newArrayList();
405         ActionBuilder ab = new ActionBuilder();
406
407         SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
408         Ipv4Builder ipdst = new Ipv4Builder();
409         ipdst.setIpv4Address(prefixdst);
410         setNwDstActionBuilder.setAddress(ipdst.build());
411         ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
412         ab.setOrder(0);
413         ab.setKey(new ActionKey(0));
414         actionList.add(ab.build());
415
416         // Create an Apply Action
417         ApplyActionsBuilder aab = new ApplyActionsBuilder();
418         aab.setAction(actionList);
419
420         // Wrap our Apply Action in an Instruction
421         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
422
423         return ib;
424     }
425
426     /**
427      * Create Drop Instruction
428      *
429      * @param ib Map InstructionBuilder without any instructions
430      * @return ib Map InstructionBuilder with instructions
431      */
432     public static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
433
434         DropActionBuilder dab = new DropActionBuilder();
435         DropAction dropAction = dab.build();
436         ActionBuilder ab = new ActionBuilder();
437         ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
438         ab.setOrder(0);
439         ab.setKey(new ActionKey(0));
440
441         // Add our drop action to a list
442         List<Action> actionList = Lists.newArrayList();
443         actionList.add(ab.build());
444
445         // Create an Apply Action
446         ApplyActionsBuilder aab = new ApplyActionsBuilder();
447         aab.setAction(actionList);
448
449         // Wrap our Apply Action in an Instruction
450         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
451
452         return ib;
453     }
454
455     /**
456      * Create GOTO Table Instruction Builder
457      *
458      * @param ib      Map InstructionBuilder without any instructions
459      * @param tableId short representing a flow table ID short representing a flow table ID
460      * @return ib Map InstructionBuilder with instructions
461      */
462     public static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
463
464         GoToTableBuilder gttb = new GoToTableBuilder();
465         gttb.setTableId(tableId);
466
467         // Wrap our Apply Action in an InstructionBuilder
468         ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
469
470         return ib;
471     }
472
473     /**
474      * Create Set Tunnel ID Instruction Builder
475      *
476      * @param ib       Map InstructionBuilder without any instructions
477      * @param tunnelId BigInteger representing a tunnel ID
478      * @return ib Map InstructionBuilder with instructions
479      */
480     public static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
481
482         List<Action> actionList = Lists.newArrayList();
483         ActionBuilder ab = new ActionBuilder();
484         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
485
486         // Build the Set Tunnel Field Action
487         TunnelBuilder tunnel = new TunnelBuilder();
488         tunnel.setTunnelId(tunnelId);
489         setFieldBuilder.setTunnel(tunnel.build());
490         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
491         ab.setOrder(0);
492         ab.setKey(new ActionKey(0));
493         actionList.add(ab.build());
494
495         ApplyActionsBuilder aab = new ApplyActionsBuilder();
496         aab.setAction(actionList);
497
498         // Wrap the Apply Action in an InstructionBuilder and return
499         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
500
501         return ib;
502     }
503
504     /**
505      * Create Set Source TCP Port Instruction
506      *
507      * @param ib      Map InstructionBuilder without any instructions
508      * @param tcpport Integer representing a source TCP port
509      * @return ib Map InstructionBuilder with instructions
510      */
511     public static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
512
513         List<Action> actionList = Lists.newArrayList();
514         ActionBuilder ab = new ActionBuilder();
515         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
516
517         // Build the Destination TCP Port
518         PortNumber tcpsrcport = new PortNumber(tcpport);
519         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
520         tcpmatch.setTcpSourcePort(tcpsrcport);
521
522         setFieldBuilder.setLayer4Match(tcpmatch.build());
523         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
524         ab.setOrder(0);
525         ab.setKey(new ActionKey(0));
526         actionList.add(ab.build());
527
528         ApplyActionsBuilder aab = new ApplyActionsBuilder();
529         aab.setAction(actionList);
530         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
531
532         return ib;
533     }
534
535     /**
536      * Create Set Destination TCP Port Instruction
537      *
538      * @param ib      Map InstructionBuilder without any instructions
539      * @param tcpport Integer representing a source TCP port
540      * @return ib Map InstructionBuilder with instructions
541      */
542     public static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
543
544         List<Action> actionList = Lists.newArrayList();
545         ActionBuilder ab = new ActionBuilder();
546         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
547
548         // Build the Destination TCP Port
549         PortNumber tcpdstport = new PortNumber(tcpport);
550         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
551         tcpmatch.setTcpDestinationPort(tcpdstport);
552
553         setFieldBuilder.setLayer4Match(tcpmatch.build());
554         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
555         ab.setOrder(0);
556         ab.setKey(new ActionKey(0));
557         actionList.add(ab.build());
558
559         ApplyActionsBuilder aab = new ApplyActionsBuilder();
560         aab.setAction(actionList);
561         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
562
563         return ib;
564     }
565
566     /**
567      * Create Set Source UDP Port Instruction
568      *
569      * @param ib      Map InstructionBuilder without any instructions
570      * @param udpport Integer representing a source UDP port
571      * @return ib Map InstructionBuilder with instructions
572      */
573     public static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
574
575         List<Action> actionList = Lists.newArrayList();
576         ActionBuilder ab = new ActionBuilder();
577         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
578
579         // Build the Destination TCP Port
580         PortNumber udpsrcport = new PortNumber(udpport);
581         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
582         udpmatch.setUdpSourcePort(udpsrcport);
583
584         setFieldBuilder.setLayer4Match(udpmatch.build());
585         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
586         ab.setOrder(0);
587         ab.setKey(new ActionKey(0));
588         actionList.add(ab.build());
589
590         ApplyActionsBuilder aab = new ApplyActionsBuilder();
591         aab.setAction(actionList);
592         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
593
594         return ib;
595     }
596
597     /**
598      * Create Set Destination UDP Port Instruction
599      *
600      * @param ib      Map InstructionBuilder without any instructions
601      * @param udpport Integer representing a destination UDP port
602      * @return ib Map InstructionBuilder with instructions
603      */
604     public static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
605
606         List<Action> actionList = Lists.newArrayList();
607         ActionBuilder ab = new ActionBuilder();
608         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
609
610         // Build the Destination TCP Port
611         PortNumber udpdstport = new PortNumber(udpport);
612         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
613         udpmatch.setUdpDestinationPort(udpdstport);
614
615         setFieldBuilder.setLayer4Match(udpmatch.build());
616         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
617         ab.setOrder(0);
618         ab.setKey(new ActionKey(0));
619         actionList.add(ab.build());
620
621         ApplyActionsBuilder aab = new ApplyActionsBuilder();
622         aab.setAction(actionList);
623         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
624
625         return ib;
626     }
627
628     /**
629      * Create Set ICMP Code Instruction
630      *
631      * @param ib   Map InstructionBuilder without any instructions
632      * @param code short repesenting an ICMP code
633      * @return ib Map InstructionBuilder with instructions
634      */
635
636     public static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
637
638         List<Action> actionList = Lists.newArrayList();
639         ActionBuilder ab = new ActionBuilder();
640         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
641         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
642
643         // Build the ICMPv4 Code Match
644         icmpv4match.setIcmpv4Code(code);
645         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
646
647         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
648         ab.setOrder(0);
649         ab.setKey(new ActionKey(0));
650         actionList.add(ab.build());
651         ApplyActionsBuilder aab = new ApplyActionsBuilder();
652         aab.setAction(actionList);
653
654         // Wrap our Apply Action in an Instruction
655         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
656
657         return ib;
658     }
659
660     /**
661      * Create Set ICMP Code Instruction
662      *
663      * @param ib Map InstructionBuilder without any instructions
664      * @return ib Map InstructionBuilder with instructions
665      */
666     public static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
667
668         List<Action> actionList = Lists.newArrayList();
669         ActionBuilder ab = new ActionBuilder();
670         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
671         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
672
673         // Build the ICMPv4 Code Match
674         icmpv4match.setIcmpv4Code(type);
675         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
676
677         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
678         ab.setOrder(0);
679         ab.setKey(new ActionKey(0));
680         actionList.add(ab.build());
681         ApplyActionsBuilder aab = new ApplyActionsBuilder();
682         aab.setAction(actionList);
683
684         // Wrap our Apply Action in an Instruction
685         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
686
687         return ib;
688     }
689
690     /**
691      * Create Decrement TTL Instruction
692      *
693      * @param ib Map InstructionBuilder without any instructions
694      * @return ib Map InstructionBuilder with instructions
695      */
696     public static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
697         DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
698         DecNwTtl decNwTtl = decNwTtlBuilder.build();
699         ActionBuilder ab = new ActionBuilder();
700         ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
701         ab.setOrder(0);
702         ab.setKey(new ActionKey(0));
703
704         // Add our drop action to a list
705         List<Action> actionList = Lists.newArrayList();
706         actionList.add(ab.build());
707
708         // Create an Apply Action
709         ApplyActionsBuilder aab = new ApplyActionsBuilder();
710         aab.setAction(actionList);
711
712         // Wrap our Apply Action in an Instruction
713         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
714
715         return ib;
716     }
717
718     /**
719      * Set ARP_SHA Instructions
720      * @param ib Map InstructionBuilder
721      * @param macsrc the macsrc
722      * @return instructionbuilder with new instructions
723      */
724     public static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
725
726         List<Action> actionList = Lists.newArrayList();
727         ActionBuilder ab = new ActionBuilder();
728
729         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
730         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
731         ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
732         arpsrc.setAddress(macsrc);
733         arpmatch.setArpSourceHardwareAddress(arpsrc.build());
734         setFieldBuilder.setLayer3Match(arpmatch.build());
735         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
736         ab.setOrder(0);
737         ab.setKey(new ActionKey(0));
738         actionList.add(ab.build());
739
740         ApplyActionsBuilder aab = new ApplyActionsBuilder();
741         aab.setAction(actionList);
742         // Wrap our Apply Action in an Instruction
743         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
744
745         return ib;
746     }
747
748     /**
749      * Set ARP_THA Instructions
750      * @param ib Map InstructionBuilder
751      * @param macdst the macdst
752      * @return instructionbuilder with new attributes
753      */
754     public static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
755
756         List<Action> actionList = Lists.newArrayList();
757         ActionBuilder ab = new ActionBuilder();
758         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
759
760         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
761         ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
762         arpdst.setAddress(macdst);
763         setFieldBuilder.setLayer3Match(arpmatch.build());
764         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
765         ab.setOrder(0);
766         ab.setKey(new ActionKey(0));
767         actionList.add(ab.build());
768
769         ApplyActionsBuilder aab = new ApplyActionsBuilder();
770         aab.setAction(actionList);
771         // Wrap our Apply Action in an Instruction
772         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
773
774         return ib;
775     }
776
777     /**
778      * Set ARP_TPA Instructions
779      * @param ib Map InstructionBuilder
780      * @param dstiparp the dstiparp
781      * @return instructionbuilder with new attributes
782      */
783     public static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
784
785         List<Action> actionList = Lists.newArrayList();
786         ActionBuilder ab = new ActionBuilder();
787         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
788
789         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
790         arpmatch.setArpTargetTransportAddress(dstiparp);
791         setFieldBuilder.setLayer3Match(arpmatch.build());
792         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
793         ab.setOrder(0);
794         ab.setKey(new ActionKey(0));
795         actionList.add(ab.build());
796
797         ApplyActionsBuilder aab = new ApplyActionsBuilder();
798         aab.setAction(actionList);
799         // Wrap our Apply Action in an Instruction
800         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
801
802         return ib;
803     }
804
805     /**
806      * Set ARP_SPA Instructions
807      * @param ib Map InstructionBuilder
808      * @param srciparp the srciparp
809      * @return instructionbuilder with new attributes
810      */
811     public static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
812
813         List<Action> actionList = Lists.newArrayList();
814         ActionBuilder ab = new ActionBuilder();
815         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
816
817         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
818         arpmatch.setArpSourceTransportAddress(srciparp);
819         setFieldBuilder.setLayer3Match(arpmatch.build());
820         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
821         ab.setOrder(0);
822         ab.setKey(new ActionKey(0));
823         actionList.add(ab.build());
824
825         ApplyActionsBuilder aab = new ApplyActionsBuilder();
826         aab.setAction(actionList);
827         // Wrap our Apply Action in an Instruction
828         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
829
830         return ib;
831     }
832
833     /**
834      * Set the Tunnel EndpointIPv4 Source Address
835      * @param ib Map InstructionBuilder
836      * @param srcIp Ipv4Prefix source IP for the tunnel endpoint (TEP)
837      * @return instructionbuilder with new attributes
838      */
839     public static InstructionBuilder createTunnelIpv4SrcInstructions(InstructionBuilder ib, Ipv4Prefix srcIp) {
840
841         List<Action> actionList = new ArrayList<Action>();
842         ActionBuilder ab = new ActionBuilder();
843
844         // Build the tunnel endpoint source IPv4 address
845         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
846
847         // Add the new IPv4 object as the tunnel destination
848         TunnelIpv4MatchBuilder tunnelIpv4MatchBuilder = new TunnelIpv4MatchBuilder();
849         tunnelIpv4MatchBuilder.setTunnelIpv4Source(srcIp);
850         setFieldBuilder.setLayer3Match(tunnelIpv4MatchBuilder.build());
851
852         // Add the IPv4 tunnel src to the set_field value
853         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
854         ab.setOrder(0);
855         ab.setKey(new ActionKey(0));
856         actionList.add(ab.build());
857
858         // Resulting action is a per/flow src TEP (set_field:172.16.100.100->tun_src)
859         ApplyActionsBuilder aab = new ApplyActionsBuilder();
860         aab.setAction(actionList);
861         // Wrap our Apply Action in an Instruction
862         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
863
864         return ib;
865     }
866
867     /**
868      * Set the Tunnel EndpointIPv4 Destination Address
869      * @param ib Map InstructionBuilder
870      * @param dstIp Ipv4Prefix destination IP for the tunnel endpoint (TEP)
871      * @return instructionbuilder with new attributes
872      */
873     public static InstructionBuilder createTunnelIpv4DstInstructions(InstructionBuilder ib, Ipv4Prefix dstIp) {
874
875         List<Action> actionList = new ArrayList<Action>();
876         ActionBuilder ab = new ActionBuilder();
877
878         // Build the tunnel endpoint dst IPv4 address
879         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
880
881         // Add the new IPv4 object as the tunnel destination
882         TunnelIpv4MatchBuilder tunnelIpv4MatchBuilder = new TunnelIpv4MatchBuilder();
883         tunnelIpv4MatchBuilder.setTunnelIpv4Destination(dstIp);
884         setFieldBuilder.setLayer3Match(tunnelIpv4MatchBuilder.build());
885
886         // Add the IPv4 tunnel src to the set_field value
887         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
888         ab.setOrder(0);
889         ab.setKey(new ActionKey(0));
890         actionList.add(ab.build());
891
892         // Resulting action is a per/flow src TEP (set_field:172.16.100.100->tun_src)
893         ApplyActionsBuilder aab = new ApplyActionsBuilder();
894         aab.setAction(actionList);
895         // Wrap our Apply Action in an Instruction
896         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
897
898         return ib;
899     }
900
901     /**
902      * Set IPv4 Source Address Instructions
903      * @param ib Map InstructionBuilder
904      * @param metaData BigInteger representing the OpenFlow metadata
905      * @param metaDataMask  BigInteger representing the OpenFlow metadata mask
906      * @return instructionbuilder with new attributes
907      */
908     public static InstructionBuilder createMetadataInstructions(InstructionBuilder ib, BigInteger metaData, BigInteger metaDataMask) {
909
910         WriteMetadataBuilder aab = new WriteMetadataBuilder();
911         aab.setMetadata(metaData);
912         aab.setMetadataMask(metaDataMask);
913         ib.setInstruction(new WriteMetadataCaseBuilder().setWriteMetadata(aab.build()).build());
914
915         /**
916         *
917         * TODO Determine why the following fails serialization
918         * with a null value. Per the spec it is optional.
919         * The metadata match, the Flowmod works w/o an accompanying mask.
920         *
921         * if (metaDataMask != null) {
922         *    aab.setMetadataMask(metaDataMask);
923         * }
924         *
925         */
926
927         return ib;
928     }
929
930     public static InstructionBuilder createDlSrcInstructions(InstructionBuilder ib, MacAddress macAddress) {
931
932         List<Action> actionList = Lists.newArrayList();
933         ActionBuilder ab = new ActionBuilder();
934
935         SetDlSrcActionBuilder dlSrcActionBuilder= new SetDlSrcActionBuilder();
936
937         dlSrcActionBuilder.setAddress(macAddress);
938
939         ab.setAction(new SetDlSrcActionCaseBuilder().setSetDlSrcAction(dlSrcActionBuilder.build()).build());
940         ab.setOrder(0);
941         ab.setKey(new ActionKey(0));
942         actionList.add(ab.build());
943
944
945         // Create an Apply Action
946         ApplyActionsBuilder aab = new ApplyActionsBuilder();
947         aab.setAction(actionList);
948
949         // Wrap our Apply Action in an Instruction
950         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
951
952         return ib;
953     }
954
955     public static InstructionBuilder createDlDstInstructions(InstructionBuilder ib, MacAddress macAddress) {
956
957         List<Action> actionList = Lists.newArrayList();
958         ActionBuilder ab = new ActionBuilder();
959
960         SetDlDstActionBuilder dlDstActionBuilder= new SetDlDstActionBuilder();
961
962         dlDstActionBuilder.setAddress(macAddress);
963
964         ab.setAction(new SetDlDstActionCaseBuilder().setSetDlDstAction(dlDstActionBuilder.build()).build());
965         ab.setOrder(0);
966         ab.setKey(new ActionKey(0));
967         actionList.add(ab.build());
968
969         // Create an Apply Action
970         ApplyActionsBuilder aab = new ApplyActionsBuilder();
971         aab.setAction(actionList);
972
973         // Wrap our Apply Action in an Instruction
974         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
975
976         return ib;
977     }
978
979     public static ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action>
980                   actionList (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action... actions) {
981
982         ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> alist
983             = new ArrayList<>();
984         int count = 0;
985         for (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action : actions) {
986             alist.add(new ActionBuilder()
987                 .setOrder(count)
988                 .setKey(new ActionKey(count))
989                 .setAction(action)
990                 .build());
991             count++;
992         }
993         return alist;
994     }
995
996     public static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction
997         applyActionIns(org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action... actions) {
998
999         return new ApplyActionsCaseBuilder()
1000             .setApplyActions(new ApplyActionsBuilder()
1001                 .setAction(actionList(actions))
1002                 .build())
1003             .build();
1004     }
1005
1006     public static Instructions getInstructions(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction... instructions) {
1007         ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction> ins
1008             = new ArrayList<>();
1009         int order = 0;
1010         for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction i : instructions) {
1011             ins.add(new InstructionBuilder()
1012                 .setOrder(order)
1013                 .setKey(new InstructionKey(order))
1014                 .setInstruction(i)
1015                 .build());
1016             order++;
1017         }
1018         return new InstructionsBuilder().setInstruction(ins).build();
1019     }
1020
1021     public static Instructions dropInstructions() {
1022         return getInstructions(applyActionIns(dropAction()));
1023     }
1024
1025     /**
1026      * Get a list of Instructions containing Nicira extensions that can have
1027      * additional OF/OXM instructions added to the returned Instruction list
1028      *
1029      * @param instructions org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instructions
1030      * @return instruction list that additional
1031      */
1032     public static List<Instruction> getInstructionList(
1033             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction... instructions) {
1034         ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction> ins
1035                 = new ArrayList<>();
1036         int order = 0;
1037         for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction i : instructions) {
1038             ins.add(new InstructionBuilder()
1039                     .setOrder(order++)
1040                     .setInstruction(i)
1041                     .build());
1042         }
1043         return ins;
1044     }
1045 }