2 * Copyright (C) 2013 Red Hat, Inc.
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
8 * Authors : Madhu Venugopal, Brent Salisbury, Dave Tucker
10 package org.opendaylight.ovsdb.openstack.netvirt.providers;
12 import com.google.common.base.Optional;
13 import com.google.common.util.concurrent.CheckedFuture;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
20 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
21 import org.opendaylight.controller.sal.core.Node;
22 import org.opendaylight.controller.sal.utils.HexEncode;
23 import org.opendaylight.controller.sal.utils.Status;
24 import org.opendaylight.controller.sal.utils.StatusCode;
25 import org.opendaylight.ovsdb.lib.notation.Row;
26 import org.opendaylight.ovsdb.lib.notation.UUID;
27 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
28 import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
29 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
30 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProvider;
31 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
32 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
33 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
34 import org.opendaylight.ovsdb.plugin.api.StatusWithUuid;
35 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
36 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
37 import org.opendaylight.ovsdb.schema.openvswitch.Port;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
122 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
124 import com.google.common.base.Preconditions;
125 import com.google.common.collect.Lists;
126 import com.google.common.collect.Maps;
127 import org.slf4j.Logger;
128 import org.slf4j.LoggerFactory;
130 import java.math.BigInteger;
131 import java.net.InetAddress;
132 import java.util.List;
133 import java.util.Map;
134 import java.util.Set;
135 import java.util.concurrent.ExecutionException;
138 * Open vSwitch OpenFlow 1.3 Networking Provider for OpenStack Neutron
140 public class OF13Provider implements NetworkingProvider {
141 private static final Logger logger = LoggerFactory.getLogger(OF13Provider.class);
142 private DataBroker dataBroker;
143 private static final short TABLE_0_DEFAULT_INGRESS = 0;
144 private static final short TABLE_1_ISOLATE_TENANT = 10;
145 private static final short TABLE_2_LOCAL_FORWARD = 20;
146 private static Long groupId = 1L;
148 private volatile org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService configurationService;
149 private volatile BridgeConfigurationManager bridgeConfigurationManager;
150 private volatile TenantNetworkManager tenantNetworkManager;
151 private volatile OvsdbConfigurationService ovsdbConfigurationService;
152 private volatile OvsdbConnectionService connectionService;
153 private volatile MdsalConsumer mdsalConsumer;
155 public OF13Provider(){
160 public boolean hasPerTenantTunneling() {
164 private Status getTunnelReadinessStatus (Node node, String tunnelKey) {
165 InetAddress srcTunnelEndPoint = configurationService.getTunnelEndPoint(node);
166 if (srcTunnelEndPoint == null) {
167 logger.error("Tunnel Endpoint not configured for Node {}", node);
168 return new Status(StatusCode.NOTFOUND, "Tunnel Endpoint not configured for "+ node);
171 if (!bridgeConfigurationManager.isNodeNeutronReady(node)) {
172 logger.error(node+" is not Overlay ready");
173 return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready");
176 if (!tenantNetworkManager.isTenantNetworkPresentInNode(node, tunnelKey)) {
177 logger.debug(node+" has no VM corresponding to segment "+ tunnelKey);
178 return new Status(StatusCode.NOTACCEPTABLE, node+" has no VM corresponding to segment "+ tunnelKey);
180 return new Status(StatusCode.SUCCESS);
183 private String getTunnelName(String tunnelType, InetAddress dst) {
184 return tunnelType+"-"+dst.getHostAddress();
187 private boolean isTunnelPresent(Node node, String tunnelName, String bridgeUUID) throws Exception {
188 Preconditions.checkNotNull(ovsdbConfigurationService);
189 Row bridgeRow = ovsdbConfigurationService
190 .getRow(node, ovsdbConfigurationService.getTableName(node, Bridge.class), bridgeUUID);
191 Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeRow);
192 if (bridge != null) {
193 Set<UUID> ports = bridge.getPortsColumn().getData();
194 for (UUID portUUID : ports) {
195 Row portRow = ovsdbConfigurationService
196 .getRow(node, ovsdbConfigurationService.getTableName(node, Port.class), portUUID.toString());
197 Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow);
198 if (port != null && tunnelName.equalsIgnoreCase(port.getName())) return true;
204 private String getPortUuid(Node node, String name, String bridgeUUID) throws Exception {
205 Preconditions.checkNotNull(ovsdbConfigurationService);
206 Row bridgeRow = ovsdbConfigurationService
207 .getRow(node, ovsdbConfigurationService.getTableName(node, Bridge.class), bridgeUUID);
208 Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeRow);
209 if (bridge != null) {
210 Set<UUID> ports = bridge.getPortsColumn().getData();
211 for (UUID portUUID : ports) {
212 Row portRow = ovsdbConfigurationService
213 .getRow(node, ovsdbConfigurationService.getTableName(node, Port.class), portUUID.toString());
214 Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow);
215 if (port != null && name.equalsIgnoreCase(port.getName())) return portUUID.toString();
221 private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst) {
222 Preconditions.checkNotNull(ovsdbConfigurationService);
224 String bridgeUUID = null;
225 String tunnelBridgeName = configurationService.getIntegrationBridgeName();
226 Map<String, Row> bridgeTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Bridge.class));
227 if (bridgeTable != null) {
228 for (String uuid : bridgeTable.keySet()) {
229 Bridge bridge = ovsdbConfigurationService.getTypedRow(node,Bridge.class, bridgeTable.get(uuid));
230 if (bridge.getName().equals(tunnelBridgeName)) {
236 if (bridgeUUID == null) {
237 logger.error("Could not find Bridge {} in {}", tunnelBridgeName, node);
238 return new Status(StatusCode.NOTFOUND, "Could not find "+tunnelBridgeName+" in "+node);
240 String portName = getTunnelName(tunnelType, dst);
242 if (this.isTunnelPresent(node, portName, bridgeUUID)) {
243 logger.trace("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node);
244 return new Status(StatusCode.SUCCESS);
247 Port tunnelPort = ovsdbConfigurationService.createTypedRow(node, Port.class);
248 tunnelPort.setName(portName);
249 StatusWithUuid statusWithUuid = ovsdbConfigurationService
250 .insertRow(node, ovsdbConfigurationService.getTableName(node, Port.class), bridgeUUID, tunnelPort.getRow());
251 if (!statusWithUuid.isSuccess()) {
252 logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID);
253 return statusWithUuid;
256 String tunnelPortUUID = statusWithUuid.getUuid().toString();
257 String interfaceUUID = null;
259 while ((interfaceUUID == null) && (timeout > 0)) {
260 Row portRow = ovsdbConfigurationService
261 .getRow(node, ovsdbConfigurationService.getTableName(node, Port.class), tunnelPortUUID);
262 tunnelPort = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow);
263 Set<UUID> interfaces = tunnelPort.getInterfacesColumn().getData();
264 if (interfaces == null || interfaces.size() == 0) {
265 // Wait for the OVSDB update to sync up the Local cache.
270 interfaceUUID = interfaces.toArray()[0].toString();
271 Row intfRow = ovsdbConfigurationService
272 .getRow(node, ovsdbConfigurationService.getTableName(node, Interface.class), interfaceUUID);
273 Interface intf = ovsdbConfigurationService.getTypedRow(node, Interface.class, intfRow);
274 if (intf == null) interfaceUUID = null;
277 if (interfaceUUID == null) {
278 logger.error("Cannot identify Tunnel Interface for port {}/{}", portName, tunnelPortUUID);
279 return new Status(StatusCode.INTERNALERROR);
282 Interface tunInterface = ovsdbConfigurationService.createTypedRow(node, Interface.class);
283 tunInterface.setType(tunnelType);
284 Map<String, String> options = Maps.newHashMap();
285 options.put("key", "flow");
286 options.put("local_ip", src.getHostAddress());
287 options.put("remote_ip", dst.getHostAddress());
288 tunInterface.setOptions(options);
289 Status status = ovsdbConfigurationService
290 .updateRow(node, ovsdbConfigurationService.getTableName(node, Interface.class), tunnelPortUUID, interfaceUUID, tunInterface.getRow());
291 logger.debug("Tunnel {} add status : {}", tunInterface, status);
293 } catch (Exception e) {
294 logger.error("Exception in addTunnelPort", e);
295 return new Status(StatusCode.INTERNALERROR);
299 /* delete port from ovsdb port table */
300 private Status deletePort(Node node, String bridgeName, String portName) {
301 Preconditions.checkNotNull(ovsdbConfigurationService);
303 String bridgeUUID = null;
304 Map<String, Row> bridgeTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Bridge.class));
305 if (bridgeTable != null) {
306 for (String uuid : bridgeTable.keySet()) {
307 Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeTable.get(uuid));
308 if (bridge.getName().equals(bridgeName)) {
314 if (bridgeUUID == null) {
315 logger.debug("Could not find Bridge {} in {}", bridgeName, node);
316 return new Status(StatusCode.SUCCESS);
319 String portUUID = this.getPortUuid(node, portName, bridgeUUID);
320 Status status = new Status(StatusCode.SUCCESS);
321 if (portUUID != null) {
322 status = ovsdbConfigurationService
323 .deleteRow(node, ovsdbConfigurationService.getTableName(node, Port.class), portUUID);
324 if (!status.isSuccess()) {
325 logger.error("Failed to delete port {} in {} status : {}", portName, bridgeUUID,
329 logger.debug("Port {} delete status : {}", portName, status);
332 } catch (Exception e) {
333 logger.error("Exception in deletePort", e);
334 return new Status(StatusCode.INTERNALERROR);
338 private Status deleteTunnelPort(Node node, String tunnelType, InetAddress src, InetAddress dst) {
339 String tunnelBridgeName = configurationService.getIntegrationBridgeName();
340 String portName = getTunnelName(tunnelType, dst);
341 return deletePort(node, tunnelBridgeName, portName);
344 private Status deletePhysicalPort(Node node, String phyIntfName) {
345 String intBridgeName = configurationService.getIntegrationBridgeName();
346 return deletePort(node, intBridgeName, phyIntfName);
349 private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
353 * Match: VM sMac and Local Ingress Port
354 * Action:Action: Set Tunnel ID and GOTO Local Table (5)
357 handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, true);
362 * Match: Drop any remaining Ingress Local VM Packets
363 * Action: Drop w/ a low priority
366 handleDropSrcIface(dpid, localPort, true);
371 * Match: Match TunID and Destination DL/dMAC Addr
372 * Action: Output Port
373 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
376 handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, true);
381 * Match: Tunnel ID and dMAC (::::FF:FF)
382 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
383 * actions=output:2,3,4,5
386 handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, true);
389 * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
394 * Match: Any remaining Ingress Local VM Packets
395 * Action: Drop w/ a low priority
396 * -------------------------------------------
397 * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
400 handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, true);
405 * Match: Any Remaining Flows w/a TunID
406 * Action: Drop w/ a low priority
407 * table=2,priority=8192,tun_id=0x5 actions=drop
410 handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, true);
413 private void removeLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
417 * Match: VM sMac and Local Ingress Port
418 * Action:Action: Set Tunnel ID and GOTO Local Table (5)
421 handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, false);
426 * Match: Drop any remaining Ingress Local VM Packets
427 * Action: Drop w/ a low priority
430 handleDropSrcIface(dpid, localPort, false);
435 * Match: Match TunID and Destination DL/dMAC Addr
436 * Action: Output Port
437 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
440 handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, false);
445 * Match: Tunnel ID and dMAC (::::FF:FF)
446 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
447 * actions=output:2,3,4,5
450 handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, false);
453 private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
457 * Match: Ingress Port, Tunnel ID
458 * Action: GOTO Local Table (20)
461 handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
466 * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
467 * Action: Flood to selected destination TEPs
468 * -------------------------------------------
469 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
470 * actions=output:10,output:11,goto_table:2
473 handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
477 private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
481 * Match: Drop any remaining Ingress Local VM Packets
482 * Action: Drop w/ a low priority
483 * -------------------------------------------
484 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
485 * actions=output:11,goto_table:2
488 handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, true);
491 private void removeRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
495 * Match: Drop any remaining Ingress Local VM Packets
496 * Action: Drop w/ a low priority
497 * -------------------------------------------
498 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
499 * actions=output:11,goto_table:2
502 handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, false);
505 /* Remove tunnel rules if last node in this tenant network */
506 private void removePerTunnelRules(Node node, Long dpid, String segmentationId, long tunnelOFPort) {
508 * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
513 * Match: Any remaining Ingress Local VM Packets
514 * Action: Drop w/ a low priority
515 * -------------------------------------------
516 * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
519 handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, false);
524 * Match: Any Remaining Flows w/a TunID
525 * Action: Drop w/ a low priority
526 * table=2,priority=8192,tun_id=0x5 actions=drop
529 handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, false);
534 * Match: Ingress Port, Tunnel ID
535 * Action: GOTO Local Table (10)
538 handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
543 * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
544 * Action: Flood to selected destination TEPs
545 * -------------------------------------------
546 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
547 * actions=output:10,output:11,goto_table:2
550 handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
553 private void programLocalVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
557 * Match: VM sMac and Local Ingress Port
558 * Action: Set VLAN ID and GOTO Local Table 1
561 handleLocalInPortSetVlan(dpid, TABLE_0_DEFAULT_INGRESS,
562 TABLE_1_ISOLATE_TENANT, segmentationId, localPort,
568 * Match: Drop any remaining Ingress Local VM Packets
569 * Action: Drop w/ a low priority
572 handleDropSrcIface(dpid, localPort, true);
577 * Match: Match VLAN ID and Destination DL/dMAC Addr
578 * Action: strip vlan, output to local port
579 * Example: table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions= strip vlan, output:2
582 handleLocalVlanUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
583 localPort, attachedMac, true);
588 * Match: VLAN ID and dMAC (::::FF:FF)
589 * Action: strip vlan, output to all local ports in this vlan
590 * Example: table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
591 * actions= strip_vlan, output:2,3,4,5
594 handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
600 * Match: Any Remaining Flows w/a VLAN ID
601 * Action: Drop w/ a low priority
602 * Example: table=2,priority=8192,vlan_id=0x5 actions=drop
605 handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
609 private void removeLocalVlanRules(Node node, Long dpid,
610 String segmentationId, String attachedMac,
615 * Match: VM sMac and Local Ingress Port
616 * Action: Set VLAN ID and GOTO Local Table 1
619 handleLocalInPortSetVlan(dpid, TABLE_0_DEFAULT_INGRESS,
620 TABLE_1_ISOLATE_TENANT, segmentationId, localPort,
626 * Match: Drop any remaining Ingress Local VM Packets
627 * Action: Drop w/ a low priority
630 handleDropSrcIface(dpid, localPort, false);
635 * Match: Match VLAN ID and Destination DL/dMAC Addr
636 * Action: strip vlan, output to local port
637 * Example: table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions= strip vlan, output:2
640 handleLocalVlanUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
641 localPort, attachedMac, false);
646 * Match: VLAN ID and dMAC (::::FF:FF)
647 * Action: strip vlan, output to all local ports in this vlan
648 * Example: table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
649 * actions= strip_vlan, output:2,3,4,5
652 handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
656 private void programLocalIngressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
660 * Match: Ingress port = physical interface, Vlan ID
661 * Action: GOTO Local Table 2
664 handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD,
665 segmentationId, ethPort, true);
670 * Match: Match VLAN ID and L2 ::::FF:FF Flooding
671 * Action: Flood to local and remote VLAN members
672 * -------------------------------------------
673 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
674 * actions=output:10 (eth port),goto_table:2
677 handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
678 segmentationId, ethPort, true);
681 private void programRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
685 * Match: Destination MAC is local VM MAC and vlan id
686 * Action: go to table 2
687 * -------------------------------------------
688 * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
689 * actions=goto_table:2
692 handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
693 segmentationId, ethPort, attachedMac, true);
699 * Action: Go to table 2
700 * -------------------------------------------
701 * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
704 handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
705 segmentationId, ethPort, true);
708 private void removeRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
712 * Match: Destination MAC is local VM MAC and vlan id
713 * Action: go to table 2
714 * -------------------------------------------
715 * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
716 * actions=goto_table:2
719 handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
720 segmentationId, ethPort, attachedMac, false);
723 private void removePerVlanRules(Node node, Long dpid, String segmentationId, long ethPort) {
727 * Match: Any Remaining Flows w/a VLAN ID
728 * Action: Drop w/ a low priority
729 * Example: table=2,priority=8192,vlan_id=0x5 actions=drop
732 handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
738 * Match: Ingress port = physical interface, Vlan ID
739 * Action: GOTO Local Table 2
742 handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD,
743 segmentationId, ethPort, false);
748 * Match: Match VLAN ID and L2 ::::FF:FF Flooding
749 * Action: Flood to local and remote VLAN members
750 * -------------------------------------------
751 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
752 * actions=output:10 (eth port),goto_table:2
755 handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
756 segmentationId, ethPort, false);
762 * Action: Go to table 2
763 * -------------------------------------------
764 * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
767 handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
768 segmentationId, ethPort, false);
770 private Long getDpid (Node node, String bridgeUuid) {
771 Preconditions.checkNotNull(ovsdbConfigurationService);
773 Row bridgeRow = ovsdbConfigurationService
774 .getRow(node, ovsdbConfigurationService.getTableName(node, Bridge.class), bridgeUuid);
775 Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeRow);
776 Set<String> dpids = bridge.getDatapathIdColumn().getData();
777 if (dpids == null || dpids.size() == 0) return 0L;
778 return HexEncode.stringToLong((String) dpids.toArray()[0]);
779 } catch (Exception e) {
780 logger.error("Error finding Bridge's OF DPID", e);
785 private Long getIntegrationBridgeOFDPID (Node node) {
787 String bridgeName = configurationService.getIntegrationBridgeName();
788 String brIntId = this.getInternalBridgeUUID(node, bridgeName);
789 if (brIntId == null) {
790 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
794 return getDpid(node, brIntId);
795 } catch (Exception e) {
796 logger.error("Error finding Integration Bridge's OF DPID", e);
801 private Long getExternalBridgeDpid (Node node) {
803 String bridgeName = configurationService.getExternalBridgeName();
804 String brUuid = this.getInternalBridgeUUID(node, bridgeName);
805 if (brUuid == null) {
806 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
810 return getDpid(node, brUuid);
811 } catch (Exception e) {
812 logger.error("Error finding External Bridge's OF DPID", e);
817 private void programLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
819 Long dpid = this.getIntegrationBridgeOFDPID(node);
821 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
825 Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
826 if (of_ports == null || of_ports.size() <= 0) {
827 logger.debug("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
830 long localPort = (Long)of_ports.toArray()[0];
832 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
833 if (externalIds == null) {
834 logger.error("No external_ids seen in {}", intf);
838 String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC);
839 if (attachedMac == null) {
840 logger.error("No AttachedMac seen in {}", intf);
844 /* Program local rules based on network type */
845 if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
846 logger.debug("Program local vlan rules for interface {}", intf.getName());
847 programLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
848 } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
849 networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
850 logger.debug("Program local bridge rules for interface {}", intf.getName());
851 programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
853 } catch (Exception e) {
854 logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
858 private void removeLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
860 Long dpid = this.getIntegrationBridgeOFDPID(node);
862 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
866 Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
867 if (of_ports == null || of_ports.size() <= 0) {
868 logger.debug("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
871 long localPort = (Long)of_ports.toArray()[0];
873 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
874 if (externalIds == null) {
875 logger.error("No external_ids seen in {}", intf);
879 String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC);
880 if (attachedMac == null) {
881 logger.error("No AttachedMac seen in {}", intf);
885 /* Program local rules based on network type */
886 if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
887 logger.debug("Remove local vlan rules for interface {}", intf.getName());
888 removeLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
889 } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
890 networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
891 logger.debug("Remove local bridge rules for interface {}", intf.getName());
892 removeLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
894 } catch (Exception e) {
895 logger.error("Exception in removing Local Rules for "+intf+" on "+node, e);
899 private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
900 Interface intf, boolean local) {
902 Preconditions.checkNotNull(ovsdbConfigurationService);
906 Long dpid = this.getIntegrationBridgeOFDPID(node);
908 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
912 Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
913 if (of_ports == null || of_ports.size() <= 0) {
914 logger.debug("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
917 long localPort = (Long)of_ports.toArray()[0];
919 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
920 if (externalIds == null) {
921 logger.error("No external_ids seen in {}", intf);
925 String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC);
926 if (attachedMac == null) {
927 logger.error("No AttachedMac seen in {}", intf);
931 Map<String, Row> intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class));
933 for (Row row : intfs.values()) {
934 Interface tunIntf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row);
935 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
936 of_ports = tunIntf.getOpenFlowPortColumn().getData();
937 if (of_ports == null || of_ports.size() <= 0) {
938 logger.debug("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
941 long tunnelOFPort = (Long)of_ports.toArray()[0];
943 if (tunnelOFPort == -1) {
944 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
947 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
950 programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
952 logger.trace("program local ingress tunnel rules: node" + node.getNodeIDString() + " intf " + intf.getName());
954 programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
960 } catch (Exception e) {
965 private void removeTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
966 Interface intf, boolean local, boolean isLastInstanceOnNode) {
968 Preconditions.checkNotNull(ovsdbConfigurationService);
971 Long dpid = this.getIntegrationBridgeOFDPID(node);
973 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
977 Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
978 if (of_ports == null || of_ports.size() <= 0) {
979 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
982 long localPort = (Long)of_ports.toArray()[0];
984 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
985 if (externalIds == null) {
986 logger.error("No external_ids seen in {}", intf);
990 String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC);
991 if (attachedMac == null) {
992 logger.error("No AttachedMac seen in {}", intf);
996 Map<String, Row> intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class));
998 for (Row row : intfs.values()) {
999 Interface tunIntf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row);
1000 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
1001 of_ports = tunIntf.getOpenFlowPortColumn().getData();
1002 if (of_ports == null || of_ports.size() <= 0) {
1003 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
1006 long tunnelOFPort = (Long)of_ports.toArray()[0];
1008 if (tunnelOFPort == -1) {
1009 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
1012 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
1015 removeRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
1017 if (local && isLastInstanceOnNode) {
1018 removePerTunnelRules(node, dpid, segmentationId, tunnelOFPort);
1024 } catch (Exception e) {
1025 logger.error("", e);
1029 private void programVlanRules (NeutronNetwork network, Node node, Interface intf) {
1030 Preconditions.checkNotNull(ovsdbConfigurationService);
1031 logger.debug("Program vlan rules for interface {}", intf.getName());
1034 Long dpid = this.getIntegrationBridgeOFDPID(node);
1036 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1040 Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
1042 while ((of_ports == null) && (timeout > 0)) {
1043 of_ports = intf.getOpenFlowPortColumn().getData();
1044 if (of_ports == null || of_ports.size() <= 0) {
1045 // Wait for the OVSDB update to sync up the Local cache.
1050 if (of_ports == null || of_ports.size() <= 0) {
1051 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1055 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
1056 if (externalIds == null) {
1057 logger.error("No external_ids seen in {}", intf);
1061 String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC);
1062 if (attachedMac == null) {
1063 logger.error("No AttachedMac seen in {}", intf);
1067 Map<String, Row> intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class));
1068 if (intfs != null) {
1069 for (Row row : intfs.values()) {
1070 Interface ethIntf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row);
1071 if (ethIntf.getName().equalsIgnoreCase(bridgeConfigurationManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()))) {
1072 of_ports = ethIntf.getOpenFlowPortColumn().getData();
1074 while ((of_ports == null) && (timeout > 0)) {
1075 of_ports = ethIntf.getOpenFlowPortColumn().getData();
1076 if (of_ports == null || of_ports.size() <= 0) {
1077 // Wait for the OVSDB update to sync up the Local cache.
1083 if (of_ports == null || of_ports.size() <= 0) {
1084 logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1087 long ethOFPort = (Long)of_ports.toArray()[0];
1089 if (ethOFPort == -1) {
1090 logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1091 throw new Exception("port number < 0");
1093 logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1095 programRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1096 programLocalIngressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1101 } catch (Exception e) {
1102 logger.error("", e);
1106 private void removeVlanRules (NeutronNetwork network, Node node,
1107 Interface intf, boolean isLastInstanceOnNode) {
1108 Preconditions.checkNotNull(ovsdbConfigurationService);
1109 logger.debug("Remove vlan rules for interface {}", intf.getName());
1113 Long dpid = this.getIntegrationBridgeOFDPID(node);
1115 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1119 Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
1120 if (of_ports == null || of_ports.size() <= 0) {
1121 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1125 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
1126 if (externalIds == null) {
1127 logger.error("No external_ids seen in {}", intf);
1131 String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC);
1132 if (attachedMac == null) {
1133 logger.error("No AttachedMac seen in {}", intf);
1137 Map<String, Row> intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class));
1138 if (intfs != null) {
1139 for (Row row : intfs.values()) {
1140 Interface ethIntf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row);
1141 if (ethIntf.getName().equalsIgnoreCase(bridgeConfigurationManager.getPhysicalInterfaceName(node,
1142 network.getProviderPhysicalNetwork()))) {
1143 of_ports = ethIntf.getOpenFlowPortColumn().getData();
1144 if (of_ports == null || of_ports.size() <= 0) {
1145 logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1148 long ethOFPort = (Long)of_ports.toArray()[0];
1150 if (ethOFPort == -1) {
1151 logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1152 throw new Exception("port number < 0");
1154 logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1156 removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1157 if (isLastInstanceOnNode) {
1158 removePerVlanRules(node, dpid, network.getProviderSegmentationID(), ethOFPort);
1164 } catch (Exception e) {
1165 logger.error("", e);
1170 public Status handleInterfaceUpdate(NeutronNetwork network, Node srcNode, Interface intf) {
1171 Preconditions.checkNotNull(connectionService);
1172 List<Node> nodes = connectionService.getNodes();
1173 nodes.remove(srcNode);
1174 this.programLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf);
1176 if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1177 this.programVlanRules(network, srcNode, intf);
1178 } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1179 || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)){
1180 for (Node dstNode : nodes) {
1181 InetAddress src = configurationService.getTunnelEndPoint(srcNode);
1182 InetAddress dst = configurationService.getTunnelEndPoint(dstNode);
1183 Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst);
1184 if (status.isSuccess()) {
1185 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
1187 addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src);
1188 if (status.isSuccess()) {
1189 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
1194 return new Status(StatusCode.SUCCESS);
1197 private Status triggerInterfaceUpdates(Node node) {
1198 Preconditions.checkNotNull(ovsdbConfigurationService);
1200 Map<String, Row> intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class));
1201 if (intfs != null) {
1202 for (Row row : intfs.values()) {
1203 Interface intf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row);
1204 NeutronNetwork network = tenantNetworkManager.getTenantNetwork(intf);
1205 logger.debug("Trigger Interface update for {}", intf);
1206 if (network != null) {
1207 this.handleInterfaceUpdate(network, node, intf);
1211 } catch (Exception e) {
1212 logger.error("Error Triggering the lost interface updates for "+ node, e);
1213 return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
1215 return new Status(StatusCode.SUCCESS);
1218 public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
1219 // TODO Auto-generated method stub
1224 public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, Interface intf,
1225 boolean isLastInstanceOnNode) {
1226 Preconditions.checkNotNull(connectionService);
1227 Status status = new Status(StatusCode.SUCCESS);
1228 List<Node> nodes = connectionService.getNodes();
1229 nodes.remove(srcNode);
1231 logger.info("Delete intf " + intf.getName() + " isLastInstanceOnNode " + isLastInstanceOnNode);
1232 List<String> phyIfName = bridgeConfigurationManager.getAllPhysicalInterfaceNames(srcNode);
1233 if (intf.getTypeColumn().getData().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)
1234 || intf.getTypeColumn().getData().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
1235 /* Delete tunnel port */
1237 Map<String, String> options = intf.getOptionsColumn().getData();
1238 InetAddress src = InetAddress.getByName(options.get("local_ip"));
1239 InetAddress dst = InetAddress.getByName(options.get("remote_ip"));
1240 status = deleteTunnelPort(srcNode, intf.getTypeColumn().getData(), src, dst);
1241 } catch (Exception e) {
1242 logger.error(e.getMessage(), e);
1244 } else if (phyIfName.contains(intf.getName())) {
1245 deletePhysicalPort(srcNode, intf.getName());
1247 /* delete all other interfaces */
1248 this.removeLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(),
1251 if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1252 this.removeVlanRules(network, srcNode,
1253 intf, isLastInstanceOnNode);
1254 } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1255 || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
1257 for (Node dstNode : nodes) {
1258 InetAddress src = configurationService.getTunnelEndPoint(srcNode);
1259 InetAddress dst = configurationService.getTunnelEndPoint(dstNode);
1260 logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode" + srcNode.getNodeIDString());
1261 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1262 dst, srcNode, intf, true, isLastInstanceOnNode);
1263 logger.info("Remove tunnel rules for interface " + intf.getName() + " on dstNode" + dstNode.getNodeIDString());
1264 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1265 src, dstNode, intf, false, isLastInstanceOnNode);
1273 public void initializeFlowRules(Node node) {
1274 this.initializeFlowRules(node, configurationService.getIntegrationBridgeName());
1275 this.initializeFlowRules(node, configurationService.getExternalBridgeName());
1276 this.triggerInterfaceUpdates(node);
1279 private void initializeFlowRules(Node node, String bridgeName) {
1280 String bridgeUuid = this.getInternalBridgeUUID(node, bridgeName);
1281 if (bridgeUuid == null) {
1285 Long dpid = getDpid(node, bridgeUuid);
1288 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1295 * Match: LLDP (0x88CCL)
1296 * Action: Packet_In to Controller Reserved Port
1299 writeLLDPRule(dpid);
1300 if (bridgeName.equals(configurationService.getExternalBridgeName())) {
1301 writeNormalRule(dpid);
1306 * Create an LLDP Flow Rule to encapsulate into
1307 * a packet_in that is sent to the controller
1308 * for topology handling.
1309 * Match: Ethertype 0x88CCL
1310 * Action: Punt to Controller in a Packet_In msg
1313 private void writeLLDPRule(Long dpidLong) {
1315 String nodeName = "openflow:" + dpidLong;
1316 EtherType etherType = new EtherType(0x88CCL);
1318 MatchBuilder matchBuilder = new MatchBuilder();
1319 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1320 FlowBuilder flowBuilder = new FlowBuilder();
1322 // Create Match(es) and Set them in the FlowBuilder Object
1323 flowBuilder.setMatch(createEtherTypeMatch(matchBuilder, etherType).build());
1325 // Create the OF Actions and Instructions
1326 InstructionBuilder ib = new InstructionBuilder();
1327 InstructionsBuilder isb = new InstructionsBuilder();
1329 // Instructions List Stores Individual Instructions
1330 List<Instruction> instructions = Lists.newArrayList();
1332 // Call the InstructionBuilder Methods Containing Actions
1333 createSendToControllerInstructions(ib);
1335 ib.setKey(new InstructionKey(0));
1336 instructions.add(ib.build());
1338 // Add InstructionBuilder to the Instruction(s)Builder List
1339 isb.setInstruction(instructions);
1341 // Add InstructionsBuilder to FlowBuilder
1342 flowBuilder.setInstructions(isb.build());
1344 String flowId = "LLDP";
1345 flowBuilder.setId(new FlowId(flowId));
1346 FlowKey key = new FlowKey(new FlowId(flowId));
1347 flowBuilder.setBarrier(true);
1348 flowBuilder.setTableId((short) 0);
1349 flowBuilder.setKey(key);
1350 flowBuilder.setFlowName(flowId);
1351 flowBuilder.setHardTimeout(0);
1352 flowBuilder.setIdleTimeout(0);
1353 writeFlow(flowBuilder, nodeBuilder);
1357 * Create a NORMAL Table Miss Flow Rule
1359 * Action: forward to NORMAL pipeline
1362 private void writeNormalRule(Long dpidLong) {
1364 String nodeName = "openflow:" + dpidLong;
1366 MatchBuilder matchBuilder = new MatchBuilder();
1367 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1368 FlowBuilder flowBuilder = new FlowBuilder();
1370 // Create the OF Actions and Instructions
1371 InstructionBuilder ib = new InstructionBuilder();
1372 InstructionsBuilder isb = new InstructionsBuilder();
1374 // Instructions List Stores Individual Instructions
1375 List<Instruction> instructions = Lists.newArrayList();
1377 // Call the InstructionBuilder Methods Containing Actions
1378 createNormalInstructions(ib);
1380 ib.setKey(new InstructionKey(0));
1381 instructions.add(ib.build());
1383 // Add InstructionBuilder to the Instruction(s)Builder List
1384 isb.setInstruction(instructions);
1386 // Add InstructionsBuilder to FlowBuilder
1387 flowBuilder.setInstructions(isb.build());
1389 String flowId = "NORMAL";
1390 flowBuilder.setId(new FlowId(flowId));
1391 FlowKey key = new FlowKey(new FlowId(flowId));
1392 flowBuilder.setMatch(matchBuilder.build());
1393 flowBuilder.setPriority(0);
1394 flowBuilder.setBarrier(true);
1395 flowBuilder.setTableId((short) 0);
1396 flowBuilder.setKey(key);
1397 flowBuilder.setFlowName(flowId);
1398 flowBuilder.setHardTimeout(0);
1399 flowBuilder.setIdleTimeout(0);
1400 writeFlow(flowBuilder, nodeBuilder);
1404 * (Table:0) Ingress Tunnel Traffic
1405 * Match: OpenFlow InPort and Tunnel ID
1406 * Action: GOTO Local Table (10)
1407 * table=0,tun_id=0x5,in_port=10, actions=goto_table:2
1410 private void handleTunnelIn(Long dpidLong, Short writeTable,
1411 Short goToTableId, String segmentationId,
1412 Long ofPort, boolean write) {
1414 String nodeName = "openflow:" + dpidLong;
1416 BigInteger tunnelId = new BigInteger(segmentationId);
1417 MatchBuilder matchBuilder = new MatchBuilder();
1418 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1419 FlowBuilder flowBuilder = new FlowBuilder();
1421 // Create Match(es) and Set them in the FlowBuilder Object
1422 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, tunnelId).build());
1423 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ofPort).build());
1426 // Create the OF Actions and Instructions
1427 InstructionBuilder ib = new InstructionBuilder();
1428 InstructionsBuilder isb = new InstructionsBuilder();
1430 // Instructions List Stores Individual Instructions
1431 List<Instruction> instructions = Lists.newArrayList();
1433 // Call the InstructionBuilder Methods Containing Actions
1434 createGotoTableInstructions(ib, goToTableId);
1436 ib.setKey(new InstructionKey(0));
1437 instructions.add(ib.build());
1439 // Add InstructionBuilder to the Instruction(s)Builder List
1440 isb.setInstruction(instructions);
1442 // Add InstructionsBuilder to FlowBuilder
1443 flowBuilder.setInstructions(isb.build());
1446 String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
1447 // Add Flow Attributes
1448 flowBuilder.setId(new FlowId(flowId));
1449 FlowKey key = new FlowKey(new FlowId(flowId));
1450 flowBuilder.setStrict(true);
1451 flowBuilder.setBarrier(false);
1452 flowBuilder.setTableId(writeTable);
1453 flowBuilder.setKey(key);
1454 flowBuilder.setFlowName(flowId);
1455 flowBuilder.setHardTimeout(0);
1456 flowBuilder.setIdleTimeout(0);
1459 writeFlow(flowBuilder, nodeBuilder);
1461 removeFlow(flowBuilder, nodeBuilder);
1466 * (Table:0) Ingress VLAN Traffic
1467 * Match: OpenFlow InPort and vlan ID
1468 * Action: GOTO Local Table (20)
1469 * table=0,vlan_id=0x5,in_port=10, actions=goto_table:2
1472 private void handleVlanIn(Long dpidLong, Short writeTable, Short goToTableId,
1473 String segmentationId, Long ethPort, boolean write) {
1475 String nodeName = "openflow:" + dpidLong;
1477 MatchBuilder matchBuilder = new MatchBuilder();
1478 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1479 FlowBuilder flowBuilder = new FlowBuilder();
1481 // Create Match(es) and Set them in the FlowBuilder Object
1482 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1483 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ethPort).build());
1486 // Create the OF Actions and Instructions
1487 InstructionBuilder ib = new InstructionBuilder();
1488 InstructionsBuilder isb = new InstructionsBuilder();
1490 // Instructions List Stores Individual Instructions
1491 List<Instruction> instructions = Lists.newArrayList();
1493 // Call the InstructionBuilder Methods Containing Actions
1494 createGotoTableInstructions(ib, goToTableId);
1496 ib.setKey(new InstructionKey(0));
1497 instructions.add(ib.build());
1499 // Add InstructionBuilder to the Instruction(s)Builder List
1500 isb.setInstruction(instructions);
1502 // Add InstructionsBuilder to FlowBuilder
1503 flowBuilder.setInstructions(isb.build());
1506 String flowId = "VlanIn_"+segmentationId+"_"+ethPort;
1507 // Add Flow Attributes
1508 flowBuilder.setId(new FlowId(flowId));
1509 FlowKey key = new FlowKey(new FlowId(flowId));
1510 flowBuilder.setStrict(true);
1511 flowBuilder.setBarrier(false);
1512 flowBuilder.setTableId(writeTable);
1513 flowBuilder.setKey(key);
1514 flowBuilder.setFlowName(flowId);
1515 flowBuilder.setHardTimeout(0);
1516 flowBuilder.setIdleTimeout(0);
1518 writeFlow(flowBuilder, nodeBuilder);
1520 removeFlow(flowBuilder, nodeBuilder);
1525 * (Table:0) Egress VM Traffic Towards TEP
1526 * Match: Destination Ethernet Addr and OpenFlow InPort
1527 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1528 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1529 * actions=set_field:5->tun_id,goto_table=1"
1532 private void handleLocalInPort(Long dpidLong, Short writeTable, Short goToTableId,
1533 String segmentationId, Long inPort, String attachedMac,
1536 String nodeName = "openflow:" + dpidLong;
1538 MatchBuilder matchBuilder = new MatchBuilder();
1539 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1540 FlowBuilder flowBuilder = new FlowBuilder();
1542 // Create the OF Match using MatchBuilder
1543 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1544 // TODO Broken In_Port Match
1545 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1547 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1548 // Add Flow Attributes
1549 flowBuilder.setId(new FlowId(flowId));
1550 FlowKey key = new FlowKey(new FlowId(flowId));
1551 flowBuilder.setStrict(true);
1552 flowBuilder.setBarrier(false);
1553 flowBuilder.setTableId(writeTable);
1554 flowBuilder.setKey(key);
1555 flowBuilder.setFlowName(flowId);
1556 flowBuilder.setHardTimeout(0);
1557 flowBuilder.setIdleTimeout(0);
1560 // Instantiate the Builders for the OF Actions and Instructions
1561 InstructionBuilder ib = new InstructionBuilder();
1562 InstructionsBuilder isb = new InstructionsBuilder();
1564 // Instructions List Stores Individual Instructions
1565 List<Instruction> instructions = Lists.newArrayList();
1567 // GOTO Instuctions Need to be added first to the List
1568 createGotoTableInstructions(ib, goToTableId);
1570 ib.setKey(new InstructionKey(0));
1571 instructions.add(ib.build());
1572 // TODO Broken SetTunID
1573 createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
1575 ib.setKey(new InstructionKey(1));
1576 instructions.add(ib.build());
1578 // Add InstructionBuilder to the Instruction(s)Builder List
1579 isb.setInstruction(instructions);
1581 // Add InstructionsBuilder to FlowBuilder
1582 flowBuilder.setInstructions(isb.build());
1584 writeFlow(flowBuilder, nodeBuilder);
1586 removeFlow(flowBuilder, nodeBuilder);
1591 * (Table:0) Egress VM Traffic Towards TEP
1592 * Match: Source Ethernet Addr and OpenFlow InPort
1593 * Instruction: Set VLANID and GOTO Table Egress (n)
1594 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1595 * actions=push_vlan, set_field:5->vlan_id,goto_table=1"
1598 private void handleLocalInPortSetVlan(Long dpidLong, Short writeTable,
1599 Short goToTableId, String segmentationId,
1600 Long inPort, String attachedMac,
1603 String nodeName = "openflow:" + dpidLong;
1605 MatchBuilder matchBuilder = new MatchBuilder();
1606 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1607 FlowBuilder flowBuilder = new FlowBuilder();
1609 // Create the OF Match using MatchBuilder
1610 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1611 // TODO Broken In_Port Match
1612 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1614 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1615 // Add Flow Attributes
1616 flowBuilder.setId(new FlowId(flowId));
1617 FlowKey key = new FlowKey(new FlowId(flowId));
1618 flowBuilder.setStrict(true);
1619 flowBuilder.setBarrier(false);
1620 flowBuilder.setTableId(writeTable);
1621 flowBuilder.setKey(key);
1622 flowBuilder.setFlowName(flowId);
1623 flowBuilder.setHardTimeout(0);
1624 flowBuilder.setIdleTimeout(0);
1627 // Instantiate the Builders for the OF Actions and Instructions
1628 InstructionBuilder ib = new InstructionBuilder();
1629 InstructionsBuilder isb = new InstructionsBuilder();
1631 // Instructions List Stores Individual Instructions
1632 List<Instruction> instructions = Lists.newArrayList();
1634 // GOTO Instructions Need to be added first to the List
1635 createGotoTableInstructions(ib, goToTableId);
1637 ib.setKey(new InstructionKey(0));
1638 instructions.add(ib.build());
1639 // Set VLAN ID Instruction
1640 createSetVlanInstructions(ib, new VlanId(Integer.valueOf(segmentationId)));
1642 ib.setKey(new InstructionKey(1));
1643 instructions.add(ib.build());
1645 // Add InstructionBuilder to the Instruction(s)Builder List
1646 isb.setInstruction(instructions);
1648 // Add InstructionsBuilder to FlowBuilder
1649 flowBuilder.setInstructions(isb.build());
1651 writeFlow(flowBuilder, nodeBuilder);
1653 removeFlow(flowBuilder, nodeBuilder);
1658 * (Table:0) Drop frames source from a VM that do not
1659 * match the associated MAC address of the local VM.
1660 * Match: Low priority anything not matching the VM SMAC
1662 * table=0,priority=16384,in_port=1 actions=drop"
1665 private void handleDropSrcIface(Long dpidLong, Long inPort, boolean write) {
1667 String nodeName = "openflow:" + dpidLong;
1669 MatchBuilder matchBuilder = new MatchBuilder();
1670 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1671 FlowBuilder flowBuilder = new FlowBuilder();
1673 // Create the OF Match using MatchBuilder
1674 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1677 // Instantiate the Builders for the OF Actions and Instructions
1678 InstructionBuilder ib = new InstructionBuilder();
1679 InstructionsBuilder isb = new InstructionsBuilder();
1681 // Instructions List Stores Individual Instructions
1682 List<Instruction> instructions = Lists.newArrayList();
1684 // Call the InstructionBuilder Methods Containing Actions
1685 createDropInstructions(ib);
1687 ib.setKey(new InstructionKey(0));
1688 instructions.add(ib.build());
1690 // Add InstructionBuilder to the Instruction(s)Builder List
1691 isb.setInstruction(instructions);
1693 // Add InstructionsBuilder to FlowBuilder
1694 flowBuilder.setInstructions(isb.build());
1697 String flowId = "DropFilter_"+inPort;
1698 // Add Flow Attributes
1699 flowBuilder.setId(new FlowId(flowId));
1700 FlowKey key = new FlowKey(new FlowId(flowId));
1701 flowBuilder.setStrict(true);
1702 flowBuilder.setBarrier(false);
1703 flowBuilder.setTableId((short) 0);
1704 flowBuilder.setKey(key);
1705 flowBuilder.setFlowName(flowId);
1706 flowBuilder.setPriority(8192);
1707 flowBuilder.setHardTimeout(0);
1708 flowBuilder.setIdleTimeout(0);
1710 writeFlow(flowBuilder, nodeBuilder);
1712 removeFlow(flowBuilder, nodeBuilder);
1717 * (Table:1) Egress Tunnel Traffic
1718 * Match: Destination Ethernet Addr and Local InPort
1719 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1720 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
1721 * actions=output:10,goto_table:2"
1723 private void handleTunnelOut(Long dpidLong, Short writeTable,
1724 Short goToTableId, String segmentationId,
1725 Long OFPortOut, String attachedMac,
1728 String nodeName = "openflow:" + dpidLong;
1730 MatchBuilder matchBuilder = new MatchBuilder();
1731 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1732 FlowBuilder flowBuilder = new FlowBuilder();
1734 // Create the OF Match using MatchBuilder
1735 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1736 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1738 String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
1739 // Add Flow Attributes
1740 flowBuilder.setId(new FlowId(flowId));
1741 FlowKey key = new FlowKey(new FlowId(flowId));
1742 flowBuilder.setStrict(true);
1743 flowBuilder.setBarrier(false);
1744 flowBuilder.setTableId(writeTable);
1745 flowBuilder.setKey(key);
1746 flowBuilder.setFlowName(flowId);
1747 flowBuilder.setHardTimeout(0);
1748 flowBuilder.setIdleTimeout(0);
1751 // Instantiate the Builders for the OF Actions and Instructions
1752 InstructionBuilder ib = new InstructionBuilder();
1753 InstructionsBuilder isb = new InstructionsBuilder();
1755 // Instructions List Stores Individual Instructions
1756 List<Instruction> instructions = Lists.newArrayList();
1759 createGotoTableInstructions(ib, goToTableId);
1761 ib.setKey(new InstructionKey(0));
1762 instructions.add(ib.build());
1763 // Set the Output Port/Iface
1764 createOutputPortInstructions(ib, dpidLong, OFPortOut);
1766 ib.setKey(new InstructionKey(1));
1767 instructions.add(ib.build());
1769 // Add InstructionBuilder to the Instruction(s)Builder List
1770 isb.setInstruction(instructions);
1772 // Add InstructionsBuilder to FlowBuilder
1773 flowBuilder.setInstructions(isb.build());
1775 writeFlow(flowBuilder, nodeBuilder);
1777 removeFlow(flowBuilder, nodeBuilder);
1782 * (Table:1) Egress VLAN Traffic
1783 * Match: Destination Ethernet Addr and VLAN id
1784 * Instruction: GOTO Table Table 2
1785 * table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
1786 * actions= goto_table:2"
1789 private void handleVlanOut(Long dpidLong, Short writeTable,
1790 Short goToTableId, String segmentationId,
1791 Long ethPort, String attachedMac, boolean write) {
1793 String nodeName = "openflow:" + dpidLong;
1795 MatchBuilder matchBuilder = new MatchBuilder();
1796 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1797 FlowBuilder flowBuilder = new FlowBuilder();
1799 // Create the OF Match using MatchBuilder
1800 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1801 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1803 String flowId = "VlanOut_"+segmentationId+"_"+ethPort+"_"+attachedMac;
1804 // Add Flow Attributes
1805 flowBuilder.setId(new FlowId(flowId));
1806 FlowKey key = new FlowKey(new FlowId(flowId));
1807 flowBuilder.setStrict(true);
1808 flowBuilder.setBarrier(false);
1809 flowBuilder.setTableId(writeTable);
1810 flowBuilder.setKey(key);
1811 flowBuilder.setFlowName(flowId);
1812 flowBuilder.setHardTimeout(0);
1813 flowBuilder.setIdleTimeout(0);
1816 // Instantiate the Builders for the OF Actions and Instructions
1817 InstructionBuilder ib = new InstructionBuilder();
1818 InstructionsBuilder isb = new InstructionsBuilder();
1820 // Instructions List Stores Individual Instructions
1821 List<Instruction> instructions = Lists.newArrayList();
1824 createGotoTableInstructions(ib, goToTableId);
1826 ib.setKey(new InstructionKey(0));
1827 instructions.add(ib.build());
1829 // Add InstructionBuilder to the Instruction(s)Builder List
1830 isb.setInstruction(instructions);
1832 // Add InstructionsBuilder to FlowBuilder
1833 flowBuilder.setInstructions(isb.build());
1835 writeFlow(flowBuilder, nodeBuilder);
1837 removeFlow(flowBuilder, nodeBuilder);
1842 * (Table:1) Egress Tunnel Traffic
1843 * Match: Destination Ethernet Addr and Local InPort
1844 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1845 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1846 * actions=output:10,output:11,goto_table:2
1849 private void handleTunnelFloodOut(Long dpidLong, Short writeTable,
1850 Short localTable, String segmentationId,
1851 Long OFPortOut, boolean write) {
1853 String nodeName = "openflow:" + dpidLong;
1855 MatchBuilder matchBuilder = new MatchBuilder();
1856 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1857 FlowBuilder flowBuilder = new FlowBuilder();
1859 // Create the OF Match using MatchBuilder
1861 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1864 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1866 String flowId = "TunnelFloodOut_"+segmentationId;
1867 // Add Flow Attributes
1868 flowBuilder.setId(new FlowId(flowId));
1869 FlowKey key = new FlowKey(new FlowId(flowId));
1870 flowBuilder.setBarrier(true);
1871 flowBuilder.setTableId(writeTable);
1872 flowBuilder.setKey(key);
1873 flowBuilder.setPriority(16384);
1874 flowBuilder.setFlowName(flowId);
1875 flowBuilder.setHardTimeout(0);
1876 flowBuilder.setIdleTimeout(0);
1878 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1879 // Instantiate the Builders for the OF Actions and Instructions
1880 InstructionBuilder ib = new InstructionBuilder();
1881 InstructionsBuilder isb = new InstructionsBuilder();
1882 List<Instruction> instructions = Lists.newArrayList();
1883 List<Instruction> existingInstructions = null;
1885 Instructions ins = flow.getInstructions();
1887 existingInstructions = ins.getInstruction();
1893 createGotoTableInstructions(ib, localTable);
1895 ib.setKey(new InstructionKey(0));
1896 instructions.add(ib.build());
1897 // Set the Output Port/Iface
1898 //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, OFPortOut, existingInstructions);
1899 createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
1901 ib.setKey(new InstructionKey(1));
1902 instructions.add(ib.build());
1904 // Add InstructionBuilder to the Instruction(s)Builder List
1905 isb.setInstruction(instructions);
1907 // Add InstructionsBuilder to FlowBuilder
1908 flowBuilder.setInstructions(isb.build());
1910 writeFlow(flowBuilder, nodeBuilder);
1912 /* remove port from action list */
1913 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
1914 OFPortOut, existingInstructions);
1916 /* if all port are removed, remove the flow too. */
1917 removeFlow(flowBuilder, nodeBuilder);
1919 /* Install instruction with new output port list*/
1921 ib.setKey(new InstructionKey(0));
1922 instructions.add(ib.build());
1924 // Add InstructionBuilder to the Instruction(s)Builder List
1925 isb.setInstruction(instructions);
1927 // Add InstructionsBuilder to FlowBuilder
1928 flowBuilder.setInstructions(isb.build());
1934 * (Table:1) Egress VLAN Traffic
1935 * Match: Destination Ethernet Addr and VLAN id
1936 * Instruction: GOTO table 2 and Output port eth interface
1937 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1938 * actions=output:eth1,goto_table:2
1941 private void handleVlanFloodOut(Long dpidLong, Short writeTable,
1942 Short localTable, String segmentationId,
1943 Long ethPort, boolean write) {
1945 String nodeName = "openflow:" + dpidLong;
1947 MatchBuilder matchBuilder = new MatchBuilder();
1948 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1949 FlowBuilder flowBuilder = new FlowBuilder();
1951 // Create the OF Match using MatchBuilder
1953 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1955 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1957 String flowId = "VlanFloodOut_"+segmentationId;
1958 // Add Flow Attributes
1959 flowBuilder.setId(new FlowId(flowId));
1960 FlowKey key = new FlowKey(new FlowId(flowId));
1961 flowBuilder.setBarrier(true);
1962 flowBuilder.setTableId(writeTable);
1963 flowBuilder.setKey(key);
1964 flowBuilder.setPriority(16384);
1965 flowBuilder.setFlowName(flowId);
1966 flowBuilder.setHardTimeout(0);
1967 flowBuilder.setIdleTimeout(0);
1969 //ToDo: Is there something to be done with result of the call to getFlow?
1971 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1972 // Instantiate the Builders for the OF Actions and Instructions
1973 InstructionBuilder ib = new InstructionBuilder();
1974 InstructionsBuilder isb = new InstructionsBuilder();
1975 List<Instruction> instructions = Lists.newArrayList();
1979 createGotoTableInstructions(ib, localTable);
1981 ib.setKey(new InstructionKey(0));
1982 instructions.add(ib.build());
1983 // Set the Output Port/Iface
1984 createOutputPortInstructions(ib, dpidLong, ethPort);
1986 ib.setKey(new InstructionKey(1));
1987 instructions.add(ib.build());
1989 // Add InstructionBuilder to the Instruction(s)Builder List
1990 isb.setInstruction(instructions);
1992 // Add InstructionsBuilder to FlowBuilder
1993 flowBuilder.setInstructions(isb.build());
1995 writeFlow(flowBuilder, nodeBuilder);
1997 removeFlow(flowBuilder, nodeBuilder);
2002 * (Table:1) Table Drain w/ Catch All
2004 * Action: GOTO Local Table (10)
2005 * table=2,priority=8192,tun_id=0x5 actions=drop
2008 private void handleTunnelMiss(Long dpidLong, Short writeTable,
2009 Short goToTableId, String segmentationId,
2012 String nodeName = "openflow:" + dpidLong;
2014 MatchBuilder matchBuilder = new MatchBuilder();
2015 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2016 FlowBuilder flowBuilder = new FlowBuilder();
2018 // Create Match(es) and Set them in the FlowBuilder Object
2019 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2022 // Create the OF Actions and Instructions
2023 InstructionBuilder ib = new InstructionBuilder();
2024 InstructionsBuilder isb = new InstructionsBuilder();
2026 // Instructions List Stores Individual Instructions
2027 List<Instruction> instructions = Lists.newArrayList();
2029 // Call the InstructionBuilder Methods Containing Actions
2030 createGotoTableInstructions(ib, goToTableId);
2032 ib.setKey(new InstructionKey(0));
2033 instructions.add(ib.build());
2035 // Add InstructionBuilder to the Instruction(s)Builder List
2036 isb.setInstruction(instructions);
2038 // Add InstructionsBuilder to FlowBuilder
2039 flowBuilder.setInstructions(isb.build());
2042 String flowId = "TunnelMiss_"+segmentationId;
2043 // Add Flow Attributes
2044 flowBuilder.setId(new FlowId(flowId));
2045 FlowKey key = new FlowKey(new FlowId(flowId));
2046 flowBuilder.setStrict(true);
2047 flowBuilder.setBarrier(false);
2048 flowBuilder.setTableId(writeTable);
2049 flowBuilder.setKey(key);
2050 flowBuilder.setPriority(8192);
2051 flowBuilder.setFlowName(flowId);
2052 flowBuilder.setHardTimeout(0);
2053 flowBuilder.setIdleTimeout(0);
2055 writeFlow(flowBuilder, nodeBuilder);
2057 removeFlow(flowBuilder, nodeBuilder);
2063 * (Table:1) Table Drain w/ Catch All
2065 * Action: Output port eth interface
2066 * table=1,priority=8192,vlan_id=0x5 actions= output port:eth1
2069 private void handleVlanMiss(Long dpidLong, Short writeTable,
2070 Short goToTableId, String segmentationId,
2071 Long ethPort, boolean write) {
2073 String nodeName = "openflow:" + dpidLong;
2075 MatchBuilder matchBuilder = new MatchBuilder();
2076 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2077 FlowBuilder flowBuilder = new FlowBuilder();
2079 // Create Match(es) and Set them in the FlowBuilder Object
2080 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2083 // Create the OF Actions and Instructions
2084 InstructionBuilder ib = new InstructionBuilder();
2085 InstructionsBuilder isb = new InstructionsBuilder();
2087 // Instructions List Stores Individual Instructions
2088 List<Instruction> instructions = Lists.newArrayList();
2090 // Call the InstructionBuilder Methods Containing Actions
2091 //createGotoTableInstructions(ib, goToTableId);
2093 //ib.setKey(new InstructionKey(0));
2094 //instructions.add(ib.build());
2095 // Set the Output Port/Iface
2096 createOutputPortInstructions(ib, dpidLong, ethPort);
2098 ib.setKey(new InstructionKey(1));
2099 instructions.add(ib.build());
2101 // Add InstructionBuilder to the Instruction(s)Builder List
2102 isb.setInstruction(instructions);
2104 // Add InstructionsBuilder to FlowBuilder
2105 flowBuilder.setInstructions(isb.build());
2108 String flowId = "VlanMiss_"+segmentationId;
2109 // Add Flow Attributes
2110 flowBuilder.setId(new FlowId(flowId));
2111 FlowKey key = new FlowKey(new FlowId(flowId));
2112 flowBuilder.setStrict(true);
2113 flowBuilder.setBarrier(false);
2114 flowBuilder.setTableId(writeTable);
2115 flowBuilder.setKey(key);
2116 flowBuilder.setPriority(8192);
2117 flowBuilder.setFlowName(flowId);
2118 flowBuilder.setHardTimeout(0);
2119 flowBuilder.setIdleTimeout(0);
2121 writeFlow(flowBuilder, nodeBuilder);
2123 removeFlow(flowBuilder, nodeBuilder);
2128 * (Table:1) Local Broadcast Flood
2129 * Match: Tunnel ID and dMAC
2130 * Action: Output Port
2131 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2134 private void handleLocalUcastOut(Long dpidLong, Short writeTable,
2135 String segmentationId, Long localPort,
2136 String attachedMac, boolean write) {
2138 String nodeName = "openflow:" + dpidLong;
2140 MatchBuilder matchBuilder = new MatchBuilder();
2141 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2142 FlowBuilder flowBuilder = new FlowBuilder();
2144 // Create the OF Match using MatchBuilder
2145 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2146 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2148 String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2149 // Add Flow Attributes
2150 flowBuilder.setId(new FlowId(flowId));
2151 FlowKey key = new FlowKey(new FlowId(flowId));
2152 flowBuilder.setStrict(true);
2153 flowBuilder.setBarrier(false);
2154 flowBuilder.setTableId(writeTable);
2155 flowBuilder.setKey(key);
2156 flowBuilder.setFlowName(flowId);
2157 flowBuilder.setHardTimeout(0);
2158 flowBuilder.setIdleTimeout(0);
2161 // Instantiate the Builders for the OF Actions and Instructions
2162 InstructionBuilder ib = new InstructionBuilder();
2163 InstructionsBuilder isb = new InstructionsBuilder();
2165 // Instructions List Stores Individual Instructions
2166 List<Instruction> instructions = Lists.newArrayList();
2168 // Set the Output Port/Iface
2169 createOutputPortInstructions(ib, dpidLong, localPort);
2171 ib.setKey(new InstructionKey(0));
2172 instructions.add(ib.build());
2174 // Add InstructionBuilder to the Instruction(s)Builder List
2175 isb.setInstruction(instructions);
2177 // Add InstructionsBuilder to FlowBuilder
2178 flowBuilder.setInstructions(isb.build());
2179 writeFlow(flowBuilder, nodeBuilder);
2181 removeFlow(flowBuilder, nodeBuilder);
2186 * (Table:2) Local VLAN unicast
2187 * Match: VLAN ID and dMAC
2188 * Action: Output Port
2189 * table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2192 private void handleLocalVlanUcastOut(Long dpidLong, Short writeTable,
2193 String segmentationId, Long localPort,
2194 String attachedMac, boolean write) {
2196 String nodeName = "openflow:" + dpidLong;
2198 MatchBuilder matchBuilder = new MatchBuilder();
2199 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2200 FlowBuilder flowBuilder = new FlowBuilder();
2202 // Create the OF Match using MatchBuilder
2203 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2204 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2206 String flowId = "VlanUcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2207 // Add Flow Attributes
2208 flowBuilder.setId(new FlowId(flowId));
2209 FlowKey key = new FlowKey(new FlowId(flowId));
2210 flowBuilder.setStrict(true);
2211 flowBuilder.setBarrier(false);
2212 flowBuilder.setTableId(writeTable);
2213 flowBuilder.setKey(key);
2214 flowBuilder.setFlowName(flowId);
2215 flowBuilder.setHardTimeout(0);
2216 flowBuilder.setIdleTimeout(0);
2219 // Instantiate the Builders for the OF Actions and Instructions
2220 InstructionBuilder ib = new InstructionBuilder();
2221 InstructionsBuilder isb = new InstructionsBuilder();
2223 // Instructions List Stores Individual Instructions
2224 List<Instruction> instructions = Lists.newArrayList();
2225 List<Instruction> instructions_tmp = Lists.newArrayList();
2227 /* Strip vlan and store to tmp instruction space*/
2228 createPopVlanInstructions(ib);
2230 ib.setKey(new InstructionKey(0));
2231 instructions_tmp.add(ib.build());
2233 // Set the Output Port/Iface
2234 ib = new InstructionBuilder();
2235 addOutputPortInstructions(ib, dpidLong, localPort, instructions_tmp);
2237 ib.setKey(new InstructionKey(0));
2238 instructions.add(ib.build());
2240 // Add InstructionBuilder to the Instruction(s)Builder List
2241 isb.setInstruction(instructions);
2243 // Add InstructionsBuilder to FlowBuilder
2244 flowBuilder.setInstructions(isb.build());
2245 writeFlow(flowBuilder, nodeBuilder);
2247 removeFlow(flowBuilder, nodeBuilder);
2252 * (Table:2) Local Broadcast Flood
2253 * Match: Tunnel ID and dMAC (::::FF:FF)
2254 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2255 * actions=output:2,3,4,5
2258 private void handleLocalBcastOut(Long dpidLong, Short writeTable,
2259 String segmentationId, Long localPort,
2262 String nodeName = "openflow:" + dpidLong;
2264 MatchBuilder matchBuilder = new MatchBuilder();
2265 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2266 FlowBuilder flowBuilder = new FlowBuilder();
2268 // Create the OF Match using MatchBuilder
2269 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2270 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
2272 String flowId = "BcastOut_"+segmentationId;
2273 // Add Flow Attributes
2274 flowBuilder.setId(new FlowId(flowId));
2275 FlowKey key = new FlowKey(new FlowId(flowId));
2276 flowBuilder.setStrict(true);
2277 flowBuilder.setBarrier(false);
2278 flowBuilder.setTableId(writeTable);
2279 flowBuilder.setKey(key);
2280 flowBuilder.setPriority(16384);
2281 flowBuilder.setFlowName(flowId);
2282 flowBuilder.setHardTimeout(0);
2283 flowBuilder.setIdleTimeout(0);
2284 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2285 // Instantiate the Builders for the OF Actions and Instructions
2286 InstructionBuilder ib = new InstructionBuilder();
2287 InstructionsBuilder isb = new InstructionsBuilder();
2288 List<Instruction> instructions = Lists.newArrayList();
2289 List<Instruction> existingInstructions = null;
2291 Instructions ins = flow.getInstructions();
2293 existingInstructions = ins.getInstruction();
2298 // Create output port list
2299 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
2301 ib.setKey(new InstructionKey(0));
2302 instructions.add(ib.build());
2304 // Add InstructionBuilder to the Instruction(s)Builder List
2305 isb.setInstruction(instructions);
2307 // Add InstructionsBuilder to FlowBuilder
2308 flowBuilder.setInstructions(isb.build());
2310 writeFlow(flowBuilder, nodeBuilder);
2312 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong, localPort,
2313 existingInstructions);
2315 /* if all ports are removed, remove flow */
2316 removeFlow(flowBuilder, nodeBuilder);
2318 /* Install instruction with new output port list*/
2320 ib.setKey(new InstructionKey(0));
2321 instructions.add(ib.build());
2323 // Add InstructionBuilder to the Instruction(s)Builder List
2324 isb.setInstruction(instructions);
2326 // Add InstructionsBuilder to FlowBuilder
2327 flowBuilder.setInstructions(isb.build());
2329 writeFlow(flowBuilder, nodeBuilder);
2335 * (Table:2) Local VLAN Broadcast Flood
2336 * Match: vlan ID and dMAC (::::FF:FF)
2337 * table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2338 * actions=strip_vlan, output:2,3,4,5
2341 private void handleLocalVlanBcastOut(Long dpidLong, Short writeTable,
2342 String segmentationId, Long localPort,
2345 String nodeName = "openflow:" + dpidLong;
2347 MatchBuilder matchBuilder = new MatchBuilder();
2348 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2349 FlowBuilder flowBuilder = new FlowBuilder();
2351 // Create the OF Match using MatchBuilder
2352 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2353 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
2355 String flowId = "VlanBcastOut_"+segmentationId;
2356 // Add Flow Attributes
2357 flowBuilder.setId(new FlowId(flowId));
2358 FlowKey key = new FlowKey(new FlowId(flowId));
2359 flowBuilder.setStrict(true);
2360 flowBuilder.setBarrier(false);
2361 flowBuilder.setTableId(writeTable);
2362 flowBuilder.setKey(key);
2363 flowBuilder.setPriority(16384);
2364 flowBuilder.setFlowName(flowId);
2365 flowBuilder.setHardTimeout(0);
2366 flowBuilder.setIdleTimeout(0);
2367 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2368 // Instantiate the Builders for the OF Actions and Instructions
2369 InstructionBuilder ib = new InstructionBuilder();
2370 InstructionsBuilder isb = new InstructionsBuilder();
2371 List<Instruction> instructions = Lists.newArrayList();
2372 List<Instruction> existingInstructions = null;
2373 boolean add_pop_vlan = true;
2375 Instructions ins = flow.getInstructions();
2377 existingInstructions = ins.getInstruction();
2382 if (existingInstructions != null) {
2383 /* Check if pop vlan is already the first action in action list */
2384 List<Action> existingActions;
2385 for (Instruction in : existingInstructions) {
2386 if (in.getInstruction() instanceof ApplyActionsCase) {
2387 existingActions = (((ApplyActionsCase)
2388 in.getInstruction()).getApplyActions().getAction());
2389 if (existingActions.get(0).getAction() instanceof PopVlanActionCase) {
2390 add_pop_vlan = false;
2396 existingInstructions = Lists.newArrayList();
2401 createPopVlanInstructions(ib);
2403 ib.setKey(new InstructionKey(0));
2404 existingInstructions.add(ib.build());
2405 ib = new InstructionBuilder();
2409 //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, localPort, existingInstructions);
2410 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
2412 ib.setKey(new InstructionKey(0));
2413 instructions.add(ib.build());
2415 // Add InstructionBuilder to the Instruction(s)Builder List
2416 isb.setInstruction(instructions);
2418 // Add InstructionsBuilder to FlowBuilder
2419 flowBuilder.setInstructions(isb.build());
2421 writeFlow(flowBuilder, nodeBuilder);
2423 //boolean flowRemove = removeOutputPortFromGroup(nodeBuilder, ib, dpidLong,
2424 // localPort, existingInstructions);
2425 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
2426 localPort, existingInstructions);
2428 /* if all ports are removed, remove flow */
2429 removeFlow(flowBuilder, nodeBuilder);
2431 /* Install instruction with new output port list*/
2433 ib.setKey(new InstructionKey(0));
2434 instructions.add(ib.build());
2436 // Add InstructionBuilder to the Instruction(s)Builder List
2437 isb.setInstruction(instructions);
2439 // Add InstructionsBuilder to FlowBuilder
2440 flowBuilder.setInstructions(isb.build());
2441 writeFlow(flowBuilder, nodeBuilder);
2447 * (Table:1) Local Table Miss
2448 * Match: Any Remaining Flows w/a TunID
2449 * Action: Drop w/ a low priority
2450 * table=2,priority=8192,tun_id=0x5 actions=drop
2453 private void handleLocalTableMiss(Long dpidLong, Short writeTable,
2454 String segmentationId, boolean write) {
2456 String nodeName = "openflow:" + dpidLong;
2458 MatchBuilder matchBuilder = new MatchBuilder();
2459 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2460 FlowBuilder flowBuilder = new FlowBuilder();
2462 // Create Match(es) and Set them in the FlowBuilder Object
2463 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2466 // Create the OF Actions and Instructions
2467 InstructionBuilder ib = new InstructionBuilder();
2468 InstructionsBuilder isb = new InstructionsBuilder();
2470 // Instructions List Stores Individual Instructions
2471 List<Instruction> instructions = Lists.newArrayList();
2473 // Call the InstructionBuilder Methods Containing Actions
2474 createDropInstructions(ib);
2476 ib.setKey(new InstructionKey(0));
2477 instructions.add(ib.build());
2479 // Add InstructionBuilder to the Instruction(s)Builder List
2480 isb.setInstruction(instructions);
2482 // Add InstructionsBuilder to FlowBuilder
2483 flowBuilder.setInstructions(isb.build());
2486 String flowId = "LocalTableMiss_"+segmentationId;
2487 // Add Flow Attributes
2488 flowBuilder.setId(new FlowId(flowId));
2489 FlowKey key = new FlowKey(new FlowId(flowId));
2490 flowBuilder.setStrict(true);
2491 flowBuilder.setBarrier(false);
2492 flowBuilder.setTableId(writeTable);
2493 flowBuilder.setKey(key);
2494 flowBuilder.setPriority(8192);
2495 flowBuilder.setFlowName(flowId);
2496 flowBuilder.setHardTimeout(0);
2497 flowBuilder.setIdleTimeout(0);
2499 writeFlow(flowBuilder, nodeBuilder);
2501 removeFlow(flowBuilder, nodeBuilder);
2506 * (Table:1) Local Table Miss
2507 * Match: Any Remaining Flows w/a VLAN ID
2508 * Action: Drop w/ a low priority
2509 * table=2,priority=8192,vlan_id=0x5 actions=drop
2512 private void handleLocalVlanTableMiss(Long dpidLong, Short writeTable,
2513 String segmentationId, boolean write) {
2515 String nodeName = "openflow:" + dpidLong;
2517 MatchBuilder matchBuilder = new MatchBuilder();
2518 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2519 FlowBuilder flowBuilder = new FlowBuilder();
2521 // Create Match(es) and Set them in the FlowBuilder Object
2522 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2525 // Create the OF Actions and Instructions
2526 InstructionBuilder ib = new InstructionBuilder();
2527 InstructionsBuilder isb = new InstructionsBuilder();
2529 // Instructions List Stores Individual Instructions
2530 List<Instruction> instructions = Lists.newArrayList();
2532 // Call the InstructionBuilder Methods Containing Actions
2533 createDropInstructions(ib);
2535 ib.setKey(new InstructionKey(0));
2536 instructions.add(ib.build());
2538 // Add InstructionBuilder to the Instruction(s)Builder List
2539 isb.setInstruction(instructions);
2541 // Add InstructionsBuilder to FlowBuilder
2542 flowBuilder.setInstructions(isb.build());
2545 String flowId = "LocalTableMiss_"+segmentationId;
2546 // Add Flow Attributes
2547 flowBuilder.setId(new FlowId(flowId));
2548 FlowKey key = new FlowKey(new FlowId(flowId));
2549 flowBuilder.setStrict(true);
2550 flowBuilder.setBarrier(false);
2551 flowBuilder.setTableId(writeTable);
2552 flowBuilder.setKey(key);
2553 flowBuilder.setPriority(8192);
2554 flowBuilder.setFlowName(flowId);
2555 flowBuilder.setHardTimeout(0);
2556 flowBuilder.setIdleTimeout(0);
2558 writeFlow(flowBuilder, nodeBuilder);
2560 removeFlow(flowBuilder, nodeBuilder);
2564 private Group getGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2565 Preconditions.checkNotNull(mdsalConsumer);
2566 if (mdsalConsumer == null) {
2567 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2571 dataBroker = mdsalConsumer.getDataBroker();
2572 if (dataBroker == null) {
2573 logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
2577 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2578 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2579 new GroupKey(groupBuilder.getGroupId())).build();
2580 ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction();
2582 Optional<Group> data = readTx.read(LogicalDatastoreType.CONFIGURATION, path1).get();
2583 if (data.isPresent()) {
2586 } catch (InterruptedException|ExecutionException e) {
2587 logger.error(e.getMessage(), e);
2590 logger.debug("Cannot find data for Group " + groupBuilder.getGroupName());
2594 private void writeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2595 Preconditions.checkNotNull(mdsalConsumer);
2596 if (mdsalConsumer == null) {
2597 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2601 dataBroker = mdsalConsumer.getDataBroker();
2602 if (dataBroker == null) {
2603 logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
2607 ReadWriteTransaction modification = dataBroker.newReadWriteTransaction();
2609 // Sanity check: do not create parent's tree deeper than we should
2610 InstanceIdentifier<?> requiredPath = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2611 .rev130819.nodes.Node.class, nodeBuilder.getKey()).build();
2613 if (!modification.read(LogicalDatastoreType.CONFIGURATION, requiredPath).get().isPresent()) {
2614 logger.error("Unable to get configuration resource to store group "+groupBuilder.getGroupName()
2615 +" ("+requiredPath.toString()+")");
2618 } catch (InterruptedException|ExecutionException e) {
2619 logger.error(e.getMessage(), e);
2623 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2624 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2625 new GroupKey(groupBuilder.getGroupId())).build();
2626 modification.put(LogicalDatastoreType.CONFIGURATION, path1, groupBuilder.build(), true /*createMissingParents*/);
2628 CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
2630 commitFuture.get(); // TODO: Make it async (See bug 1362)
2631 logger.debug("Transaction success for write of Group "+groupBuilder.getGroupName());
2632 } catch (InterruptedException|ExecutionException e) {
2633 logger.error(e.getMessage(), e);
2637 private void removeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2638 Preconditions.checkNotNull(mdsalConsumer);
2639 if (mdsalConsumer == null) {
2640 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2644 dataBroker = mdsalConsumer.getDataBroker();
2645 if (dataBroker == null) {
2646 logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
2650 WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
2651 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2652 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2653 new GroupKey(groupBuilder.getGroupId())).build();
2654 modification.delete(LogicalDatastoreType.CONFIGURATION, path1);
2655 CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
2658 commitFuture.get(); // TODO: Make it async (See bug 1362)
2659 logger.debug("Transaction success for deletion of Group "+groupBuilder.getGroupName());
2660 } catch (InterruptedException|ExecutionException e) {
2661 logger.error(e.getMessage(), e);
2664 private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2665 Preconditions.checkNotNull(mdsalConsumer);
2666 if (mdsalConsumer == null) {
2667 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2671 dataBroker = mdsalConsumer.getDataBroker();
2672 if (dataBroker == null) {
2673 logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
2677 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2678 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2679 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2681 ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction();
2683 Optional<Flow> data = readTx.read(LogicalDatastoreType.CONFIGURATION, path1).get();
2684 if (data.isPresent()) {
2687 } catch (InterruptedException|ExecutionException e) {
2688 logger.error(e.getMessage(), e);
2691 logger.debug("Cannot find data for Flow " + flowBuilder.getFlowName());
2695 private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2696 Preconditions.checkNotNull(mdsalConsumer);
2697 if (mdsalConsumer == null) {
2698 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2702 dataBroker = mdsalConsumer.getDataBroker();
2703 if (dataBroker == null) {
2704 logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
2708 ReadWriteTransaction modification = dataBroker.newReadWriteTransaction();
2710 // Sanity check: do not create parent's tree deeper than we should
2711 InstanceIdentifier<?> requiredPath = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2712 .rev130819.nodes.Node.class, nodeBuilder.getKey()).build();
2714 if (!modification.read(LogicalDatastoreType.CONFIGURATION, requiredPath).get().isPresent()) {
2715 logger.error("Unable to get configuration resource to store flow "+flowBuilder.getFlowName()
2716 +" ("+requiredPath.toString()+")");
2719 } catch (InterruptedException|ExecutionException e) {
2720 logger.error(e.getMessage(), e);
2724 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2725 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2726 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2728 //modification.put(LogicalDatastoreType.OPERATIONAL, path1, flowBuilder.build());
2729 modification.put(LogicalDatastoreType.CONFIGURATION, path1, flowBuilder.build(), true /*createMissingParents*/);
2732 CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
2734 commitFuture.get(); // TODO: Make it async (See bug 1362)
2735 logger.debug("Transaction success for write of Flow "+flowBuilder.getFlowName());
2736 } catch (InterruptedException|ExecutionException e) {
2737 logger.error(e.getMessage(), e);
2741 private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2742 Preconditions.checkNotNull(mdsalConsumer);
2743 if (mdsalConsumer == null) {
2744 logger.error("ERROR finding MDSAL Service.");
2748 dataBroker = mdsalConsumer.getDataBroker();
2749 if (dataBroker == null) {
2750 logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
2754 WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
2755 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class)
2756 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2757 .rev130819.nodes.Node.class, nodeBuilder.getKey())
2758 .augmentation(FlowCapableNode.class).child(Table.class,
2759 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2760 //modification.delete(LogicalDatastoreType.OPERATIONAL, nodeBuilderToInstanceId(nodeBuilder));
2761 //modification.delete(LogicalDatastoreType.OPERATIONAL, path1);
2762 //modification.delete(LogicalDatastoreType.CONFIGURATION, nodeBuilderToInstanceId(nodeBuilder));
2763 modification.delete(LogicalDatastoreType.CONFIGURATION, path1);
2765 CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
2767 commitFuture.get(); // TODO: Make it async (See bug 1362)
2768 logger.debug("Transaction success for deletion of Flow "+flowBuilder.getFlowName());
2769 } catch (InterruptedException|ExecutionException e) {
2770 logger.error(e.getMessage(), e);
2775 * Create Ingress Port Match dpidLong, inPort
2777 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
2778 * @param dpidLong Long the datapath ID of a switch/node
2779 * @param inPort Long ingress port on a switch
2780 * @return matchBuilder Map MatchBuilder Object with a match
2782 protected static MatchBuilder createInPortMatch(MatchBuilder matchBuilder, Long dpidLong, Long inPort) {
2784 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
2785 logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, inPort);
2786 matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
2787 matchBuilder.setInPort(ncid);
2789 return matchBuilder;
2793 * Create EtherType Match
2795 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
2796 * @param etherType Long EtherType
2797 * @return matchBuilder Map MatchBuilder Object with a match
2799 protected static MatchBuilder createEtherTypeMatch(MatchBuilder matchBuilder, EtherType etherType) {
2801 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2802 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2803 ethTypeBuilder.setType(new EtherType(etherType));
2804 ethernetMatch.setEthernetType(ethTypeBuilder.build());
2805 matchBuilder.setEthernetMatch(ethernetMatch.build());
2807 return matchBuilder;
2811 * Create Ethernet Source Match
2813 * @param matchBuilder MatchBuilder Object without a match yet
2814 * @param sMacAddr String representing a source MAC
2815 * @return matchBuilder Map MatchBuilder Object with a match
2817 protected static MatchBuilder createEthSrcMatch(MatchBuilder matchBuilder, MacAddress sMacAddr) {
2819 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2820 EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
2821 ethSourceBuilder.setAddress(new MacAddress(sMacAddr));
2822 ethernetMatch.setEthernetSource(ethSourceBuilder.build());
2823 matchBuilder.setEthernetMatch(ethernetMatch.build());
2825 return matchBuilder;
2829 * Create Ethernet Destination Match
2831 * @param matchBuilder MatchBuilder Object without a match yet
2832 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
2833 * @return matchBuilder Map MatchBuilder Object with a match
2836 protected static MatchBuilder createVlanIdMatch(MatchBuilder matchBuilder, VlanId vlanId) {
2837 VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
2838 VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
2839 vlanIdBuilder.setVlanId(new VlanId(vlanId));
2840 vlanIdBuilder.setVlanIdPresent(true);
2841 vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
2842 matchBuilder.setVlanMatch(vlanMatchBuilder.build());
2844 return matchBuilder;
2848 * Create Ethernet Destination Match
2850 * @param matchBuilder MatchBuilder Object without a match yet
2851 * @param dMacAddr String representing a destination MAC
2852 * @return matchBuilder Map MatchBuilder Object with a match
2855 protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
2857 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2858 EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
2859 ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
2861 ethDestinationBuilder.setMask(mask);
2863 ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
2864 matchBuilder.setEthernetMatch(ethernetMatch.build());
2866 return matchBuilder;
2870 * Tunnel ID Match Builder
2872 * @param matchBuilder MatchBuilder Object without a match yet
2873 * @param tunnelId BigInteger representing a tunnel ID
2874 * @return matchBuilder Map MatchBuilder Object with a match
2876 protected static MatchBuilder createTunnelIDMatch(MatchBuilder matchBuilder, BigInteger tunnelId) {
2878 TunnelBuilder tunnelBuilder = new TunnelBuilder();
2879 tunnelBuilder.setTunnelId(tunnelId);
2880 matchBuilder.setTunnel(tunnelBuilder.build());
2882 return matchBuilder;
2886 * Match ICMP code and type
2888 * @param matchBuilder MatchBuilder Object without a match yet
2889 * @param type short representing an ICMP type
2890 * @param code short representing an ICMP code
2891 * @return matchBuilder Map MatchBuilder Object with a match
2893 protected static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
2895 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2896 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2897 ethTypeBuilder.setType(new EtherType(0x0800L));
2898 eth.setEthernetType(ethTypeBuilder.build());
2899 matchBuilder.setEthernetMatch(eth.build());
2901 // Build the IPv4 Match requied per OVS Syntax
2902 IpMatchBuilder ipmatch = new IpMatchBuilder();
2903 ipmatch.setIpProtocol((short) 1);
2904 matchBuilder.setIpMatch(ipmatch.build());
2906 // Build the ICMPv4 Match
2907 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
2908 icmpv4match.setIcmpv4Type(type);
2909 icmpv4match.setIcmpv4Code(code);
2910 matchBuilder.setIcmpv4Match(icmpv4match.build());
2912 return matchBuilder;
2916 * @param matchBuilder MatchBuilder Object without a match yet
2917 * @param dstip String containing an IPv4 prefix
2918 * @return matchBuilder Map Object with a match
2920 private static MatchBuilder createDstL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
2922 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2923 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2924 ethTypeBuilder.setType(new EtherType(0x0800L));
2925 eth.setEthernetType(ethTypeBuilder.build());
2926 matchBuilder.setEthernetMatch(eth.build());
2928 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2929 ipv4match.setIpv4Destination(dstip);
2931 matchBuilder.setLayer3Match(ipv4match.build());
2933 return matchBuilder;
2938 * @param matchBuilder MatchBuilder Object without a match yet
2939 * @param srcip String containing an IPv4 prefix
2940 * @return matchBuilder Map Object with a match
2942 private static MatchBuilder createSrcL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix srcip) {
2944 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2945 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2946 ethTypeBuilder.setType(new EtherType(0x0800L));
2947 eth.setEthernetType(ethTypeBuilder.build());
2948 matchBuilder.setEthernetMatch(eth.build());
2950 Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
2951 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2952 ipv4match.setIpv4Source(srcip);
2953 matchBuilder.setLayer3Match(ipv4match.build());
2955 return matchBuilder;
2960 * Create Source TCP Port Match
2962 * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
2963 * @param tcpport Integer representing a source TCP port
2964 * @return matchBuilder Map MatchBuilder Object with a match
2966 protected static MatchBuilder createSetSrcTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2968 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2969 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2970 ethTypeBuilder.setType(new EtherType(0x0800L));
2971 ethType.setEthernetType(ethTypeBuilder.build());
2972 matchBuilder.setEthernetMatch(ethType.build());
2974 IpMatchBuilder ipmatch = new IpMatchBuilder();
2975 ipmatch.setIpProtocol((short) 6);
2976 matchBuilder.setIpMatch(ipmatch.build());
2978 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2979 tcpmatch.setTcpSourcePort(tcpport);
2980 matchBuilder.setLayer4Match(tcpmatch.build());
2982 return matchBuilder;
2987 * Create Destination TCP Port Match
2989 * @param matchBuilder MatchBuilder Object without a match yet
2990 * @param tcpport Integer representing a destination TCP port
2991 * @return matchBuilder Map MatchBuilder Object with a match
2993 protected static MatchBuilder createSetDstTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2995 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2996 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2997 ethTypeBuilder.setType(new EtherType(0x0800L));
2998 ethType.setEthernetType(ethTypeBuilder.build());
2999 matchBuilder.setEthernetMatch(ethType.build());
3001 IpMatchBuilder ipmatch = new IpMatchBuilder();
3002 ipmatch.setIpProtocol((short) 6);
3003 matchBuilder.setIpMatch(ipmatch.build());
3005 PortNumber dstport = new PortNumber(tcpport);
3006 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3008 tcpmatch.setTcpDestinationPort(tcpport);
3009 matchBuilder.setLayer4Match(tcpmatch.build());
3011 return matchBuilder;
3015 * Create Send to Controller Reserved Port Instruction (packet_in)
3017 * @param ib Map InstructionBuilder without any instructions
3018 * @return ib Map InstructionBuilder with instructions
3021 protected static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
3023 List<Action> actionList = Lists.newArrayList();
3024 ActionBuilder ab = new ActionBuilder();
3026 OutputActionBuilder output = new OutputActionBuilder();
3027 output.setMaxLength(0xffff);
3028 Uri value = new Uri("CONTROLLER");
3029 output.setOutputNodeConnector(value);
3030 ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
3032 ab.setKey(new ActionKey(0));
3033 actionList.add(ab.build());
3035 // Create an Apply Action
3036 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3037 aab.setAction(actionList);
3039 // Wrap our Apply Action in an Instruction
3040 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3046 * Create NORMAL Reserved Port Instruction (packet_in)
3048 * @param ib Map InstructionBuilder without any instructions
3049 * @return ib Map InstructionBuilder with instructions
3052 protected static InstructionBuilder createNormalInstructions(InstructionBuilder ib) {
3054 List<Action> actionList = Lists.newArrayList();
3055 ActionBuilder ab = new ActionBuilder();
3057 OutputActionBuilder output = new OutputActionBuilder();
3058 Uri value = new Uri("NORMAL");
3059 output.setOutputNodeConnector(value);
3060 ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
3062 ab.setKey(new ActionKey(0));
3063 actionList.add(ab.build());
3065 // Create an Apply Action
3066 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3067 aab.setAction(actionList);
3069 // Wrap our Apply Action in an Instruction
3070 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3076 * Create Output Port Instruction
3078 * @param ib Map InstructionBuilder without any instructions
3079 * @param dpidLong Long the datapath ID of a switch/node
3080 * @param port Long representing a port on a switch/node
3081 * @return ib InstructionBuilder Map with instructions
3083 protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
3085 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3086 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port);
3088 List<Action> actionList = Lists.newArrayList();
3089 ActionBuilder ab = new ActionBuilder();
3090 OutputActionBuilder oab = new OutputActionBuilder();
3091 oab.setOutputNodeConnector(ncid);
3093 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3095 ab.setKey(new ActionKey(0));
3096 actionList.add(ab.build());
3098 // Create an Apply Action
3099 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3100 aab.setAction(actionList);
3101 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3107 * Create Output Port Group Instruction
3109 * @param ib Map InstructionBuilder without any instructions
3110 * @param dpidLong Long the datapath ID of a switch/node
3111 * @param port Long representing a port on a switch/node
3112 * @return ib InstructionBuilder Map with instructions
3114 protected InstructionBuilder createOutputPortInstructions(InstructionBuilder ib,
3115 Long dpidLong, Long port ,
3116 List<Instruction> instructions) {
3117 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3118 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3120 List<Action> actionList = Lists.newArrayList();
3121 ActionBuilder ab = new ActionBuilder();
3123 List<Action> existingActions;
3124 if (instructions != null) {
3125 for (Instruction in : instructions) {
3126 if (in.getInstruction() instanceof ApplyActionsCase) {
3127 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3128 actionList.addAll(existingActions);
3132 /* Create output action for this port*/
3133 OutputActionBuilder oab = new OutputActionBuilder();
3134 oab.setOutputNodeConnector(ncid);
3135 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3136 boolean addNew = true;
3138 /* Find the group action and get the group */
3139 for (Action action : actionList) {
3140 if (action.getAction() instanceof OutputActionCase) {
3141 OutputActionCase opAction = (OutputActionCase)action.getAction();
3142 /* If output port action already in the action list of one of the buckets, skip */
3143 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3150 ab.setOrder(actionList.size());
3151 ab.setKey(new ActionKey(actionList.size()));
3152 actionList.add(ab.build());
3154 // Create an Apply Action
3155 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3156 aab.setAction(actionList);
3157 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3158 logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
3163 * Create Output Port Group Instruction
3165 * @param ib Map InstructionBuilder without any instructions
3166 * @param dpidLong Long the datapath ID of a switch/node
3167 * @param port Long representing a port on a switch/node
3168 * @return ib InstructionBuilder Map with instructions
3170 protected InstructionBuilder createOutputGroupInstructions(NodeBuilder nodeBuilder,
3171 InstructionBuilder ib,
3172 Long dpidLong, Long port ,
3173 List<Instruction> instructions) {
3174 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3175 logger.debug("createOutputGroupInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3177 List<Action> actionList = Lists.newArrayList();
3178 ActionBuilder ab = new ActionBuilder();
3180 List<Action> existingActions;
3181 if (instructions != null) {
3182 for (Instruction in : instructions) {
3183 if (in.getInstruction() instanceof ApplyActionsCase) {
3184 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3185 actionList.addAll(existingActions);
3190 GroupBuilder groupBuilder = new GroupBuilder();
3193 /* Create output action for this port*/
3194 OutputActionBuilder oab = new OutputActionBuilder();
3195 oab.setOutputNodeConnector(ncid);
3196 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3197 logger.debug("createOutputGroupInstructions(): output action {}", ab.build());
3198 boolean addNew = true;
3199 boolean groupActionAdded = false;
3201 /* Find the group action and get the group */
3202 for (Action action : actionList) {
3203 if (action.getAction() instanceof GroupActionCase) {
3204 groupActionAdded = true;
3205 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3206 Long id = groupAction.getGroupAction().getGroupId();
3207 String groupName = groupAction.getGroupAction().getGroup();
3208 GroupKey key = new GroupKey(new GroupId(id));
3210 groupBuilder.setGroupId(new GroupId(id));
3211 groupBuilder.setGroupName(groupName);
3212 groupBuilder.setGroupType(GroupTypes.GroupAll);
3213 groupBuilder.setKey(key);
3214 group = getGroup(groupBuilder, nodeBuilder);
3215 logger.debug("createOutputGroupInstructions: group {}", group);
3220 logger.debug("createOutputGroupInstructions: groupActionAdded {}", groupActionAdded);
3221 if (groupActionAdded) {
3222 /* modify the action bucket in group */
3223 groupBuilder = new GroupBuilder(group);
3224 Buckets buckets = groupBuilder.getBuckets();
3225 for (Bucket bucket : buckets.getBucket()) {
3226 List<Action> bucketActions = bucket.getAction();
3227 logger.debug("createOutputGroupInstructions: bucketActions {}", bucketActions);
3228 for (Action action : bucketActions) {
3229 if (action.getAction() instanceof OutputActionCase) {
3230 OutputActionCase opAction = (OutputActionCase)action.getAction();
3231 /* If output port action already in the action list of one of the buckets, skip */
3232 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3239 logger.debug("createOutputGroupInstructions: addNew {}", addNew);
3241 /* the new output action is not in the bucket, add to bucket */
3242 if (!buckets.getBucket().isEmpty()) {
3243 Bucket bucket = buckets.getBucket().get(0);
3244 List<Action> bucketActionList = Lists.newArrayList();
3245 bucketActionList.addAll(bucket.getAction());
3246 /* set order for new action and add to action list */
3247 ab.setOrder(bucketActionList.size());
3248 ab.setKey(new ActionKey(bucketActionList.size()));
3249 bucketActionList.add(ab.build());
3251 /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3252 BucketsBuilder bucketsBuilder = new BucketsBuilder();
3253 List<Bucket> bucketList = Lists.newArrayList();
3254 BucketBuilder bucketBuilder = new BucketBuilder();
3255 bucketBuilder.setBucketId(new BucketId((long) 1));
3256 bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3257 bucketBuilder.setAction(bucketActionList);
3258 bucketList.add(bucketBuilder.build());
3259 bucketsBuilder.setBucket(bucketList);
3260 groupBuilder.setBuckets(bucketsBuilder.build());
3261 logger.debug("createOutputGroupInstructions: bucketList {}", bucketList);
3266 groupBuilder = new GroupBuilder();
3267 groupBuilder.setGroupType(GroupTypes.GroupAll);
3268 groupBuilder.setGroupId(new GroupId(groupId));
3269 groupBuilder.setKey(new GroupKey(new GroupId(groupId)));
3270 groupBuilder.setGroupName("Output port group" + groupId);
3271 groupBuilder.setBarrier(false);
3273 BucketsBuilder bucketBuilder = new BucketsBuilder();
3274 List<Bucket> bucketList = Lists.newArrayList();
3275 BucketBuilder bucket = new BucketBuilder();
3276 bucket.setBucketId(new BucketId((long) 1));
3277 bucket.setKey(new BucketKey(new BucketId((long) 1)));
3279 /* put output action to the bucket */
3280 List<Action> bucketActionList = Lists.newArrayList();
3281 /* set order for new action and add to action list */
3282 ab.setOrder(bucketActionList.size());
3283 ab.setKey(new ActionKey(bucketActionList.size()));
3284 bucketActionList.add(ab.build());
3286 bucket.setAction(bucketActionList);
3287 bucketList.add(bucket.build());
3288 bucketBuilder.setBucket(bucketList);
3289 groupBuilder.setBuckets(bucketBuilder.build());
3291 /* Add new group action */
3292 GroupActionBuilder groupActionB = new GroupActionBuilder();
3293 groupActionB.setGroupId(groupId);
3294 groupActionB.setGroup("Output port group" + groupId);
3295 ab = new ActionBuilder();
3296 ab.setAction(new GroupActionCaseBuilder().setGroupAction(groupActionB.build()).build());
3297 ab.setOrder(actionList.size());
3298 ab.setKey(new ActionKey(actionList.size()));
3299 actionList.add(ab.build());
3303 logger.debug("createOutputGroupInstructions: group {}", groupBuilder.build());
3304 logger.debug("createOutputGroupInstructions: actionList {}", actionList);
3307 /* rewrite the group to group table */
3308 writeGroup(groupBuilder, nodeBuilder);
3311 // Create an Apply Action
3312 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3313 aab.setAction(actionList);
3314 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3320 * add Output Port action to Instruction action list.
3321 * This is use for flow with single output port actions.
3322 * Flow with mutiple output port actions should use createOutputPortInstructions() method.
3324 * @param ib Map InstructionBuilder without any instructions
3325 * @param dpidLong Long the datapath ID of a switch/node
3326 * @param port Long representing a port on a switch/node
3327 * @return ib InstructionBuilder Map with instructions
3329 protected static InstructionBuilder addOutputPortInstructions(InstructionBuilder ib,
3330 Long dpidLong, Long port ,
3331 List<Instruction> instructions) {
3332 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3333 logger.debug("addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3335 List<Action> actionList = Lists.newArrayList();
3336 ActionBuilder ab = new ActionBuilder();
3338 List<Action> existingActions;
3339 if (instructions != null) {
3340 for (Instruction in : instructions) {
3341 if (in.getInstruction() instanceof ApplyActionsCase) {
3342 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3343 actionList.addAll(existingActions);
3348 /* Create output action for this port*/
3349 OutputActionBuilder oab = new OutputActionBuilder();
3350 oab.setOutputNodeConnector(ncid);
3351 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3352 ab.setOrder(actionList.size());
3353 ab.setKey(new ActionKey(actionList.size()));
3354 actionList.add(ab.build());
3356 // Create an Apply Action
3357 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3358 aab.setAction(actionList);
3359 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3365 * Remove Output Port from action list in group bucket
3367 * @param ib Map InstructionBuilder without any instructions
3368 * @param dpidLong Long the datapath ID of a switch/node
3369 * @param port Long representing a port on a switch/node
3370 * @return ib InstructionBuilder Map with instructions
3372 protected boolean removeOutputPortFromGroup(NodeBuilder nodeBuilder, InstructionBuilder ib,
3373 Long dpidLong, Long port , List<Instruction> instructions) {
3375 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3376 logger.debug("removeOutputPortFromGroup() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3378 List<Action> actionList = Lists.newArrayList();
3381 List<Action> existingActions;
3382 if (instructions != null) {
3383 for (Instruction in : instructions) {
3384 if (in.getInstruction() instanceof ApplyActionsCase) {
3385 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3386 actionList.addAll(existingActions);
3392 GroupBuilder groupBuilder = new GroupBuilder();
3394 boolean groupActionAdded = false;
3395 /* Find the group action and get the group */
3396 for (Action action : actionList) {
3397 if (action.getAction() instanceof GroupActionCase) {
3398 groupActionAdded = true;
3399 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3400 Long id = groupAction.getGroupAction().getGroupId();
3401 String groupName = groupAction.getGroupAction().getGroup();
3402 GroupKey key = new GroupKey(new GroupId(id));
3404 groupBuilder.setGroupId(new GroupId(id));
3405 groupBuilder.setGroupName(groupName);
3406 groupBuilder.setGroupType(GroupTypes.GroupAll);
3407 groupBuilder.setKey(key);
3408 group = getGroup(groupBuilder, nodeBuilder);
3413 if (groupActionAdded) {
3414 /* modify the action bucket in group */
3415 groupBuilder = new GroupBuilder(group);
3416 Buckets buckets = groupBuilder.getBuckets();
3417 List<Action> bucketActions = Lists.newArrayList();
3418 for (Bucket bucket : buckets.getBucket()) {
3420 boolean isPortDeleted = false;
3421 bucketActions = bucket.getAction();
3422 for (Action action : bucketActions) {
3423 if (action.getAction() instanceof OutputActionCase) {
3424 OutputActionCase opAction = (OutputActionCase)action.getAction();
3425 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3426 /* Find the output port in action list and remove */
3427 index = bucketActions.indexOf(action);
3428 bucketActions.remove(action);
3429 isPortDeleted = true;
3434 if (isPortDeleted && !bucketActions.isEmpty()) {
3435 for (int i = index; i< bucketActions.size(); i++) {
3436 Action action = bucketActions.get(i);
3437 if (action.getOrder() != i) {
3438 /* Shift the action order */
3439 ab = new ActionBuilder();
3440 ab.setAction(action.getAction());
3442 ab.setKey(new ActionKey(i));
3443 Action actionNewOrder = ab.build();
3444 bucketActions.remove(action);
3445 bucketActions.add(i, actionNewOrder);
3449 } else if (bucketActions.isEmpty()) {
3450 /* remove bucket with empty action list */
3451 buckets.getBucket().remove(bucket);
3455 if (!buckets.getBucket().isEmpty()) {
3456 /* rewrite the group to group table */
3457 /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3458 BucketsBuilder bucketsBuilder = new BucketsBuilder();
3459 List<Bucket> bucketList = Lists.newArrayList();
3460 BucketBuilder bucketBuilder = new BucketBuilder();
3461 bucketBuilder.setBucketId(new BucketId((long) 1));
3462 bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3463 bucketBuilder.setAction(bucketActions);
3464 bucketList.add(bucketBuilder.build());
3465 bucketsBuilder.setBucket(bucketList);
3466 groupBuilder.setBuckets(bucketsBuilder.build());
3467 logger.debug("removeOutputPortFromGroup: bucketList {}", bucketList);
3469 writeGroup(groupBuilder, nodeBuilder);
3470 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3471 aab.setAction(actionList);
3472 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3475 /* remove group with empty bucket. return true to delete flow */
3476 removeGroup(groupBuilder, nodeBuilder);
3480 /* no group for port list. flow can be removed */
3486 * Remove Output Port from Instruction
3488 * @param ib Map InstructionBuilder without any instructions
3489 * @param dpidLong Long the datapath ID of a switch/node
3490 * @param port Long representing a port on a switch/node
3491 * @return ib InstructionBuilder Map with instructions
3493 protected static boolean removeOutputPortFromInstructions(InstructionBuilder ib,
3494 Long dpidLong, Long port , List<Instruction> instructions) {
3496 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3497 logger.debug("removeOutputPortFromInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3499 List<Action> actionList = Lists.newArrayList();
3502 List<Action> existingActions;
3503 if (instructions != null) {
3504 for (Instruction in : instructions) {
3505 if (in.getInstruction() instanceof ApplyActionsCase) {
3506 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3507 actionList.addAll(existingActions);
3514 boolean isPortDeleted = false;
3515 boolean removeFlow = true;
3516 for (Action action : actionList) {
3517 if (action.getAction() instanceof OutputActionCase) {
3518 OutputActionCase opAction = (OutputActionCase)action.getAction();
3519 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3520 /* Find the output port in action list and remove */
3521 index = actionList.indexOf(action);
3522 actionList.remove(action);
3523 isPortDeleted = true;
3530 if (isPortDeleted) {
3531 for (int i = index; i< actionList.size(); i++) {
3532 Action action = actionList.get(i);
3533 if (action.getOrder() != i) {
3534 /* Shift the action order */
3535 ab = new ActionBuilder();
3536 ab.setAction(action.getAction());
3538 ab.setKey(new ActionKey(i));
3539 Action actionNewOrder = ab.build();
3540 actionList.remove(action);
3541 actionList.add(i, actionNewOrder);
3543 if (action.getAction() instanceof OutputActionCase) {
3549 /* Put new action list in Apply Action instruction */
3551 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3552 aab.setAction(actionList);
3553 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3554 logger.debug("removeOutputPortFromInstructions() : applyAction {}", aab.build());
3557 /* if all output port are removed. Return true to indicate flow remove */
3563 * Create Set Vlan ID Instruction - This includes push vlan action, and set field -> vlan vid action
3565 * @param ib Map InstructionBuilder without any instructions
3566 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
3567 * @return ib Map InstructionBuilder with instructions
3569 protected static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
3571 List<Action> actionList = Lists.newArrayList();
3572 ActionBuilder ab = new ActionBuilder();
3574 /* First we push vlan header */
3575 PushVlanActionBuilder vlan = new PushVlanActionBuilder();
3576 vlan.setEthernetType(new Integer(0x8100));
3577 ab.setAction(new PushVlanActionCaseBuilder().setPushVlanAction(vlan.build()).build());
3579 actionList.add(ab.build());
3581 /* Then we set vlan id value as vlanId */
3582 SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
3583 vl.setVlanId(vlanId);
3584 ab = new ActionBuilder();
3585 ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
3587 actionList.add(ab.build());
3588 // Create an Apply Action
3589 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3590 aab.setAction(actionList);
3592 // Wrap our Apply Action in an Instruction
3593 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3599 * Create Pop Vlan Instruction - this remove vlan header
3601 * @param ib Map InstructionBuilder without any instructions
3602 * @return ib Map InstructionBuilder with instructions
3604 protected static InstructionBuilder createPopVlanInstructions(InstructionBuilder ib) {
3606 List<Action> actionList = Lists.newArrayList();
3607 ActionBuilder ab = new ActionBuilder();
3609 PopVlanActionBuilder popVlanActionBuilder = new PopVlanActionBuilder();
3610 ab.setAction(new PopVlanActionCaseBuilder().setPopVlanAction(popVlanActionBuilder.build()).build());
3612 actionList.add(ab.build());
3614 // Create an Apply Action
3615 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3616 aab.setAction(actionList);
3618 // Wrap our Apply Action in an Instruction
3619 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3625 * Create Set IPv4 Source Instruction
3627 * @param ib Map InstructionBuilder without any instructions
3628 * @param prefixsrc String containing an IPv4 prefix
3629 * @return ib Map InstructionBuilder with instructions
3631 protected static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
3633 List<Action> actionList = Lists.newArrayList();
3634 ActionBuilder ab = new ActionBuilder();
3636 SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
3637 Ipv4Builder ipsrc = new Ipv4Builder();
3638 ipsrc.setIpv4Address(prefixsrc);
3639 setNwsrcActionBuilder.setAddress(ipsrc.build());
3640 ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
3641 actionList.add(ab.build());
3643 // Create an Apply Action
3644 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3645 aab.setAction(actionList);
3647 // Wrap our Apply Action in an Instruction
3648 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3654 * Create Set IPv4 Destination Instruction
3656 * @param ib Map InstructionBuilder without any instructions
3657 * @param prefixdst String containing an IPv4 prefix
3658 * @return ib Map InstructionBuilder with instructions
3660 protected static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
3662 List<Action> actionList = Lists.newArrayList();
3663 ActionBuilder ab = new ActionBuilder();
3665 SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
3666 Ipv4Builder ipdst = new Ipv4Builder();
3667 ipdst.setIpv4Address(prefixdst);
3668 setNwDstActionBuilder.setAddress(ipdst.build());
3669 ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
3670 actionList.add(ab.build());
3672 // Create an Apply Action
3673 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3674 aab.setAction(actionList);
3676 // Wrap our Apply Action in an Instruction
3677 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3683 * Create Drop Instruction
3685 * @param ib Map InstructionBuilder without any instructions
3686 * @return ib Map InstructionBuilder with instructions
3688 protected static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
3690 DropActionBuilder dab = new DropActionBuilder();
3691 DropAction dropAction = dab.build();
3692 ActionBuilder ab = new ActionBuilder();
3693 ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
3696 // Add our drop action to a list
3697 List<Action> actionList = Lists.newArrayList();
3698 actionList.add(ab.build());
3700 // Create an Apply Action
3701 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3702 aab.setAction(actionList);
3704 // Wrap our Apply Action in an Instruction
3705 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3711 * Create GOTO Table Instruction Builder
3713 * @param ib Map InstructionBuilder without any instructions
3714 * @param tableId short representing a flow table ID short representing a flow table ID
3715 * @return ib Map InstructionBuilder with instructions
3717 protected static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
3719 GoToTableBuilder gttb = new GoToTableBuilder();
3720 gttb.setTableId(tableId);
3722 // Wrap our Apply Action in an InstructionBuilder
3723 ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
3729 * Create Set Tunnel ID Instruction Builder
3731 * @param ib Map InstructionBuilder without any instructions
3732 * @param tunnelId BigInteger representing a tunnel ID
3733 * @return ib Map InstructionBuilder with instructions
3735 protected static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
3737 List<Action> actionList = Lists.newArrayList();
3738 ActionBuilder ab = new ActionBuilder();
3739 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3741 // Build the Set Tunnel Field Action
3742 TunnelBuilder tunnel = new TunnelBuilder();
3743 tunnel.setTunnelId(tunnelId);
3744 setFieldBuilder.setTunnel(tunnel.build());
3745 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3747 actionList.add(ab.build());
3749 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3750 aab.setAction(actionList);
3752 // Wrap the Apply Action in an InstructionBuilder and return
3753 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3759 * Create Set Source TCP Port Instruction
3761 * @param ib Map InstructionBuilder without any instructions
3762 * @param tcpport Integer representing a source TCP port
3763 * @return ib Map InstructionBuilder with instructions
3765 protected static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3767 List<Action> actionList = Lists.newArrayList();
3768 ActionBuilder ab = new ActionBuilder();
3769 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3771 // Build the Destination TCP Port
3772 PortNumber tcpsrcport = new PortNumber(tcpport);
3773 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3774 tcpmatch.setTcpSourcePort(tcpsrcport);
3776 setFieldBuilder.setLayer4Match(tcpmatch.build());
3777 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3778 ab.setKey(new ActionKey(1));
3779 actionList.add(ab.build());
3781 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3782 aab.setAction(actionList);
3783 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3789 * Create Set Destination TCP Port Instruction
3791 * @param ib Map InstructionBuilder without any instructions
3792 * @param tcpport Integer representing a source TCP port
3793 * @return ib Map InstructionBuilder with instructions
3795 protected static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3797 List<Action> actionList = Lists.newArrayList();
3798 ActionBuilder ab = new ActionBuilder();
3799 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3801 // Build the Destination TCP Port
3802 PortNumber tcpdstport = new PortNumber(tcpport);
3803 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3804 tcpmatch.setTcpDestinationPort(tcpdstport);
3806 setFieldBuilder.setLayer4Match(tcpmatch.build());
3807 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3808 ab.setKey(new ActionKey(1));
3809 actionList.add(ab.build());
3811 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3812 aab.setAction(actionList);
3813 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3819 * Create Set Source UDP Port Instruction
3821 * @param ib Map InstructionBuilder without any instructions
3822 * @param udpport Integer representing a source UDP port
3823 * @return ib Map InstructionBuilder with instructions
3825 protected static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
3827 List<Action> actionList = Lists.newArrayList();
3828 ActionBuilder ab = new ActionBuilder();
3829 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3831 // Build the Destination TCP Port
3832 PortNumber udpsrcport = new PortNumber(udpport);
3833 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3834 udpmatch.setUdpSourcePort(udpsrcport);
3836 setFieldBuilder.setLayer4Match(udpmatch.build());
3837 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3838 ab.setKey(new ActionKey(1));
3839 actionList.add(ab.build());
3841 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3842 aab.setAction(actionList);
3843 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3849 * Create Set Destination UDP Port Instruction
3851 * @param ib Map InstructionBuilder without any instructions
3852 * @param udpport Integer representing a destination UDP port
3853 * @return ib Map InstructionBuilder with instructions
3855 protected static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
3857 List<Action> actionList = Lists.newArrayList();
3858 ActionBuilder ab = new ActionBuilder();
3859 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3861 // Build the Destination TCP Port
3862 PortNumber udpdstport = new PortNumber(udpport);
3863 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3864 udpmatch.setUdpDestinationPort(udpdstport);
3866 setFieldBuilder.setLayer4Match(udpmatch.build());
3867 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3868 ab.setKey(new ActionKey(1));
3869 actionList.add(ab.build());
3871 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3872 aab.setAction(actionList);
3873 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3879 * Create Set ICMP Code Instruction
3881 * @param ib Map InstructionBuilder without any instructions
3882 * @param code short repesenting an ICMP code
3883 * @return ib Map InstructionBuilder with instructions
3886 private static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
3888 List<Action> actionList = Lists.newArrayList();
3889 ActionBuilder ab = new ActionBuilder();
3890 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3891 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3893 // Build the ICMPv4 Code Match
3894 icmpv4match.setIcmpv4Code(code);
3895 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3897 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3898 ab.setKey(new ActionKey(0));
3899 actionList.add(ab.build());
3900 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3901 aab.setAction(actionList);
3903 // Wrap our Apply Action in an Instruction
3904 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3910 * Create Set ICMP Code Instruction
3912 * @param ib Map InstructionBuilder without any instructions
3913 * @return ib Map InstructionBuilder with instructions
3915 private static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
3917 List<Action> actionList = Lists.newArrayList();
3918 ActionBuilder ab = new ActionBuilder();
3919 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3920 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3922 // Build the ICMPv4 Code Match
3923 icmpv4match.setIcmpv4Code(type);
3924 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3926 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3927 ab.setKey(new ActionKey(1));
3928 actionList.add(ab.build());
3929 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3930 aab.setAction(actionList);
3932 // Wrap our Apply Action in an Instruction
3933 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3939 * Create Decrement TTL Instruction
3941 * @param ib Map InstructionBuilder without any instructions
3942 * @return ib Map InstructionBuilder with instructions
3944 private static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
3945 DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
3946 DecNwTtl decNwTtl = decNwTtlBuilder.build();
3947 ActionBuilder ab = new ActionBuilder();
3948 ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
3950 // Add our drop action to a list
3951 List<Action> actionList = Lists.newArrayList();
3952 actionList.add(ab.build());
3954 // Create an Apply Action
3955 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3956 aab.setAction(actionList);
3958 // Wrap our Apply Action in an Instruction
3959 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3967 private static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
3969 List<Action> actionList = Lists.newArrayList();
3970 ActionBuilder ab = new ActionBuilder();
3972 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3973 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3974 ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
3975 arpsrc.setAddress(macsrc);
3976 arpmatch.setArpSourceHardwareAddress(arpsrc.build());
3977 setFieldBuilder.setLayer3Match(arpmatch.build());
3978 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3979 ab.setKey(new ActionKey(0));
3980 actionList.add(ab.build());
3982 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3983 aab.setAction(actionList);
3991 private static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
3993 List<Action> actionList = Lists.newArrayList();
3994 ActionBuilder ab = new ActionBuilder();
3995 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3997 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3998 ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
3999 arpdst.setAddress(macdst);
4000 setFieldBuilder.setLayer3Match(arpmatch.build());
4001 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
4002 ab.setKey(new ActionKey(0));
4003 actionList.add(ab.build());
4005 ApplyActionsBuilder aab = new ApplyActionsBuilder();
4006 aab.setAction(actionList);
4014 private static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
4016 List<Action> actionList = Lists.newArrayList();
4017 ActionBuilder ab = new ActionBuilder();
4018 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
4020 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
4021 arpmatch.setArpTargetTransportAddress(dstiparp);
4022 setFieldBuilder.setLayer3Match(arpmatch.build());
4023 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
4024 ab.setKey(new ActionKey(0));
4025 actionList.add(ab.build());
4027 ApplyActionsBuilder aab = new ApplyActionsBuilder();
4028 aab.setAction(actionList);
4036 private static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
4038 List<Action> actionList = Lists.newArrayList();
4039 ActionBuilder ab = new ActionBuilder();
4040 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
4042 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
4043 arpmatch.setArpSourceTransportAddress(srciparp);
4044 setFieldBuilder.setLayer3Match(arpmatch.build());
4045 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
4046 ab.setKey(new ActionKey(0));
4047 actionList.add(ab.build());
4049 ApplyActionsBuilder aab = new ApplyActionsBuilder();
4050 aab.setAction(actionList);
4056 public void initializeOFFlowRules(Node openflowNode) {
4057 Preconditions.checkNotNull(connectionService);
4058 List<Node> ovsNodes = connectionService.getNodes();
4059 if (ovsNodes == null) return;
4060 for (Node ovsNode : ovsNodes) {
4061 Long brIntDpid = this.getIntegrationBridgeOFDPID(ovsNode);
4062 Long brExDpid = this.getExternalBridgeDpid(ovsNode);
4063 logger.debug("Compare openflowNode to OVS node {} vs {} and {}", openflowNode.getID(), brIntDpid, brExDpid);
4064 String openflowID = openflowNode.getID().toString();
4065 if (openflowID.contains(brExDpid.toString())) {
4066 this.initializeFlowRules(ovsNode, configurationService.getExternalBridgeName());
4067 this.triggerInterfaceUpdates(ovsNode);
4069 if (openflowID.contains(brIntDpid.toString())) {
4070 this.initializeFlowRules(ovsNode, configurationService.getIntegrationBridgeName());
4071 this.triggerInterfaceUpdates(ovsNode);
4076 private NodeBuilder createNodeBuilder(String nodeId) {
4077 NodeBuilder builder = new NodeBuilder();
4078 builder.setId(new NodeId(nodeId));
4079 builder.setKey(new NodeKey(builder.getId()));
4083 private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeBuilderToInstanceId(NodeBuilder
4085 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
4086 node.getKey()).toInstance();
4089 private String getInternalBridgeUUID (Node node, String bridgeName) {
4090 Preconditions.checkNotNull(ovsdbConfigurationService);
4092 Map<String, Row> bridgeTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Bridge.class));
4093 if (bridgeTable == null) return null;
4094 for (String key : bridgeTable.keySet()) {
4095 Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeTable.get(key));
4096 if (bridge.getName().equals(bridgeName)) return key;
4098 } catch (Exception e) {
4099 logger.error("Error getting Bridge Identifier for {} / {}", node, bridgeName, e);