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.neutron.provider;
12 import java.math.BigInteger;
13 import java.net.InetAddress;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.Future;
22 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
23 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
24 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
25 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
26 import org.opendaylight.controller.sal.core.Node;
27 import org.opendaylight.controller.sal.utils.HexEncode;
28 import org.opendaylight.controller.sal.utils.ServiceHelper;
29 import org.opendaylight.controller.sal.utils.Status;
30 import org.opendaylight.controller.sal.utils.StatusCode;
31 import org.opendaylight.controller.switchmanager.ISwitchManager;
32 import org.opendaylight.ovsdb.lib.notation.Row;
33 import org.opendaylight.ovsdb.lib.notation.UUID;
34 import org.opendaylight.ovsdb.neutron.IAdminConfigManager;
35 import org.opendaylight.ovsdb.neutron.IInternalNetworkManager;
36 import org.opendaylight.ovsdb.neutron.IMDSALConsumer;
37 import org.opendaylight.ovsdb.neutron.ITenantNetworkManager;
38 import org.opendaylight.ovsdb.neutron.NetworkHandler;
39 import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
40 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
41 import org.opendaylight.ovsdb.plugin.StatusWithUuid;
42 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
43 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
44 import org.opendaylight.ovsdb.schema.openvswitch.Port;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketKey;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
129 import org.opendaylight.yangtools.yang.binding.DataObject;
130 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
131 import org.opendaylight.yangtools.yang.common.RpcResult;
132 import org.slf4j.Logger;
133 import org.slf4j.LoggerFactory;
139 public class OF13Provider implements NetworkProvider {
140 private static final Logger logger = LoggerFactory.getLogger(OF13Provider.class);
141 private DataBrokerService dataBrokerService;
142 private static final short TABLE_0_DEFAULT_INGRESS = 0;
143 private static final short TABLE_1_ISOLATE_TENANT = 10;
144 private static final short TABLE_2_LOCAL_FORWARD = 20;
145 private static Long groupId = 1L;
147 private IAdminConfigManager adminConfigManager;
148 private IInternalNetworkManager internalNetworkManager;
149 private ITenantNetworkManager tenantNetworkManager;
151 public OF13Provider(IAdminConfigManager adminConfigManager,
152 IInternalNetworkManager internalNetworkManager,
153 ITenantNetworkManager tenantNetworkManager) {
154 this.adminConfigManager = adminConfigManager;
155 this.internalNetworkManager = internalNetworkManager;
156 this.tenantNetworkManager = tenantNetworkManager;
160 public boolean hasPerTenantTunneling() {
164 private Status getTunnelReadinessStatus (Node node, String tunnelKey) {
165 InetAddress srcTunnelEndPoint = adminConfigManager.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 (!internalNetworkManager.isInternalNetworkNeutronReady(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 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
189 Row bridgeRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Bridge.class), bridgeUUID);
190 Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeRow);
191 if (bridge != null) {
192 Set<UUID> ports = bridge.getPortsColumn().getData();
193 for (UUID portUUID : ports) {
194 Row portRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Port.class), portUUID.toString());
195 Port port = ovsdbTable.getTypedRow(node, Port.class, portRow);
196 if (port != null && port.getName().equalsIgnoreCase(tunnelName)) return true;
202 private String getPortUuid(Node node, String name, String bridgeUUID) throws Exception {
203 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
204 Row bridgeRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Bridge.class), bridgeUUID);
205 Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeRow);
206 if (bridge != null) {
207 Set<UUID> ports = bridge.getPortsColumn().getData();
208 for (UUID portUUID : ports) {
209 Row portRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Port.class), portUUID.toString());
210 Port port = ovsdbTable.getTypedRow(node, Port.class, portRow);
211 if (port != null && port.getName().equalsIgnoreCase(name)) return portUUID.toString();
217 private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst) {
219 String bridgeUUID = null;
220 String tunnelBridgeName = adminConfigManager.getIntegrationBridgeName();
221 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
222 Map<String, Row> bridgeTable = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Bridge.class));
223 if (bridgeTable != null) {
224 for (String uuid : bridgeTable.keySet()) {
225 Bridge bridge = ovsdbTable.getTypedRow(node,Bridge.class, bridgeTable.get(uuid));
226 if (bridge.getName().equals(tunnelBridgeName)) {
232 if (bridgeUUID == null) {
233 logger.error("Could not find Bridge {} in {}", tunnelBridgeName, node);
234 return new Status(StatusCode.NOTFOUND, "Could not find "+tunnelBridgeName+" in "+node);
236 String portName = getTunnelName(tunnelType, dst);
238 if (this.isTunnelPresent(node, portName, bridgeUUID)) {
239 logger.trace("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node);
240 return new Status(StatusCode.SUCCESS);
243 Port tunnelPort = ovsdbTable.createTypedRow(node, Port.class);
244 tunnelPort.setName(portName);
245 StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, ovsdbTable.getTableName(node, Port.class), bridgeUUID, tunnelPort.getRow());
246 if (!statusWithUuid.isSuccess()) {
247 logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID);
248 return statusWithUuid;
251 String tunnelPortUUID = statusWithUuid.getUuid().toString();
252 String interfaceUUID = null;
254 while ((interfaceUUID == null) && (timeout > 0)) {
255 Row portRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Port.class), tunnelPortUUID);
256 tunnelPort = ovsdbTable.getTypedRow(node, Port.class, portRow);
257 Set<UUID> interfaces = tunnelPort.getInterfacesColumn().getData();
258 if (interfaces == null || interfaces.size() == 0) {
259 // Wait for the OVSDB update to sync up the Local cache.
264 interfaceUUID = interfaces.toArray()[0].toString();
265 Interface intf = (Interface)ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Interface.class), interfaceUUID);
266 if (intf == null) interfaceUUID = null;
269 if (interfaceUUID == null) {
270 logger.error("Cannot identify Tunnel Interface for port {}/{}", portName, tunnelPortUUID);
271 return new Status(StatusCode.INTERNALERROR);
274 Interface tunInterface = ovsdbTable.createTypedRow(node, Interface.class);
275 tunInterface.setType(tunnelType);
276 Map<String, String> options = new HashMap<String, String>();
277 options.put("key", "flow");
278 options.put("local_ip", src.getHostAddress());
279 options.put("remote_ip", dst.getHostAddress());
280 tunInterface.setOptions(options);
281 Status status = ovsdbTable.updateRow(node, ovsdbTable.getTableName(node, Interface.class), tunnelPortUUID, interfaceUUID, tunInterface.getRow());
282 logger.debug("Tunnel {} add status : {}", tunInterface, status);
284 } catch (Exception e) {
285 logger.error("Exception in addTunnelPort", e);
286 return new Status(StatusCode.INTERNALERROR);
290 /* delete port from ovsdb port table */
291 private Status deletePort(Node node, String bridgeName, String portName) {
293 String bridgeUUID = null;
294 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
295 Map<String, Row> bridgeTable = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Bridge.class));
296 if (bridgeTable != null) {
297 for (String uuid : bridgeTable.keySet()) {
298 Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeTable.get(uuid));
299 if (bridge.getName().equals(bridgeName)) {
305 if (bridgeUUID == null) {
306 logger.debug("Could not find Bridge {} in {}", bridgeName, node);
307 return new Status(StatusCode.SUCCESS);
310 String portUUID = this.getPortUuid(node, portName, bridgeUUID);
311 Status status = new Status(StatusCode.SUCCESS);
312 if (portUUID != null) {
313 status = ovsdbTable.deleteRow(node, ovsdbTable.getTableName(node, Port.class), portUUID);
314 if (!status.isSuccess()) {
315 logger.error("Failed to delete port {} in {} status : {}", portName, bridgeUUID,
319 logger.debug("Port {} delete status : {}", portName, status);
322 } catch (Exception e) {
323 logger.error("Exception in deletePort", e);
324 return new Status(StatusCode.INTERNALERROR);
328 private Status deleteTunnelPort(Node node, String tunnelType, InetAddress src, InetAddress dst) {
329 String tunnelBridgeName = adminConfigManager.getIntegrationBridgeName();
330 String portName = getTunnelName(tunnelType, dst);
331 Status status = deletePort(node, tunnelBridgeName, portName);
335 private Status deletePhysicalPort(Node node, String phyIntfName) {
336 String intBridgeName = adminConfigManager.getIntegrationBridgeName();
337 Status status = deletePort(node, intBridgeName, phyIntfName);
341 private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
345 * Match: VM sMac and Local Ingress Port
346 * Action:Action: Set Tunnel ID and GOTO Local Table (5)
349 handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, true);
354 * Match: Drop any remaining Ingress Local VM Packets
355 * Action: Drop w/ a low priority
358 handleDropSrcIface(dpid, localPort, true);
363 * Match: Match TunID and Destination DL/dMAC Addr
364 * Action: Output Port
365 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
368 handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, true);
373 * Match: Tunnel ID and dMAC (::::FF:FF)
374 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
375 * actions=output:2,3,4,5
378 handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, true);
381 * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
386 * Match: Any remaining Ingress Local VM Packets
387 * Action: Drop w/ a low priority
388 * -------------------------------------------
389 * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
392 handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, true);
397 * Match: Any Remaining Flows w/a TunID
398 * Action: Drop w/ a low priority
399 * table=2,priority=8192,tun_id=0x5 actions=drop
402 handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, true);
405 private void removeLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
409 * Match: VM sMac and Local Ingress Port
410 * Action:Action: Set Tunnel ID and GOTO Local Table (5)
413 handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, false);
418 * Match: Drop any remaining Ingress Local VM Packets
419 * Action: Drop w/ a low priority
422 handleDropSrcIface(dpid, localPort, false);
427 * Match: Match TunID and Destination DL/dMAC Addr
428 * Action: Output Port
429 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
432 handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, false);
437 * Match: Tunnel ID and dMAC (::::FF:FF)
438 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
439 * actions=output:2,3,4,5
442 handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, false);
445 private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
449 * Match: Ingress Port, Tunnel ID
450 * Action: GOTO Local Table (20)
453 handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
458 * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
459 * Action: Flood to selected destination TEPs
460 * -------------------------------------------
461 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
462 * actions=output:10,output:11,goto_table:2
465 handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
469 private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
473 * Match: Drop any remaining Ingress Local VM Packets
474 * Action: Drop w/ a low priority
475 * -------------------------------------------
476 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
477 * actions=output:11,goto_table:2
480 handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, true);
483 private void removeRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
487 * Match: Drop any remaining Ingress Local VM Packets
488 * Action: Drop w/ a low priority
489 * -------------------------------------------
490 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
491 * actions=output:11,goto_table:2
494 handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, false);
497 /* Remove tunnel rules if last node in this tenant network */
498 private void removePerTunnelRules(Node node, Long dpid, String segmentationId, long tunnelOFPort) {
500 * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
505 * Match: Any remaining Ingress Local VM Packets
506 * Action: Drop w/ a low priority
507 * -------------------------------------------
508 * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
511 handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, false);
516 * Match: Any Remaining Flows w/a TunID
517 * Action: Drop w/ a low priority
518 * table=2,priority=8192,tun_id=0x5 actions=drop
521 handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, false);
526 * Match: Ingress Port, Tunnel ID
527 * Action: GOTO Local Table (10)
530 handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
535 * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
536 * Action: Flood to selected destination TEPs
537 * -------------------------------------------
538 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
539 * actions=output:10,output:11,goto_table:2
542 handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
545 private void programLocalVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
549 * Match: VM sMac and Local Ingress Port
550 * Action: Set VLAN ID and GOTO Local Table 1
553 handleLocalInPortSetVlan(dpid, TABLE_0_DEFAULT_INGRESS,
554 TABLE_1_ISOLATE_TENANT, segmentationId, localPort,
560 * Match: Drop any remaining Ingress Local VM Packets
561 * Action: Drop w/ a low priority
564 handleDropSrcIface(dpid, localPort, true);
569 * Match: Match VLAN ID and Destination DL/dMAC Addr
570 * Action: strip vlan, output to local port
571 * Example: table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions= strip vlan, output:2
574 handleLocalVlanUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
575 localPort, attachedMac, true);
580 * Match: VLAN ID and dMAC (::::FF:FF)
581 * Action: strip vlan, output to all local ports in this vlan
582 * Example: table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
583 * actions= strip_vlan, output:2,3,4,5
586 handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
592 * Match: Any Remaining Flows w/a VLAN ID
593 * Action: Drop w/ a low priority
594 * Example: table=2,priority=8192,vlan_id=0x5 actions=drop
597 handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
601 private void removeLocalVlanRules(Node node, Long dpid,
602 String segmentationId, String attachedMac,
607 * Match: VM sMac and Local Ingress Port
608 * Action: Set VLAN ID and GOTO Local Table 1
611 handleLocalInPortSetVlan(dpid, TABLE_0_DEFAULT_INGRESS,
612 TABLE_1_ISOLATE_TENANT, segmentationId, localPort,
618 * Match: Drop any remaining Ingress Local VM Packets
619 * Action: Drop w/ a low priority
622 handleDropSrcIface(dpid, localPort, false);
627 * Match: Match VLAN ID and Destination DL/dMAC Addr
628 * Action: strip vlan, output to local port
629 * Example: table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions= strip vlan, output:2
632 handleLocalVlanUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
633 localPort, attachedMac, false);
638 * Match: VLAN ID and dMAC (::::FF:FF)
639 * Action: strip vlan, output to all local ports in this vlan
640 * Example: table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
641 * actions= strip_vlan, output:2,3,4,5
644 handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
648 private void programLocalIngressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
652 * Match: Ingress port = physical interface, Vlan ID
653 * Action: GOTO Local Table 2
656 handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD,
657 segmentationId, ethPort, true);
662 * Match: Match VLAN ID and L2 ::::FF:FF Flooding
663 * Action: Flood to local and remote VLAN members
664 * -------------------------------------------
665 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
666 * actions=output:10 (eth port),goto_table:2
669 handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
670 segmentationId, ethPort, true);
673 private void programRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
677 * Match: Destination MAC is local VM MAC and vlan id
678 * Action: go to table 2
679 * -------------------------------------------
680 * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
681 * actions=goto_table:2
684 handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
685 segmentationId, ethPort, attachedMac, true);
691 * Action: Go to table 2
692 * -------------------------------------------
693 * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
696 handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
697 segmentationId, ethPort, true);
700 private void removeRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
704 * Match: Destination MAC is local VM MAC and vlan id
705 * Action: go to table 2
706 * -------------------------------------------
707 * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
708 * actions=goto_table:2
711 handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
712 segmentationId, ethPort, attachedMac, false);
715 private void removePerVlanRules(Node node, Long dpid, String segmentationId, long ethPort) {
719 * Match: Any Remaining Flows w/a VLAN ID
720 * Action: Drop w/ a low priority
721 * Example: table=2,priority=8192,vlan_id=0x5 actions=drop
724 handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
730 * Match: Ingress port = physical interface, Vlan ID
731 * Action: GOTO Local Table 2
734 handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD,
735 segmentationId, ethPort, false);
740 * Match: Match VLAN ID and L2 ::::FF:FF Flooding
741 * Action: Flood to local and remote VLAN members
742 * -------------------------------------------
743 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
744 * actions=output:10 (eth port),goto_table:2
747 handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
748 segmentationId, ethPort, false);
754 * Action: Go to table 2
755 * -------------------------------------------
756 * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
759 handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
760 segmentationId, ethPort, false);
762 private Long getDpid (Node node, String bridgeUuid) {
764 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
765 Row bridgeRow = ovsdbTable.getRow(node, ovsdbTable.getTableName(node, Bridge.class), bridgeUuid);
766 Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeRow);
767 Set<String> dpids = bridge.getDatapathIdColumn().getData();
768 if (dpids == null || dpids.size() == 0) return 0L;
769 return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
770 } catch (Exception e) {
771 logger.error("Error finding Bridge's OF DPID", e);
776 private Long getIntegrationBridgeOFDPID (Node node) {
778 String bridgeName = adminConfigManager.getIntegrationBridgeName();
779 String brIntId = this.getInternalBridgeUUID(node, bridgeName);
780 if (brIntId == null) {
781 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
785 return getDpid(node, brIntId);
786 } catch (Exception e) {
787 logger.error("Error finding Integration Bridge's OF DPID", e);
792 private Long getExternalBridgeDpid (Node node) {
794 String bridgeName = adminConfigManager.getExternalBridgeName();
795 String brUuid = this.getInternalBridgeUUID(node, bridgeName);
796 if (brUuid == null) {
797 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
801 return getDpid(node, brUuid);
802 } catch (Exception e) {
803 logger.error("Error finding External Bridge's OF DPID", e);
808 private void programLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
810 Long dpid = this.getIntegrationBridgeOFDPID(node);
812 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
816 Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
817 if (of_ports == null || of_ports.size() <= 0) {
818 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
821 long localPort = ((Integer)of_ports.toArray()[0]).longValue();
823 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
824 if (externalIds == null) {
825 logger.error("No external_ids seen in {}", intf);
829 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
830 if (attachedMac == null) {
831 logger.error("No AttachedMac seen in {}", intf);
835 /* Program local rules based on network type */
836 if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
837 logger.debug("Program local vlan rules for interface {}", intf.getName());
838 programLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
839 } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
840 networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
841 logger.debug("Program local bridge rules for interface {}", intf.getName());
842 programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
844 } catch (Exception e) {
845 logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
849 private void removeLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
851 Long dpid = this.getIntegrationBridgeOFDPID(node);
853 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
857 Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
858 if (of_ports == null || of_ports.size() <= 0) {
859 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
862 long localPort = ((Integer)of_ports.toArray()[0]).longValue();
864 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
865 if (externalIds == null) {
866 logger.error("No external_ids seen in {}", intf);
870 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
871 if (attachedMac == null) {
872 logger.error("No AttachedMac seen in {}", intf);
876 /* Program local rules based on network type */
877 if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
878 logger.debug("Remove local vlan rules for interface {}", intf.getName());
879 removeLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
880 } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
881 networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
882 logger.debug("Remove local bridge rules for interface {}", intf.getName());
883 removeLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
885 } catch (Exception e) {
886 logger.error("Exception in removing Local Rules for "+intf+" on "+node, e);
890 private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
891 Interface intf, boolean local) {
894 Long dpid = this.getIntegrationBridgeOFDPID(node);
896 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
899 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
901 Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
902 if (of_ports == null || of_ports.size() <= 0) {
903 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
906 long localPort = ((Integer)of_ports.toArray()[0]).longValue();
908 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
909 if (externalIds == null) {
910 logger.error("No external_ids seen in {}", intf);
914 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
915 if (attachedMac == null) {
916 logger.error("No AttachedMac seen in {}", intf);
920 Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
922 for (Row row : intfs.values()) {
923 Interface tunIntf = ovsdbTable.getTypedRow(node, Interface.class, row);
924 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
925 of_ports = tunIntf.getOpenFlowPortColumn().getData();
926 if (of_ports == null || of_ports.size() <= 0) {
927 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
930 long tunnelOFPort = ((Integer)of_ports.toArray()[0]).longValue();
932 if (tunnelOFPort == -1) {
933 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
936 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
939 programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
941 logger.trace("program local ingress tunnel rules: node" + node.getNodeIDString() + " intf " + intf.getName());
943 programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
949 } catch (Exception e) {
954 private void removeTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
955 Interface intf, boolean local, boolean isLastInstanceOnNode) {
958 Long dpid = this.getIntegrationBridgeOFDPID(node);
960 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
963 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
965 Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
966 if (of_ports == null || of_ports.size() <= 0) {
967 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
970 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
972 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
973 if (externalIds == null) {
974 logger.error("No external_ids seen in {}", intf);
978 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
979 if (attachedMac == null) {
980 logger.error("No AttachedMac seen in {}", intf);
984 Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
986 for (Row row : intfs.values()) {
987 Interface tunIntf = ovsdbTable.getTypedRow(node, Interface.class, row);
988 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
989 of_ports = tunIntf.getOpenFlowPortColumn().getData();
990 if (of_ports == null || of_ports.size() <= 0) {
991 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
994 long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
996 if (tunnelOFPort == -1) {
997 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
1000 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
1003 removeRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
1005 if (local && isLastInstanceOnNode) {
1006 removePerTunnelRules(node, dpid, segmentationId, tunnelOFPort);
1012 } catch (Exception e) {
1013 logger.error("", e);
1017 private void programVlanRules (NeutronNetwork network, Node node, Interface intf) {
1018 logger.debug("Program vlan rules for interface {}", intf.getName());
1022 Long dpid = this.getIntegrationBridgeOFDPID(node);
1024 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1027 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1029 Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
1031 while ((of_ports == null) && (timeout > 0)) {
1032 of_ports = intf.getOpenFlowPortColumn().getData();
1033 if (of_ports == null || of_ports.size() <= 0) {
1034 // Wait for the OVSDB update to sync up the Local cache.
1040 if (of_ports == null || of_ports.size() <= 0) {
1041 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1045 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
1046 if (externalIds == null) {
1047 logger.error("No external_ids seen in {}", intf);
1051 String attachedMac = externalIds.get(tenantNetworkManager.EXTERNAL_ID_VM_MAC);
1052 if (attachedMac == null) {
1053 logger.error("No AttachedMac seen in {}", intf);
1057 Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
1058 if (intfs != null) {
1059 for (Row row : intfs.values()) {
1060 Interface ethIntf = ovsdbTable.getTypedRow(node, Interface.class, row);
1061 if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()))) {
1062 of_ports = ethIntf.getOpenFlowPortColumn().getData();
1064 while ((of_ports == null) && (timeout > 0)) {
1065 of_ports = ethIntf.getOpenFlowPortColumn().getData();
1066 if (of_ports == null || of_ports.size() <= 0) {
1067 // Wait for the OVSDB update to sync up the Local cache.
1074 if (of_ports == null || of_ports.size() <= 0) {
1075 logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1078 long ethOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
1080 if (ethOFPort == -1) {
1081 logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1082 throw new Exception("port number < 0");
1084 logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1086 programRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1087 programLocalIngressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1092 } catch (Exception e) {
1093 logger.error("", e);
1097 private void removeVlanRules (NeutronNetwork network, Node node,
1098 Interface intf, boolean isLastInstanceOnNode) {
1099 logger.debug("Remove vlan rules for interface {}", intf.getName());
1103 Long dpid = this.getIntegrationBridgeOFDPID(node);
1105 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1108 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1110 Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
1111 if (of_ports == null || of_ports.size() <= 0) {
1112 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1116 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
1117 if (externalIds == null) {
1118 logger.error("No external_ids seen in {}", intf);
1122 String attachedMac = externalIds.get(tenantNetworkManager.EXTERNAL_ID_VM_MAC);
1123 if (attachedMac == null) {
1124 logger.error("No AttachedMac seen in {}", intf);
1128 Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
1129 if (intfs != null) {
1130 for (Row row : intfs.values()) {
1131 Interface ethIntf = ovsdbTable.getTypedRow(node, Interface.class, row);
1132 if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node,
1133 network.getProviderPhysicalNetwork()))) {
1134 of_ports = ethIntf.getOpenFlowPortColumn().getData();
1135 if (of_ports == null || of_ports.size() <= 0) {
1136 logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1139 long ethOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
1141 if (ethOFPort == -1) {
1142 logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1143 throw new Exception("port number < 0");
1145 logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1147 removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1148 if (isLastInstanceOnNode) {
1149 removePerVlanRules(node, dpid, network.getProviderSegmentationID(), ethOFPort);
1155 } catch (Exception e) {
1156 logger.error("", e);
1161 public Status handleInterfaceUpdate(NeutronNetwork network, Node srcNode, Interface intf) {
1162 ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
1163 if (switchManager == null) {
1164 logger.error("Unable to identify SwitchManager");
1166 Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
1168 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
1169 return new Status(StatusCode.NOTFOUND);
1171 Set<Node> ofNodes = switchManager.getNodes();
1172 boolean ofNodeFound = false;
1173 if (ofNodes != null) {
1174 for (Node ofNode : ofNodes) {
1175 if (ofNode.toString().contains(dpid+"")) {
1176 logger.debug("Identified the Openflow node via toString {}", ofNode);
1182 logger.error("Unable to find any Node from SwitchManager");
1185 logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
1186 return new Status(StatusCode.NOTFOUND);
1190 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
1191 List<Node> nodes = connectionService.getNodes();
1192 nodes.remove(srcNode);
1193 this.programLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf);
1195 if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1196 this.programVlanRules(network, srcNode, intf);
1197 } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1198 || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)){
1199 for (Node dstNode : nodes) {
1200 InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
1201 InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
1202 Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst);
1203 if (status.isSuccess()) {
1204 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
1206 addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src);
1207 if (status.isSuccess()) {
1208 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
1213 return new Status(StatusCode.SUCCESS);
1216 private Status triggerInterfaceUpdates(Node node) {
1218 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1219 Map<String, Row> intfs = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Interface.class));
1220 if (intfs != null) {
1221 for (Row row : intfs.values()) {
1222 Interface intf = (Interface)row;
1223 NeutronNetwork network = tenantNetworkManager.getTenantNetworkForInterface(intf);
1224 logger.debug("Trigger Interface update for {}", intf);
1225 if (network != null) {
1226 this.handleInterfaceUpdate(network, node, intf);
1230 } catch (Exception e) {
1231 logger.error("Error Triggering the lost interface updates for "+ node, e);
1232 return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
1234 return new Status(StatusCode.SUCCESS);
1237 public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
1238 // TODO Auto-generated method stub
1243 public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, Interface intf,
1244 boolean isLastInstanceOnNode) {
1245 Status status = new Status(StatusCode.SUCCESS);
1246 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
1247 List<Node> nodes = connectionService.getNodes();
1248 nodes.remove(srcNode);
1250 logger.info("Delete intf " + intf.getName() + " isLastInstanceOnNode " + isLastInstanceOnNode);
1251 List<String> phyIfName = adminConfigManager.getAllPhysicalInterfaceNames(srcNode);
1252 if (intf.getTypeColumn().getData().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)
1253 || intf.getTypeColumn().getData().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
1254 /* Delete tunnel port */
1256 Map<String, String> options = intf.getOptionsColumn().getData();
1257 InetAddress src = InetAddress.getByName(options.get("local_ip"));
1258 InetAddress dst = InetAddress.getByName(options.get("remote_ip"));
1259 status = deleteTunnelPort(srcNode, intf.getTypeColumn().getData(), src, dst);
1260 } catch (Exception e) {
1261 logger.error(e.getMessage(), e);
1263 } else if (phyIfName.contains(intf.getName())) {
1264 deletePhysicalPort(srcNode, intf.getName());
1266 /* delete all other interfaces */
1267 this.removeLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(),
1270 if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1271 this.removeVlanRules(network, srcNode,
1272 intf, isLastInstanceOnNode);
1273 } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1274 || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
1276 for (Node dstNode : nodes) {
1277 InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
1278 InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
1279 logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode" + srcNode.getNodeIDString());
1280 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1281 dst, srcNode, intf, true, isLastInstanceOnNode);
1282 logger.info("Remove tunnel rules for interface " + intf.getName() + " on dstNode" + dstNode.getNodeIDString());
1283 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1284 src, dstNode, intf, false, isLastInstanceOnNode);
1292 public void initializeFlowRules(Node node) {
1293 this.initializeFlowRules(node, adminConfigManager.getIntegrationBridgeName());
1294 this.initializeFlowRules(node, adminConfigManager.getExternalBridgeName());
1295 this.triggerInterfaceUpdates(node);
1302 private void initializeFlowRules(Node node, String bridgeName) {
1303 String bridgeUuid = this.getInternalBridgeUUID(node, bridgeName);
1304 if (bridgeUuid == null) {
1308 Long dpid = getDpid(node, bridgeUuid);
1311 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1318 * Match: LLDP (0x88CCL)
1319 * Action: Packet_In to Controller Reserved Port
1322 writeLLDPRule(dpid);
1323 if (bridgeName == adminConfigManager.getExternalBridgeName()) {
1324 writeNormalRule(dpid);
1329 * Create an LLDP Flow Rule to encapsulate into
1330 * a packet_in that is sent to the controller
1331 * for topology handling.
1332 * Match: Ethertype 0x88CCL
1333 * Action: Punt to Controller in a Packet_In msg
1336 private void writeLLDPRule(Long dpidLong) {
1338 String nodeName = "openflow:" + dpidLong;
1339 EtherType etherType = new EtherType(0x88CCL);
1341 MatchBuilder matchBuilder = new MatchBuilder();
1342 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1343 FlowBuilder flowBuilder = new FlowBuilder();
1345 // Create Match(es) and Set them in the FlowBuilder Object
1346 flowBuilder.setMatch(createEtherTypeMatch(matchBuilder, etherType).build());
1348 // Create the OF Actions and Instructions
1349 InstructionBuilder ib = new InstructionBuilder();
1350 InstructionsBuilder isb = new InstructionsBuilder();
1352 // Instructions List Stores Individual Instructions
1353 List<Instruction> instructions = new ArrayList<Instruction>();
1355 // Call the InstructionBuilder Methods Containing Actions
1356 createSendToControllerInstructions(ib);
1358 ib.setKey(new InstructionKey(0));
1359 instructions.add(ib.build());
1361 // Add InstructionBuilder to the Instruction(s)Builder List
1362 isb.setInstruction(instructions);
1364 // Add InstructionsBuilder to FlowBuilder
1365 flowBuilder.setInstructions(isb.build());
1367 String flowId = "LLDP";
1368 flowBuilder.setId(new FlowId(flowId));
1369 FlowKey key = new FlowKey(new FlowId(flowId));
1370 flowBuilder.setBarrier(true);
1371 flowBuilder.setTableId((short) 0);
1372 flowBuilder.setKey(key);
1373 flowBuilder.setFlowName(flowId);
1374 flowBuilder.setHardTimeout(0);
1375 flowBuilder.setIdleTimeout(0);
1376 writeFlow(flowBuilder, nodeBuilder);
1380 * Create a NORMAL Table Miss Flow Rule
1382 * Action: forward to NORMAL pipeline
1385 private void writeNormalRule(Long dpidLong) {
1387 String nodeName = "openflow:" + dpidLong;
1389 MatchBuilder matchBuilder = new MatchBuilder();
1390 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1391 FlowBuilder flowBuilder = new FlowBuilder();
1393 // Create the OF Actions and Instructions
1394 InstructionBuilder ib = new InstructionBuilder();
1395 InstructionsBuilder isb = new InstructionsBuilder();
1397 // Instructions List Stores Individual Instructions
1398 List<Instruction> instructions = new ArrayList<Instruction>();
1400 // Call the InstructionBuilder Methods Containing Actions
1401 createNormalInstructions(ib);
1403 ib.setKey(new InstructionKey(0));
1404 instructions.add(ib.build());
1406 // Add InstructionBuilder to the Instruction(s)Builder List
1407 isb.setInstruction(instructions);
1409 // Add InstructionsBuilder to FlowBuilder
1410 flowBuilder.setInstructions(isb.build());
1412 String flowId = "NORMAL";
1413 flowBuilder.setId(new FlowId(flowId));
1414 FlowKey key = new FlowKey(new FlowId(flowId));
1415 flowBuilder.setMatch(matchBuilder.build());
1416 flowBuilder.setPriority(0);
1417 flowBuilder.setBarrier(true);
1418 flowBuilder.setTableId((short) 0);
1419 flowBuilder.setKey(key);
1420 flowBuilder.setFlowName(flowId);
1421 flowBuilder.setHardTimeout(0);
1422 flowBuilder.setIdleTimeout(0);
1423 writeFlow(flowBuilder, nodeBuilder);
1427 * (Table:0) Ingress Tunnel Traffic
1428 * Match: OpenFlow InPort and Tunnel ID
1429 * Action: GOTO Local Table (10)
1430 * table=0,tun_id=0x5,in_port=10, actions=goto_table:2
1433 private void handleTunnelIn(Long dpidLong, Short writeTable,
1434 Short goToTableId, String segmentationId,
1435 Long ofPort, boolean write) {
1437 String nodeName = "openflow:" + dpidLong;
1439 BigInteger tunnelId = new BigInteger(segmentationId);
1440 MatchBuilder matchBuilder = new MatchBuilder();
1441 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1442 FlowBuilder flowBuilder = new FlowBuilder();
1444 // Create Match(es) and Set them in the FlowBuilder Object
1445 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, tunnelId).build());
1446 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ofPort).build());
1449 // Create the OF Actions and Instructions
1450 InstructionBuilder ib = new InstructionBuilder();
1451 InstructionsBuilder isb = new InstructionsBuilder();
1453 // Instructions List Stores Individual Instructions
1454 List<Instruction> instructions = new ArrayList<Instruction>();
1456 // Call the InstructionBuilder Methods Containing Actions
1457 createGotoTableInstructions(ib, goToTableId);
1459 ib.setKey(new InstructionKey(0));
1460 instructions.add(ib.build());
1462 // Add InstructionBuilder to the Instruction(s)Builder List
1463 isb.setInstruction(instructions);
1465 // Add InstructionsBuilder to FlowBuilder
1466 flowBuilder.setInstructions(isb.build());
1469 String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
1470 // Add Flow Attributes
1471 flowBuilder.setId(new FlowId(flowId));
1472 FlowKey key = new FlowKey(new FlowId(flowId));
1473 flowBuilder.setStrict(true);
1474 flowBuilder.setBarrier(false);
1475 flowBuilder.setTableId(writeTable);
1476 flowBuilder.setKey(key);
1477 flowBuilder.setFlowName(flowId);
1478 flowBuilder.setHardTimeout(0);
1479 flowBuilder.setIdleTimeout(0);
1482 writeFlow(flowBuilder, nodeBuilder);
1484 removeFlow(flowBuilder, nodeBuilder);
1489 * (Table:0) Ingress VLAN Traffic
1490 * Match: OpenFlow InPort and vlan ID
1491 * Action: GOTO Local Table (20)
1492 * table=0,vlan_id=0x5,in_port=10, actions=goto_table:2
1495 private void handleVlanIn(Long dpidLong, Short writeTable, Short goToTableId,
1496 String segmentationId, Long ethPort, boolean write) {
1498 String nodeName = "openflow:" + dpidLong;
1500 MatchBuilder matchBuilder = new MatchBuilder();
1501 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1502 FlowBuilder flowBuilder = new FlowBuilder();
1504 // Create Match(es) and Set them in the FlowBuilder Object
1505 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1506 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ethPort).build());
1509 // Create the OF Actions and Instructions
1510 InstructionBuilder ib = new InstructionBuilder();
1511 InstructionsBuilder isb = new InstructionsBuilder();
1513 // Instructions List Stores Individual Instructions
1514 List<Instruction> instructions = new ArrayList<Instruction>();
1516 // Call the InstructionBuilder Methods Containing Actions
1517 createGotoTableInstructions(ib, goToTableId);
1519 ib.setKey(new InstructionKey(0));
1520 instructions.add(ib.build());
1522 // Add InstructionBuilder to the Instruction(s)Builder List
1523 isb.setInstruction(instructions);
1525 // Add InstructionsBuilder to FlowBuilder
1526 flowBuilder.setInstructions(isb.build());
1529 String flowId = "VlanIn_"+segmentationId+"_"+ethPort;
1530 // Add Flow Attributes
1531 flowBuilder.setId(new FlowId(flowId));
1532 FlowKey key = new FlowKey(new FlowId(flowId));
1533 flowBuilder.setStrict(true);
1534 flowBuilder.setBarrier(false);
1535 flowBuilder.setTableId(writeTable);
1536 flowBuilder.setKey(key);
1537 flowBuilder.setFlowName(flowId);
1538 flowBuilder.setHardTimeout(0);
1539 flowBuilder.setIdleTimeout(0);
1541 writeFlow(flowBuilder, nodeBuilder);
1543 removeFlow(flowBuilder, nodeBuilder);
1548 * (Table:0) Egress VM Traffic Towards TEP
1549 * Match: Destination Ethernet Addr and OpenFlow InPort
1550 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1551 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1552 * actions=set_field:5->tun_id,goto_table=1"
1555 private void handleLocalInPort(Long dpidLong, Short writeTable, Short goToTableId,
1556 String segmentationId, Long inPort, String attachedMac,
1559 String nodeName = "openflow:" + dpidLong;
1561 MatchBuilder matchBuilder = new MatchBuilder();
1562 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1563 FlowBuilder flowBuilder = new FlowBuilder();
1565 // Create the OF Match using MatchBuilder
1566 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1567 // TODO Broken In_Port Match
1568 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1570 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1571 // Add Flow Attributes
1572 flowBuilder.setId(new FlowId(flowId));
1573 FlowKey key = new FlowKey(new FlowId(flowId));
1574 flowBuilder.setStrict(true);
1575 flowBuilder.setBarrier(false);
1576 flowBuilder.setTableId(writeTable);
1577 flowBuilder.setKey(key);
1578 flowBuilder.setFlowName(flowId);
1579 flowBuilder.setHardTimeout(0);
1580 flowBuilder.setIdleTimeout(0);
1583 // Instantiate the Builders for the OF Actions and Instructions
1584 InstructionBuilder ib = new InstructionBuilder();
1585 InstructionsBuilder isb = new InstructionsBuilder();
1587 // Instructions List Stores Individual Instructions
1588 List<Instruction> instructions = new ArrayList<Instruction>();
1590 // GOTO Instuctions Need to be added first to the List
1591 createGotoTableInstructions(ib, goToTableId);
1593 ib.setKey(new InstructionKey(0));
1594 instructions.add(ib.build());
1595 // TODO Broken SetTunID
1596 createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
1598 ib.setKey(new InstructionKey(1));
1599 instructions.add(ib.build());
1601 // Add InstructionBuilder to the Instruction(s)Builder List
1602 isb.setInstruction(instructions);
1604 // Add InstructionsBuilder to FlowBuilder
1605 flowBuilder.setInstructions(isb.build());
1607 writeFlow(flowBuilder, nodeBuilder);
1609 removeFlow(flowBuilder, nodeBuilder);
1614 * (Table:0) Egress VM Traffic Towards TEP
1615 * Match: Source Ethernet Addr and OpenFlow InPort
1616 * Instruction: Set VLANID and GOTO Table Egress (n)
1617 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1618 * actions=push_vlan, set_field:5->vlan_id,goto_table=1"
1621 private void handleLocalInPortSetVlan(Long dpidLong, Short writeTable,
1622 Short goToTableId, String segmentationId,
1623 Long inPort, String attachedMac,
1626 String nodeName = "openflow:" + dpidLong;
1628 MatchBuilder matchBuilder = new MatchBuilder();
1629 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1630 FlowBuilder flowBuilder = new FlowBuilder();
1632 // Create the OF Match using MatchBuilder
1633 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1634 // TODO Broken In_Port Match
1635 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1637 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1638 // Add Flow Attributes
1639 flowBuilder.setId(new FlowId(flowId));
1640 FlowKey key = new FlowKey(new FlowId(flowId));
1641 flowBuilder.setStrict(true);
1642 flowBuilder.setBarrier(false);
1643 flowBuilder.setTableId(writeTable);
1644 flowBuilder.setKey(key);
1645 flowBuilder.setFlowName(flowId);
1646 flowBuilder.setHardTimeout(0);
1647 flowBuilder.setIdleTimeout(0);
1650 // Instantiate the Builders for the OF Actions and Instructions
1651 InstructionBuilder ib = new InstructionBuilder();
1652 InstructionsBuilder isb = new InstructionsBuilder();
1654 // Instructions List Stores Individual Instructions
1655 List<Instruction> instructions = new ArrayList<Instruction>();
1657 // GOTO Instructions Need to be added first to the List
1658 createGotoTableInstructions(ib, goToTableId);
1660 ib.setKey(new InstructionKey(0));
1661 instructions.add(ib.build());
1662 // Set VLAN ID Instruction
1663 createSetVlanInstructions(ib, new VlanId(Integer.valueOf(segmentationId)));
1665 ib.setKey(new InstructionKey(1));
1666 instructions.add(ib.build());
1668 // Add InstructionBuilder to the Instruction(s)Builder List
1669 isb.setInstruction(instructions);
1671 // Add InstructionsBuilder to FlowBuilder
1672 flowBuilder.setInstructions(isb.build());
1674 writeFlow(flowBuilder, nodeBuilder);
1676 removeFlow(flowBuilder, nodeBuilder);
1681 * (Table:0) Drop frames source from a VM that do not
1682 * match the associated MAC address of the local VM.
1683 * Match: Low priority anything not matching the VM SMAC
1685 * table=0,priority=16384,in_port=1 actions=drop"
1688 private void handleDropSrcIface(Long dpidLong, Long inPort, boolean write) {
1690 String nodeName = "openflow:" + dpidLong;
1692 MatchBuilder matchBuilder = new MatchBuilder();
1693 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1694 FlowBuilder flowBuilder = new FlowBuilder();
1696 // Create the OF Match using MatchBuilder
1697 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1700 // Instantiate the Builders for the OF Actions and Instructions
1701 InstructionBuilder ib = new InstructionBuilder();
1702 InstructionsBuilder isb = new InstructionsBuilder();
1704 // Instructions List Stores Individual Instructions
1705 List<Instruction> instructions = new ArrayList<Instruction>();
1707 // Call the InstructionBuilder Methods Containing Actions
1708 createDropInstructions(ib);
1710 ib.setKey(new InstructionKey(0));
1711 instructions.add(ib.build());
1713 // Add InstructionBuilder to the Instruction(s)Builder List
1714 isb.setInstruction(instructions);
1716 // Add InstructionsBuilder to FlowBuilder
1717 flowBuilder.setInstructions(isb.build());
1720 String flowId = "DropFilter_"+inPort;
1721 // Add Flow Attributes
1722 flowBuilder.setId(new FlowId(flowId));
1723 FlowKey key = new FlowKey(new FlowId(flowId));
1724 flowBuilder.setStrict(true);
1725 flowBuilder.setBarrier(false);
1726 flowBuilder.setTableId((short) 0);
1727 flowBuilder.setKey(key);
1728 flowBuilder.setFlowName(flowId);
1729 flowBuilder.setPriority(8192);
1730 flowBuilder.setHardTimeout(0);
1731 flowBuilder.setIdleTimeout(0);
1733 writeFlow(flowBuilder, nodeBuilder);
1735 removeFlow(flowBuilder, nodeBuilder);
1740 * (Table:1) Egress Tunnel Traffic
1741 * Match: Destination Ethernet Addr and Local InPort
1742 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1743 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
1744 * actions=output:10,goto_table:2"
1746 private void handleTunnelOut(Long dpidLong, Short writeTable,
1747 Short goToTableId, String segmentationId,
1748 Long OFPortOut, String attachedMac,
1751 String nodeName = "openflow:" + dpidLong;
1753 MatchBuilder matchBuilder = new MatchBuilder();
1754 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1755 FlowBuilder flowBuilder = new FlowBuilder();
1757 // Create the OF Match using MatchBuilder
1758 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1759 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1761 String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
1762 // Add Flow Attributes
1763 flowBuilder.setId(new FlowId(flowId));
1764 FlowKey key = new FlowKey(new FlowId(flowId));
1765 flowBuilder.setStrict(true);
1766 flowBuilder.setBarrier(false);
1767 flowBuilder.setTableId(writeTable);
1768 flowBuilder.setKey(key);
1769 flowBuilder.setFlowName(flowId);
1770 flowBuilder.setHardTimeout(0);
1771 flowBuilder.setIdleTimeout(0);
1774 // Instantiate the Builders for the OF Actions and Instructions
1775 InstructionBuilder ib = new InstructionBuilder();
1776 InstructionsBuilder isb = new InstructionsBuilder();
1778 // Instructions List Stores Individual Instructions
1779 List<Instruction> instructions = new ArrayList<Instruction>();
1782 createGotoTableInstructions(ib, goToTableId);
1784 ib.setKey(new InstructionKey(0));
1785 instructions.add(ib.build());
1786 // Set the Output Port/Iface
1787 createOutputPortInstructions(ib, dpidLong, OFPortOut);
1789 ib.setKey(new InstructionKey(1));
1790 instructions.add(ib.build());
1792 // Add InstructionBuilder to the Instruction(s)Builder List
1793 isb.setInstruction(instructions);
1795 // Add InstructionsBuilder to FlowBuilder
1796 flowBuilder.setInstructions(isb.build());
1798 writeFlow(flowBuilder, nodeBuilder);
1800 removeFlow(flowBuilder, nodeBuilder);
1805 * (Table:1) Egress VLAN Traffic
1806 * Match: Destination Ethernet Addr and VLAN id
1807 * Instruction: GOTO Table Table 2
1808 * table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
1809 * actions= goto_table:2"
1812 private void handleVlanOut(Long dpidLong, Short writeTable,
1813 Short goToTableId, String segmentationId,
1814 Long ethPort, String attachedMac, boolean write) {
1816 String nodeName = "openflow:" + dpidLong;
1818 MatchBuilder matchBuilder = new MatchBuilder();
1819 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1820 FlowBuilder flowBuilder = new FlowBuilder();
1822 // Create the OF Match using MatchBuilder
1823 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1824 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1826 String flowId = "VlanOut_"+segmentationId+"_"+ethPort+"_"+attachedMac;
1827 // Add Flow Attributes
1828 flowBuilder.setId(new FlowId(flowId));
1829 FlowKey key = new FlowKey(new FlowId(flowId));
1830 flowBuilder.setStrict(true);
1831 flowBuilder.setBarrier(false);
1832 flowBuilder.setTableId(writeTable);
1833 flowBuilder.setKey(key);
1834 flowBuilder.setFlowName(flowId);
1835 flowBuilder.setHardTimeout(0);
1836 flowBuilder.setIdleTimeout(0);
1839 // Instantiate the Builders for the OF Actions and Instructions
1840 InstructionBuilder ib = new InstructionBuilder();
1841 InstructionsBuilder isb = new InstructionsBuilder();
1843 // Instructions List Stores Individual Instructions
1844 List<Instruction> instructions = new ArrayList<Instruction>();
1847 createGotoTableInstructions(ib, goToTableId);
1849 ib.setKey(new InstructionKey(0));
1850 instructions.add(ib.build());
1852 // Add InstructionBuilder to the Instruction(s)Builder List
1853 isb.setInstruction(instructions);
1855 // Add InstructionsBuilder to FlowBuilder
1856 flowBuilder.setInstructions(isb.build());
1858 writeFlow(flowBuilder, nodeBuilder);
1860 removeFlow(flowBuilder, nodeBuilder);
1865 * (Table:1) Egress Tunnel Traffic
1866 * Match: Destination Ethernet Addr and Local InPort
1867 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1868 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1869 * actions=output:10,output:11,goto_table:2
1872 private void handleTunnelFloodOut(Long dpidLong, Short writeTable,
1873 Short localTable, String segmentationId,
1874 Long OFPortOut, boolean write) {
1876 String nodeName = "openflow:" + dpidLong;
1878 MatchBuilder matchBuilder = new MatchBuilder();
1879 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1880 FlowBuilder flowBuilder = new FlowBuilder();
1882 // Create the OF Match using MatchBuilder
1884 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1887 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1889 String flowId = "TunnelFloodOut_"+segmentationId;
1890 // Add Flow Attributes
1891 flowBuilder.setId(new FlowId(flowId));
1892 FlowKey key = new FlowKey(new FlowId(flowId));
1893 flowBuilder.setBarrier(true);
1894 flowBuilder.setTableId(writeTable);
1895 flowBuilder.setKey(key);
1896 flowBuilder.setPriority(16384);
1897 flowBuilder.setFlowName(flowId);
1898 flowBuilder.setHardTimeout(0);
1899 flowBuilder.setIdleTimeout(0);
1901 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1902 // Instantiate the Builders for the OF Actions and Instructions
1903 InstructionBuilder ib = new InstructionBuilder();
1904 InstructionsBuilder isb = new InstructionsBuilder();
1905 List<Instruction> instructions = new ArrayList<Instruction>();
1906 List<Instruction> existingInstructions = null;
1908 Instructions ins = flow.getInstructions();
1910 existingInstructions = ins.getInstruction();
1916 createGotoTableInstructions(ib, localTable);
1918 ib.setKey(new InstructionKey(0));
1919 instructions.add(ib.build());
1920 // Set the Output Port/Iface
1921 //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, OFPortOut, existingInstructions);
1922 createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
1924 ib.setKey(new InstructionKey(1));
1925 instructions.add(ib.build());
1927 // Add InstructionBuilder to the Instruction(s)Builder List
1928 isb.setInstruction(instructions);
1930 // Add InstructionsBuilder to FlowBuilder
1931 flowBuilder.setInstructions(isb.build());
1933 writeFlow(flowBuilder, nodeBuilder);
1935 /* remove port from action list */
1936 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
1937 OFPortOut, existingInstructions);
1939 /* if all port are removed, remove the flow too. */
1940 removeFlow(flowBuilder, nodeBuilder);
1942 /* Install instruction with new output port list*/
1944 ib.setKey(new InstructionKey(0));
1945 instructions.add(ib.build());
1947 // Add InstructionBuilder to the Instruction(s)Builder List
1948 isb.setInstruction(instructions);
1950 // Add InstructionsBuilder to FlowBuilder
1951 flowBuilder.setInstructions(isb.build());
1957 * (Table:1) Egress VLAN Traffic
1958 * Match: Destination Ethernet Addr and VLAN id
1959 * Instruction: GOTO table 2 and Output port eth interface
1960 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1961 * actions=output:eth1,goto_table:2
1964 private void handleVlanFloodOut(Long dpidLong, Short writeTable,
1965 Short localTable, String segmentationId,
1966 Long ethPort, boolean write) {
1968 String nodeName = "openflow:" + dpidLong;
1970 MatchBuilder matchBuilder = new MatchBuilder();
1971 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1972 FlowBuilder flowBuilder = new FlowBuilder();
1974 // Create the OF Match using MatchBuilder
1976 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1978 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1980 String flowId = "VlanFloodOut_"+segmentationId;
1981 // Add Flow Attributes
1982 flowBuilder.setId(new FlowId(flowId));
1983 FlowKey key = new FlowKey(new FlowId(flowId));
1984 flowBuilder.setBarrier(true);
1985 flowBuilder.setTableId(writeTable);
1986 flowBuilder.setKey(key);
1987 flowBuilder.setPriority(16384);
1988 flowBuilder.setFlowName(flowId);
1989 flowBuilder.setHardTimeout(0);
1990 flowBuilder.setIdleTimeout(0);
1992 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1993 // Instantiate the Builders for the OF Actions and Instructions
1994 InstructionBuilder ib = new InstructionBuilder();
1995 InstructionsBuilder isb = new InstructionsBuilder();
1996 List<Instruction> instructions = new ArrayList<Instruction>();
2000 createGotoTableInstructions(ib, localTable);
2002 ib.setKey(new InstructionKey(0));
2003 instructions.add(ib.build());
2004 // Set the Output Port/Iface
2005 createOutputPortInstructions(ib, dpidLong, ethPort);
2007 ib.setKey(new InstructionKey(1));
2008 instructions.add(ib.build());
2010 // Add InstructionBuilder to the Instruction(s)Builder List
2011 isb.setInstruction(instructions);
2013 // Add InstructionsBuilder to FlowBuilder
2014 flowBuilder.setInstructions(isb.build());
2016 writeFlow(flowBuilder, nodeBuilder);
2018 removeFlow(flowBuilder, nodeBuilder);
2023 * (Table:1) Table Drain w/ Catch All
2025 * Action: GOTO Local Table (10)
2026 * table=2,priority=8192,tun_id=0x5 actions=drop
2029 private void handleTunnelMiss(Long dpidLong, Short writeTable,
2030 Short goToTableId, String segmentationId,
2033 String nodeName = "openflow:" + dpidLong;
2035 MatchBuilder matchBuilder = new MatchBuilder();
2036 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2037 FlowBuilder flowBuilder = new FlowBuilder();
2039 // Create Match(es) and Set them in the FlowBuilder Object
2040 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2043 // Create the OF Actions and Instructions
2044 InstructionBuilder ib = new InstructionBuilder();
2045 InstructionsBuilder isb = new InstructionsBuilder();
2047 // Instructions List Stores Individual Instructions
2048 List<Instruction> instructions = new ArrayList<Instruction>();
2050 // Call the InstructionBuilder Methods Containing Actions
2051 createGotoTableInstructions(ib, goToTableId);
2053 ib.setKey(new InstructionKey(0));
2054 instructions.add(ib.build());
2056 // Add InstructionBuilder to the Instruction(s)Builder List
2057 isb.setInstruction(instructions);
2059 // Add InstructionsBuilder to FlowBuilder
2060 flowBuilder.setInstructions(isb.build());
2063 String flowId = "TunnelMiss_"+segmentationId;
2064 // Add Flow Attributes
2065 flowBuilder.setId(new FlowId(flowId));
2066 FlowKey key = new FlowKey(new FlowId(flowId));
2067 flowBuilder.setStrict(true);
2068 flowBuilder.setBarrier(false);
2069 flowBuilder.setTableId(writeTable);
2070 flowBuilder.setKey(key);
2071 flowBuilder.setPriority(8192);
2072 flowBuilder.setFlowName(flowId);
2073 flowBuilder.setHardTimeout(0);
2074 flowBuilder.setIdleTimeout(0);
2076 writeFlow(flowBuilder, nodeBuilder);
2078 removeFlow(flowBuilder, nodeBuilder);
2084 * (Table:1) Table Drain w/ Catch All
2086 * Action: Output port eth interface
2087 * table=1,priority=8192,vlan_id=0x5 actions= output port:eth1
2090 private void handleVlanMiss(Long dpidLong, Short writeTable,
2091 Short goToTableId, String segmentationId,
2092 Long ethPort, boolean write) {
2094 String nodeName = "openflow:" + dpidLong;
2096 MatchBuilder matchBuilder = new MatchBuilder();
2097 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2098 FlowBuilder flowBuilder = new FlowBuilder();
2100 // Create Match(es) and Set them in the FlowBuilder Object
2101 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2104 // Create the OF Actions and Instructions
2105 InstructionBuilder ib = new InstructionBuilder();
2106 InstructionsBuilder isb = new InstructionsBuilder();
2108 // Instructions List Stores Individual Instructions
2109 List<Instruction> instructions = new ArrayList<Instruction>();
2111 // Call the InstructionBuilder Methods Containing Actions
2112 //createGotoTableInstructions(ib, goToTableId);
2114 //ib.setKey(new InstructionKey(0));
2115 //instructions.add(ib.build());
2116 // Set the Output Port/Iface
2117 createOutputPortInstructions(ib, dpidLong, ethPort);
2119 ib.setKey(new InstructionKey(1));
2120 instructions.add(ib.build());
2122 // Add InstructionBuilder to the Instruction(s)Builder List
2123 isb.setInstruction(instructions);
2125 // Add InstructionsBuilder to FlowBuilder
2126 flowBuilder.setInstructions(isb.build());
2129 String flowId = "VlanMiss_"+segmentationId;
2130 // Add Flow Attributes
2131 flowBuilder.setId(new FlowId(flowId));
2132 FlowKey key = new FlowKey(new FlowId(flowId));
2133 flowBuilder.setStrict(true);
2134 flowBuilder.setBarrier(false);
2135 flowBuilder.setTableId(writeTable);
2136 flowBuilder.setKey(key);
2137 flowBuilder.setPriority(8192);
2138 flowBuilder.setFlowName(flowId);
2139 flowBuilder.setHardTimeout(0);
2140 flowBuilder.setIdleTimeout(0);
2142 writeFlow(flowBuilder, nodeBuilder);
2144 removeFlow(flowBuilder, nodeBuilder);
2149 * (Table:1) Local Broadcast Flood
2150 * Match: Tunnel ID and dMAC
2151 * Action: Output Port
2152 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2155 private void handleLocalUcastOut(Long dpidLong, Short writeTable,
2156 String segmentationId, Long localPort,
2157 String attachedMac, boolean write) {
2159 String nodeName = "openflow:" + dpidLong;
2161 MatchBuilder matchBuilder = new MatchBuilder();
2162 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2163 FlowBuilder flowBuilder = new FlowBuilder();
2165 // Create the OF Match using MatchBuilder
2166 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2167 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2169 String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2170 // Add Flow Attributes
2171 flowBuilder.setId(new FlowId(flowId));
2172 FlowKey key = new FlowKey(new FlowId(flowId));
2173 flowBuilder.setStrict(true);
2174 flowBuilder.setBarrier(false);
2175 flowBuilder.setTableId(writeTable);
2176 flowBuilder.setKey(key);
2177 flowBuilder.setFlowName(flowId);
2178 flowBuilder.setHardTimeout(0);
2179 flowBuilder.setIdleTimeout(0);
2182 // Instantiate the Builders for the OF Actions and Instructions
2183 InstructionBuilder ib = new InstructionBuilder();
2184 InstructionsBuilder isb = new InstructionsBuilder();
2186 // Instructions List Stores Individual Instructions
2187 List<Instruction> instructions = new ArrayList<Instruction>();
2189 // Set the Output Port/Iface
2190 createOutputPortInstructions(ib, dpidLong, localPort);
2192 ib.setKey(new InstructionKey(0));
2193 instructions.add(ib.build());
2195 // Add InstructionBuilder to the Instruction(s)Builder List
2196 isb.setInstruction(instructions);
2198 // Add InstructionsBuilder to FlowBuilder
2199 flowBuilder.setInstructions(isb.build());
2200 writeFlow(flowBuilder, nodeBuilder);
2202 removeFlow(flowBuilder, nodeBuilder);
2207 * (Table:2) Local VLAN unicast
2208 * Match: VLAN ID and dMAC
2209 * Action: Output Port
2210 * table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2213 private void handleLocalVlanUcastOut(Long dpidLong, Short writeTable,
2214 String segmentationId, Long localPort,
2215 String attachedMac, boolean write) {
2217 String nodeName = "openflow:" + dpidLong;
2219 MatchBuilder matchBuilder = new MatchBuilder();
2220 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2221 FlowBuilder flowBuilder = new FlowBuilder();
2223 // Create the OF Match using MatchBuilder
2224 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2225 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2227 String flowId = "VlanUcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2228 // Add Flow Attributes
2229 flowBuilder.setId(new FlowId(flowId));
2230 FlowKey key = new FlowKey(new FlowId(flowId));
2231 flowBuilder.setStrict(true);
2232 flowBuilder.setBarrier(false);
2233 flowBuilder.setTableId(writeTable);
2234 flowBuilder.setKey(key);
2235 flowBuilder.setFlowName(flowId);
2236 flowBuilder.setHardTimeout(0);
2237 flowBuilder.setIdleTimeout(0);
2240 // Instantiate the Builders for the OF Actions and Instructions
2241 InstructionBuilder ib = new InstructionBuilder();
2242 InstructionsBuilder isb = new InstructionsBuilder();
2244 // Instructions List Stores Individual Instructions
2245 List<Instruction> instructions = new ArrayList<Instruction>();
2246 List<Instruction> instructions_tmp = new ArrayList<Instruction>();
2248 /* Strip vlan and store to tmp instruction space*/
2249 createPopVlanInstructions(ib);
2251 ib.setKey(new InstructionKey(0));
2252 instructions_tmp.add(ib.build());
2254 // Set the Output Port/Iface
2255 ib = new InstructionBuilder();
2256 addOutputPortInstructions(ib, dpidLong, localPort, instructions_tmp);
2258 ib.setKey(new InstructionKey(0));
2259 instructions.add(ib.build());
2261 // Add InstructionBuilder to the Instruction(s)Builder List
2262 isb.setInstruction(instructions);
2264 // Add InstructionsBuilder to FlowBuilder
2265 flowBuilder.setInstructions(isb.build());
2266 writeFlow(flowBuilder, nodeBuilder);
2268 removeFlow(flowBuilder, nodeBuilder);
2273 * (Table:2) Local Broadcast Flood
2274 * Match: Tunnel ID and dMAC (::::FF:FF)
2275 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2276 * actions=output:2,3,4,5
2279 private void handleLocalBcastOut(Long dpidLong, Short writeTable,
2280 String segmentationId, Long localPort,
2283 String nodeName = "openflow:" + dpidLong;
2285 MatchBuilder matchBuilder = new MatchBuilder();
2286 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2287 FlowBuilder flowBuilder = new FlowBuilder();
2289 // Create the OF Match using MatchBuilder
2290 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2291 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
2293 String flowId = "BcastOut_"+segmentationId;
2294 // Add Flow Attributes
2295 flowBuilder.setId(new FlowId(flowId));
2296 FlowKey key = new FlowKey(new FlowId(flowId));
2297 flowBuilder.setStrict(true);
2298 flowBuilder.setBarrier(false);
2299 flowBuilder.setTableId(writeTable);
2300 flowBuilder.setKey(key);
2301 flowBuilder.setPriority(16384);
2302 flowBuilder.setFlowName(flowId);
2303 flowBuilder.setHardTimeout(0);
2304 flowBuilder.setIdleTimeout(0);
2305 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2306 // Instantiate the Builders for the OF Actions and Instructions
2307 InstructionBuilder ib = new InstructionBuilder();
2308 InstructionsBuilder isb = new InstructionsBuilder();
2309 List<Instruction> instructions = new ArrayList<Instruction>();
2310 List<Instruction> existingInstructions = null;
2312 Instructions ins = flow.getInstructions();
2314 existingInstructions = ins.getInstruction();
2319 // Create output port list
2320 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
2322 ib.setKey(new InstructionKey(0));
2323 instructions.add(ib.build());
2325 // Add InstructionBuilder to the Instruction(s)Builder List
2326 isb.setInstruction(instructions);
2328 // Add InstructionsBuilder to FlowBuilder
2329 flowBuilder.setInstructions(isb.build());
2331 writeFlow(flowBuilder, nodeBuilder);
2333 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong, localPort,
2334 existingInstructions);
2336 /* if all ports are removed, remove flow */
2337 removeFlow(flowBuilder, nodeBuilder);
2339 /* Install instruction with new output port list*/
2341 ib.setKey(new InstructionKey(0));
2342 instructions.add(ib.build());
2344 // Add InstructionBuilder to the Instruction(s)Builder List
2345 isb.setInstruction(instructions);
2347 // Add InstructionsBuilder to FlowBuilder
2348 flowBuilder.setInstructions(isb.build());
2350 writeFlow(flowBuilder, nodeBuilder);
2356 * (Table:2) Local VLAN Broadcast Flood
2357 * Match: vlan ID and dMAC (::::FF:FF)
2358 * table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2359 * actions=strip_vlan, output:2,3,4,5
2362 private void handleLocalVlanBcastOut(Long dpidLong, Short writeTable,
2363 String segmentationId, Long localPort,
2366 String nodeName = "openflow:" + dpidLong;
2368 MatchBuilder matchBuilder = new MatchBuilder();
2369 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2370 FlowBuilder flowBuilder = new FlowBuilder();
2372 // Create the OF Match using MatchBuilder
2373 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2374 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
2376 String flowId = "VlanBcastOut_"+segmentationId;
2377 // Add Flow Attributes
2378 flowBuilder.setId(new FlowId(flowId));
2379 FlowKey key = new FlowKey(new FlowId(flowId));
2380 flowBuilder.setStrict(true);
2381 flowBuilder.setBarrier(false);
2382 flowBuilder.setTableId(writeTable);
2383 flowBuilder.setKey(key);
2384 flowBuilder.setPriority(16384);
2385 flowBuilder.setFlowName(flowId);
2386 flowBuilder.setHardTimeout(0);
2387 flowBuilder.setIdleTimeout(0);
2388 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2389 // Instantiate the Builders for the OF Actions and Instructions
2390 InstructionBuilder ib = new InstructionBuilder();
2391 InstructionsBuilder isb = new InstructionsBuilder();
2392 List<Instruction> instructions = new ArrayList<Instruction>();
2393 List<Instruction> existingInstructions = null;
2394 boolean add_pop_vlan = true;
2396 Instructions ins = flow.getInstructions();
2398 existingInstructions = ins.getInstruction();
2403 if (existingInstructions != null) {
2404 /* Check if pop vlan is already the first action in action list */
2405 List<Action> existingActions = null;
2406 for (Instruction in : existingInstructions) {
2407 if (in.getInstruction() instanceof ApplyActionsCase) {
2408 existingActions = (((ApplyActionsCase)
2409 in.getInstruction()).getApplyActions().getAction());
2410 if (existingActions.get(0).getAction() instanceof PopVlanActionCase) {
2411 add_pop_vlan = false;
2417 existingInstructions = new ArrayList<Instruction>();
2422 createPopVlanInstructions(ib);
2424 ib.setKey(new InstructionKey(0));
2425 existingInstructions.add(ib.build());
2426 ib = new InstructionBuilder();
2430 //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, localPort, existingInstructions);
2431 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
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());
2442 writeFlow(flowBuilder, nodeBuilder);
2444 //boolean flowRemove = removeOutputPortFromGroup(nodeBuilder, ib, dpidLong,
2445 // localPort, existingInstructions);
2446 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
2447 localPort, existingInstructions);
2449 /* if all ports are removed, remove flow */
2450 removeFlow(flowBuilder, nodeBuilder);
2452 /* Install instruction with new output port list*/
2454 ib.setKey(new InstructionKey(0));
2455 instructions.add(ib.build());
2457 // Add InstructionBuilder to the Instruction(s)Builder List
2458 isb.setInstruction(instructions);
2460 // Add InstructionsBuilder to FlowBuilder
2461 flowBuilder.setInstructions(isb.build());
2462 writeFlow(flowBuilder, nodeBuilder);
2468 * (Table:1) Local Table Miss
2469 * Match: Any Remaining Flows w/a TunID
2470 * Action: Drop w/ a low priority
2471 * table=2,priority=8192,tun_id=0x5 actions=drop
2474 private void handleLocalTableMiss(Long dpidLong, Short writeTable,
2475 String segmentationId, boolean write) {
2477 String nodeName = "openflow:" + dpidLong;
2479 MatchBuilder matchBuilder = new MatchBuilder();
2480 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2481 FlowBuilder flowBuilder = new FlowBuilder();
2483 // Create Match(es) and Set them in the FlowBuilder Object
2484 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2487 // Create the OF Actions and Instructions
2488 InstructionBuilder ib = new InstructionBuilder();
2489 InstructionsBuilder isb = new InstructionsBuilder();
2491 // Instructions List Stores Individual Instructions
2492 List<Instruction> instructions = new ArrayList<Instruction>();
2494 // Call the InstructionBuilder Methods Containing Actions
2495 createDropInstructions(ib);
2497 ib.setKey(new InstructionKey(0));
2498 instructions.add(ib.build());
2500 // Add InstructionBuilder to the Instruction(s)Builder List
2501 isb.setInstruction(instructions);
2503 // Add InstructionsBuilder to FlowBuilder
2504 flowBuilder.setInstructions(isb.build());
2507 String flowId = "LocalTableMiss_"+segmentationId;
2508 // Add Flow Attributes
2509 flowBuilder.setId(new FlowId(flowId));
2510 FlowKey key = new FlowKey(new FlowId(flowId));
2511 flowBuilder.setStrict(true);
2512 flowBuilder.setBarrier(false);
2513 flowBuilder.setTableId(writeTable);
2514 flowBuilder.setKey(key);
2515 flowBuilder.setPriority(8192);
2516 flowBuilder.setFlowName(flowId);
2517 flowBuilder.setHardTimeout(0);
2518 flowBuilder.setIdleTimeout(0);
2520 writeFlow(flowBuilder, nodeBuilder);
2522 removeFlow(flowBuilder, nodeBuilder);
2527 * (Table:1) Local Table Miss
2528 * Match: Any Remaining Flows w/a VLAN ID
2529 * Action: Drop w/ a low priority
2530 * table=2,priority=8192,vlan_id=0x5 actions=drop
2533 private void handleLocalVlanTableMiss(Long dpidLong, Short writeTable,
2534 String segmentationId, boolean write) {
2536 String nodeName = "openflow:" + dpidLong;
2538 MatchBuilder matchBuilder = new MatchBuilder();
2539 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2540 FlowBuilder flowBuilder = new FlowBuilder();
2542 // Create Match(es) and Set them in the FlowBuilder Object
2543 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2546 // Create the OF Actions and Instructions
2547 InstructionBuilder ib = new InstructionBuilder();
2548 InstructionsBuilder isb = new InstructionsBuilder();
2550 // Instructions List Stores Individual Instructions
2551 List<Instruction> instructions = new ArrayList<Instruction>();
2553 // Call the InstructionBuilder Methods Containing Actions
2554 createDropInstructions(ib);
2556 ib.setKey(new InstructionKey(0));
2557 instructions.add(ib.build());
2559 // Add InstructionBuilder to the Instruction(s)Builder List
2560 isb.setInstruction(instructions);
2562 // Add InstructionsBuilder to FlowBuilder
2563 flowBuilder.setInstructions(isb.build());
2566 String flowId = "LocalTableMiss_"+segmentationId;
2567 // Add Flow Attributes
2568 flowBuilder.setId(new FlowId(flowId));
2569 FlowKey key = new FlowKey(new FlowId(flowId));
2570 flowBuilder.setStrict(true);
2571 flowBuilder.setBarrier(false);
2572 flowBuilder.setTableId(writeTable);
2573 flowBuilder.setKey(key);
2574 flowBuilder.setPriority(8192);
2575 flowBuilder.setFlowName(flowId);
2576 flowBuilder.setHardTimeout(0);
2577 flowBuilder.setIdleTimeout(0);
2579 writeFlow(flowBuilder, nodeBuilder);
2581 removeFlow(flowBuilder, nodeBuilder);
2585 private Group getGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2586 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2587 if (mdsalConsumer == null) {
2588 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2592 dataBrokerService = mdsalConsumer.getDataBrokerService();
2594 if (dataBrokerService == null) {
2595 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2599 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2600 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2601 new GroupKey(groupBuilder.getGroupId())).build();
2602 return (Group)dataBrokerService.readConfigurationData(path1);
2605 private Group writeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2606 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2607 if (mdsalConsumer == null) {
2608 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2612 dataBrokerService = mdsalConsumer.getDataBrokerService();
2614 if (dataBrokerService == null) {
2615 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2618 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2619 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2620 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2621 new GroupKey(groupBuilder.getGroupId())).build();
2622 modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2623 modification.putConfigurationData(path1, groupBuilder.build());
2624 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2627 RpcResult<TransactionStatus> result = commitFuture.get();
2628 TransactionStatus status = result.getResult();
2629 logger.debug("Transaction Status "+status.toString()+" for Group "+groupBuilder.getGroupName());
2630 } catch (InterruptedException e) {
2631 logger.error(e.getMessage(), e);
2632 } catch (ExecutionException e) {
2633 logger.error(e.getMessage(), e);
2635 return (Group)dataBrokerService.readConfigurationData(path1);
2638 private Group removeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2639 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2640 if (mdsalConsumer == null) {
2641 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2645 dataBrokerService = mdsalConsumer.getDataBrokerService();
2647 if (dataBrokerService == null) {
2648 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2651 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2652 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2653 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2654 new GroupKey(groupBuilder.getGroupId())).build();
2655 modification.removeConfigurationData(path1);
2656 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2659 RpcResult<TransactionStatus> result = commitFuture.get();
2660 TransactionStatus status = result.getResult();
2661 logger.debug("Transaction Status "+status.toString()+" for Group "+groupBuilder.getGroupName());
2662 } catch (InterruptedException e) {
2663 logger.error(e.getMessage(), e);
2664 } catch (ExecutionException e) {
2665 logger.error(e.getMessage(), e);
2667 return (Group)dataBrokerService.readConfigurationData(path1);
2669 private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2670 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2671 if (mdsalConsumer == null) {
2672 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2676 dataBrokerService = mdsalConsumer.getDataBrokerService();
2678 if (dataBrokerService == null) {
2679 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2683 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2684 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2685 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2686 return (Flow)dataBrokerService.readConfigurationData(path1);
2689 private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2690 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2691 if (mdsalConsumer == null) {
2692 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2696 dataBrokerService = mdsalConsumer.getDataBrokerService();
2698 if (dataBrokerService == null) {
2699 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2702 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2703 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2704 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2705 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2706 //modification.putOperationalData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2707 //modification.putOperationalData(path1, flowBuilder.build());
2708 modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2709 modification.putConfigurationData(path1, flowBuilder.build());
2710 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2712 RpcResult<TransactionStatus> result = commitFuture.get();
2713 TransactionStatus status = result.getResult();
2714 logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
2715 } catch (InterruptedException e) {
2716 logger.error(e.getMessage(), e);
2717 } catch (ExecutionException e) {
2718 logger.error(e.getMessage(), e);
2722 private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2723 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2724 if (mdsalConsumer == null) {
2725 logger.error("ERROR finding MDSAL Service.");
2729 dataBrokerService = mdsalConsumer.getDataBrokerService();
2731 if (dataBrokerService == null) {
2732 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2735 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2736 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class)
2737 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2738 .rev130819.nodes.Node.class, nodeBuilder.getKey())
2739 .augmentation(FlowCapableNode.class).child(Table.class,
2740 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2741 //modification.removeOperationalData(nodeBuilderToInstanceId(nodeBuilder));
2742 //modification.removeOperationalData(path1);
2743 //modification.removeConfigurationData(nodeBuilderToInstanceId(nodeBuilder));
2744 modification.removeConfigurationData(path1);
2745 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2747 RpcResult<TransactionStatus> result = commitFuture.get();
2748 TransactionStatus status = result.getResult();
2749 logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
2750 } catch (InterruptedException e) {
2751 logger.error(e.getMessage(), e);
2752 } catch (ExecutionException e) {
2753 logger.error(e.getMessage(), e);
2758 * Create Ingress Port Match dpidLong, inPort
2760 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
2761 * @param dpidLong Long the datapath ID of a switch/node
2762 * @param inPort Long ingress port on a switch
2763 * @return matchBuilder Map MatchBuilder Object with a match
2765 protected static MatchBuilder createInPortMatch(MatchBuilder matchBuilder, Long dpidLong, Long inPort) {
2767 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
2768 logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, inPort);
2769 matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
2770 matchBuilder.setInPort(ncid);
2772 return matchBuilder;
2776 * Create EtherType Match
2778 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
2779 * @param etherType Long EtherType
2780 * @return matchBuilder Map MatchBuilder Object with a match
2782 protected static MatchBuilder createEtherTypeMatch(MatchBuilder matchBuilder, EtherType etherType) {
2784 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2785 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2786 ethTypeBuilder.setType(new EtherType(etherType));
2787 ethernetMatch.setEthernetType(ethTypeBuilder.build());
2788 matchBuilder.setEthernetMatch(ethernetMatch.build());
2790 return matchBuilder;
2794 * Create Ethernet Source Match
2796 * @param matchBuilder MatchBuilder Object without a match yet
2797 * @param sMacAddr String representing a source MAC
2798 * @return matchBuilder Map MatchBuilder Object with a match
2800 protected static MatchBuilder createEthSrcMatch(MatchBuilder matchBuilder, MacAddress sMacAddr) {
2802 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2803 EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
2804 ethSourceBuilder.setAddress(new MacAddress(sMacAddr));
2805 ethernetMatch.setEthernetSource(ethSourceBuilder.build());
2806 matchBuilder.setEthernetMatch(ethernetMatch.build());
2808 return matchBuilder;
2812 * Create Ethernet Destination Match
2814 * @param matchBuilder MatchBuilder Object without a match yet
2815 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
2816 * @return matchBuilder Map MatchBuilder Object with a match
2819 protected static MatchBuilder createVlanIdMatch(MatchBuilder matchBuilder, VlanId vlanId) {
2820 VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
2821 VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
2822 vlanIdBuilder.setVlanId(new VlanId(vlanId));
2823 vlanIdBuilder.setVlanIdPresent(true);
2824 vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
2825 matchBuilder.setVlanMatch(vlanMatchBuilder.build());
2827 return matchBuilder;
2831 * Create Ethernet Destination Match
2833 * @param matchBuilder MatchBuilder Object without a match yet
2834 * @param dMacAddr String representing a destination MAC
2835 * @return matchBuilder Map MatchBuilder Object with a match
2838 protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
2840 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2841 EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
2842 ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
2844 ethDestinationBuilder.setMask(mask);
2846 ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
2847 matchBuilder.setEthernetMatch(ethernetMatch.build());
2849 return matchBuilder;
2853 * Tunnel ID Match Builder
2855 * @param matchBuilder MatchBuilder Object without a match yet
2856 * @param tunnelId BigInteger representing a tunnel ID
2857 * @return matchBuilder Map MatchBuilder Object with a match
2859 protected static MatchBuilder createTunnelIDMatch(MatchBuilder matchBuilder, BigInteger tunnelId) {
2861 TunnelBuilder tunnelBuilder = new TunnelBuilder();
2862 tunnelBuilder.setTunnelId(tunnelId);
2863 matchBuilder.setTunnel(tunnelBuilder.build());
2865 return matchBuilder;
2869 * Match ICMP code and type
2871 * @param matchBuilder MatchBuilder Object without a match yet
2872 * @param type short representing an ICMP type
2873 * @param code short representing an ICMP code
2874 * @return matchBuilder Map MatchBuilder Object with a match
2876 protected static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
2878 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2879 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2880 ethTypeBuilder.setType(new EtherType(0x0800L));
2881 eth.setEthernetType(ethTypeBuilder.build());
2882 matchBuilder.setEthernetMatch(eth.build());
2884 // Build the IPv4 Match requied per OVS Syntax
2885 IpMatchBuilder ipmatch = new IpMatchBuilder();
2886 ipmatch.setIpProtocol((short) 1);
2887 matchBuilder.setIpMatch(ipmatch.build());
2889 // Build the ICMPv4 Match
2890 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
2891 icmpv4match.setIcmpv4Type(type);
2892 icmpv4match.setIcmpv4Code(code);
2893 matchBuilder.setIcmpv4Match(icmpv4match.build());
2895 return matchBuilder;
2899 * @param matchBuilder MatchBuilder Object without a match yet
2900 * @param dstip String containing an IPv4 prefix
2901 * @return matchBuilder Map Object with a match
2903 private static MatchBuilder createDstL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
2905 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2906 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2907 ethTypeBuilder.setType(new EtherType(0x0800L));
2908 eth.setEthernetType(ethTypeBuilder.build());
2909 matchBuilder.setEthernetMatch(eth.build());
2911 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2912 ipv4match.setIpv4Destination(dstip);
2914 matchBuilder.setLayer3Match(ipv4match.build());
2916 return matchBuilder;
2921 * @param matchBuilder MatchBuilder Object without a match yet
2922 * @param srcip String containing an IPv4 prefix
2923 * @return matchBuilder Map Object with a match
2925 private static MatchBuilder createSrcL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix srcip) {
2927 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2928 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2929 ethTypeBuilder.setType(new EtherType(0x0800L));
2930 eth.setEthernetType(ethTypeBuilder.build());
2931 matchBuilder.setEthernetMatch(eth.build());
2933 Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
2934 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2935 ipv4match.setIpv4Source(srcip);
2936 matchBuilder.setLayer3Match(ipv4match.build());
2938 return matchBuilder;
2943 * Create Source TCP Port Match
2945 * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
2946 * @param tcpport Integer representing a source TCP port
2947 * @return matchBuilder Map MatchBuilder Object with a match
2949 protected static MatchBuilder createSetSrcTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2951 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2952 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2953 ethTypeBuilder.setType(new EtherType(0x0800L));
2954 ethType.setEthernetType(ethTypeBuilder.build());
2955 matchBuilder.setEthernetMatch(ethType.build());
2957 IpMatchBuilder ipmatch = new IpMatchBuilder();
2958 ipmatch.setIpProtocol((short) 6);
2959 matchBuilder.setIpMatch(ipmatch.build());
2961 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2962 tcpmatch.setTcpSourcePort(tcpport);
2963 matchBuilder.setLayer4Match(tcpmatch.build());
2965 return matchBuilder;
2970 * Create Destination TCP Port Match
2972 * @param matchBuilder MatchBuilder Object without a match yet
2973 * @param tcpport Integer representing a destination TCP port
2974 * @return matchBuilder Map MatchBuilder Object with a match
2976 protected static MatchBuilder createSetDstTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2978 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2979 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2980 ethTypeBuilder.setType(new EtherType(0x0800L));
2981 ethType.setEthernetType(ethTypeBuilder.build());
2982 matchBuilder.setEthernetMatch(ethType.build());
2984 IpMatchBuilder ipmatch = new IpMatchBuilder();
2985 ipmatch.setIpProtocol((short) 6);
2986 matchBuilder.setIpMatch(ipmatch.build());
2988 PortNumber dstport = new PortNumber(tcpport);
2989 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2991 tcpmatch.setTcpDestinationPort(tcpport);
2992 matchBuilder.setLayer4Match(tcpmatch.build());
2994 return matchBuilder;
2998 * Create Send to Controller Reserved Port Instruction (packet_in)
3000 * @param ib Map InstructionBuilder without any instructions
3001 * @return ib Map InstructionBuilder with instructions
3004 protected static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
3006 List<Action> actionList = new ArrayList<Action>();
3007 ActionBuilder ab = new ActionBuilder();
3009 OutputActionBuilder output = new OutputActionBuilder();
3010 output.setMaxLength(0xffff);
3011 Uri value = new Uri("CONTROLLER");
3012 output.setOutputNodeConnector(value);
3013 ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
3015 ab.setKey(new ActionKey(0));
3016 actionList.add(ab.build());
3018 // Create an Apply Action
3019 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3020 aab.setAction(actionList);
3022 // Wrap our Apply Action in an Instruction
3023 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3029 * Create NORMAL Reserved Port Instruction (packet_in)
3031 * @param ib Map InstructionBuilder without any instructions
3032 * @return ib Map InstructionBuilder with instructions
3035 protected static InstructionBuilder createNormalInstructions(InstructionBuilder ib) {
3037 List<Action> actionList = new ArrayList<Action>();
3038 ActionBuilder ab = new ActionBuilder();
3040 OutputActionBuilder output = new OutputActionBuilder();
3041 Uri value = new Uri("NORMAL");
3042 output.setOutputNodeConnector(value);
3043 ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
3045 ab.setKey(new ActionKey(0));
3046 actionList.add(ab.build());
3048 // Create an Apply Action
3049 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3050 aab.setAction(actionList);
3052 // Wrap our Apply Action in an Instruction
3053 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3059 * Create Output Port Instruction
3061 * @param ib Map InstructionBuilder without any instructions
3062 * @param dpidLong Long the datapath ID of a switch/node
3063 * @param port Long representing a port on a switch/node
3064 * @return ib InstructionBuilder Map with instructions
3066 protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
3068 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3069 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port);
3071 List<Action> actionList = new ArrayList<Action>();
3072 ActionBuilder ab = new ActionBuilder();
3073 OutputActionBuilder oab = new OutputActionBuilder();
3074 oab.setOutputNodeConnector(ncid);
3076 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3078 ab.setKey(new ActionKey(0));
3079 actionList.add(ab.build());
3081 // Create an Apply Action
3082 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3083 aab.setAction(actionList);
3084 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3090 * Create Output Port Group Instruction
3092 * @param ib Map InstructionBuilder without any instructions
3093 * @param dpidLong Long the datapath ID of a switch/node
3094 * @param port Long representing a port on a switch/node
3095 * @return ib InstructionBuilder Map with instructions
3097 protected InstructionBuilder createOutputPortInstructions(InstructionBuilder ib,
3098 Long dpidLong, Long port ,
3099 List<Instruction> instructions) {
3100 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3101 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3103 List<Action> actionList = new ArrayList<Action>();
3104 ActionBuilder ab = new ActionBuilder();
3106 List<Action> existingActions = null;
3107 if (instructions != null) {
3108 for (Instruction in : instructions) {
3109 if (in.getInstruction() instanceof ApplyActionsCase) {
3110 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3111 actionList.addAll(existingActions);
3115 /* Create output action for this port*/
3116 OutputActionBuilder oab = new OutputActionBuilder();
3117 oab.setOutputNodeConnector(ncid);
3118 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3119 boolean addNew = true;
3121 /* Find the group action and get the group */
3122 for (Action action : actionList) {
3123 if (action.getAction() instanceof OutputActionCase) {
3124 OutputActionCase opAction = (OutputActionCase)action.getAction();
3125 /* If output port action already in the action list of one of the buckets, skip */
3126 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3133 ab.setOrder(actionList.size());
3134 ab.setKey(new ActionKey(actionList.size()));
3135 actionList.add(ab.build());
3137 // Create an Apply Action
3138 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3139 aab.setAction(actionList);
3140 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3141 logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
3146 * Create Output Port Group Instruction
3148 * @param ib Map InstructionBuilder without any instructions
3149 * @param dpidLong Long the datapath ID of a switch/node
3150 * @param port Long representing a port on a switch/node
3151 * @return ib InstructionBuilder Map with instructions
3153 protected InstructionBuilder createOutputGroupInstructions(NodeBuilder nodeBuilder,
3154 InstructionBuilder ib,
3155 Long dpidLong, Long port ,
3156 List<Instruction> instructions) {
3157 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3158 logger.debug("createOutputGroupInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3160 List<Action> actionList = new ArrayList<Action>();
3161 ActionBuilder ab = new ActionBuilder();
3163 List<Action> existingActions = null;
3164 if (instructions != null) {
3165 for (Instruction in : instructions) {
3166 if (in.getInstruction() instanceof ApplyActionsCase) {
3167 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3168 actionList.addAll(existingActions);
3173 GroupBuilder groupBuilder = new GroupBuilder();
3176 /* Create output action for this port*/
3177 OutputActionBuilder oab = new OutputActionBuilder();
3178 oab.setOutputNodeConnector(ncid);
3179 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3180 logger.debug("createOutputGroupInstructions(): output action {}", ab.build());
3181 boolean addNew = true;
3182 boolean groupActionAdded = false;
3184 /* Find the group action and get the group */
3185 for (Action action : actionList) {
3186 if (action.getAction() instanceof GroupActionCase) {
3187 groupActionAdded = true;
3188 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3189 Long id = groupAction.getGroupAction().getGroupId();
3190 String groupName = groupAction.getGroupAction().getGroup();
3191 GroupKey key = new GroupKey(new GroupId(id));
3193 groupBuilder.setGroupId(new GroupId(id));
3194 groupBuilder.setGroupName(groupName);
3195 groupBuilder.setGroupType(GroupTypes.GroupAll);
3196 groupBuilder.setKey(key);
3197 group = getGroup(groupBuilder, nodeBuilder);
3198 logger.debug("createOutputGroupInstructions: group {}", group);
3203 logger.debug("createOutputGroupInstructions: groupActionAdded {}", groupActionAdded);
3204 if (groupActionAdded) {
3205 /* modify the action bucket in group */
3206 groupBuilder = new GroupBuilder(group);
3207 Buckets buckets = groupBuilder.getBuckets();
3208 for (Bucket bucket : buckets.getBucket()) {
3209 List<Action> bucketActions = bucket.getAction();
3210 logger.debug("createOutputGroupInstructions: bucketActions {}", bucketActions);
3211 for (Action action : bucketActions) {
3212 if (action.getAction() instanceof OutputActionCase) {
3213 OutputActionCase opAction = (OutputActionCase)action.getAction();
3214 /* If output port action already in the action list of one of the buckets, skip */
3215 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3222 logger.debug("createOutputGroupInstructions: addNew {}", addNew);
3224 /* the new output action is not in the bucket, add to bucket */
3225 if (!buckets.getBucket().isEmpty()) {
3226 Bucket bucket = buckets.getBucket().get(0);
3227 List<Action> bucketActionList = new ArrayList<Action>();
3228 bucketActionList.addAll(bucket.getAction());
3229 /* set order for new action and add to action list */
3230 ab.setOrder(bucketActionList.size());
3231 ab.setKey(new ActionKey(bucketActionList.size()));
3232 bucketActionList.add(ab.build());
3234 /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3235 BucketsBuilder bucketsBuilder = new BucketsBuilder();
3236 List<Bucket> bucketList = new ArrayList<Bucket>();
3237 BucketBuilder bucketBuilder = new BucketBuilder();
3238 bucketBuilder.setBucketId(new BucketId((long) 1));
3239 bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3240 bucketBuilder.setAction(bucketActionList);
3241 bucketList.add(bucketBuilder.build());
3242 bucketsBuilder.setBucket(bucketList);
3243 groupBuilder.setBuckets(bucketsBuilder.build());
3244 logger.debug("createOutputGroupInstructions: bucketList {}", bucketList);
3249 groupBuilder = new GroupBuilder();
3250 groupBuilder.setGroupType(GroupTypes.GroupAll);
3251 groupBuilder.setGroupId(new GroupId(groupId));
3252 groupBuilder.setKey(new GroupKey(new GroupId(groupId)));
3253 groupBuilder.setGroupName("Output port group" + groupId);
3254 groupBuilder.setBarrier(false);
3256 BucketsBuilder bucketBuilder = new BucketsBuilder();
3257 List<Bucket> bucketList = new ArrayList<Bucket>();
3258 BucketBuilder bucket = new BucketBuilder();
3259 bucket.setBucketId(new BucketId((long) 1));
3260 bucket.setKey(new BucketKey(new BucketId((long) 1)));
3262 /* put output action to the bucket */
3263 List<Action> bucketActionList = new ArrayList<Action>();
3264 /* set order for new action and add to action list */
3265 ab.setOrder(bucketActionList.size());
3266 ab.setKey(new ActionKey(bucketActionList.size()));
3267 bucketActionList.add(ab.build());
3269 bucket.setAction(bucketActionList);
3270 bucketList.add(bucket.build());
3271 bucketBuilder.setBucket(bucketList);
3272 groupBuilder.setBuckets(bucketBuilder.build());
3274 /* Add new group action */
3275 GroupActionBuilder groupActionB = new GroupActionBuilder();
3276 groupActionB.setGroupId(groupId);
3277 groupActionB.setGroup("Output port group" + groupId);
3278 ab = new ActionBuilder();
3279 ab.setAction(new GroupActionCaseBuilder().setGroupAction(groupActionB.build()).build());
3280 ab.setOrder(actionList.size());
3281 ab.setKey(new ActionKey(actionList.size()));
3282 actionList.add(ab.build());
3286 logger.debug("createOutputGroupInstructions: group {}", groupBuilder.build());
3287 logger.debug("createOutputGroupInstructions: actionList {}", actionList);
3290 /* rewrite the group to group table */
3291 writeGroup(groupBuilder, nodeBuilder);
3294 // Create an Apply Action
3295 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3296 aab.setAction(actionList);
3297 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3303 * add Output Port action to Instruction action list.
3304 * This is use for flow with single output port actions.
3305 * Flow with mutiple output port actions should use createOutputPortInstructions() method.
3307 * @param ib Map InstructionBuilder without any instructions
3308 * @param dpidLong Long the datapath ID of a switch/node
3309 * @param port Long representing a port on a switch/node
3310 * @return ib InstructionBuilder Map with instructions
3312 protected static InstructionBuilder addOutputPortInstructions(InstructionBuilder ib,
3313 Long dpidLong, Long port ,
3314 List<Instruction> instructions) {
3315 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3316 logger.debug("addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3318 List<Action> actionList = new ArrayList<Action>();
3319 ActionBuilder ab = new ActionBuilder();
3321 List<Action> existingActions = null;
3322 if (instructions != null) {
3323 for (Instruction in : instructions) {
3324 if (in.getInstruction() instanceof ApplyActionsCase) {
3325 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3326 actionList.addAll(existingActions);
3331 /* Create output action for this port*/
3332 OutputActionBuilder oab = new OutputActionBuilder();
3333 oab.setOutputNodeConnector(ncid);
3334 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3335 ab.setOrder(actionList.size());
3336 ab.setKey(new ActionKey(actionList.size()));
3337 actionList.add(ab.build());
3339 // Create an Apply Action
3340 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3341 aab.setAction(actionList);
3342 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3348 * Remove Output Port from action list in group bucket
3350 * @param ib Map InstructionBuilder without any instructions
3351 * @param dpidLong Long the datapath ID of a switch/node
3352 * @param port Long representing a port on a switch/node
3353 * @return ib InstructionBuilder Map with instructions
3355 protected boolean removeOutputPortFromGroup(NodeBuilder nodeBuilder, InstructionBuilder ib,
3356 Long dpidLong, Long port , List<Instruction> instructions) {
3358 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3359 logger.debug("removeOutputPortFromGroup() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3361 List<Action> actionList = new ArrayList<Action>();
3364 List<Action> existingActions = null;
3365 if (instructions != null) {
3366 for (Instruction in : instructions) {
3367 if (in.getInstruction() instanceof ApplyActionsCase) {
3368 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3369 actionList.addAll(existingActions);
3375 GroupBuilder groupBuilder = new GroupBuilder();
3377 boolean groupActionAdded = false;
3378 /* Find the group action and get the group */
3379 for (Action action : actionList) {
3380 if (action.getAction() instanceof GroupActionCase) {
3381 groupActionAdded = true;
3382 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3383 Long id = groupAction.getGroupAction().getGroupId();
3384 String groupName = groupAction.getGroupAction().getGroup();
3385 GroupKey key = new GroupKey(new GroupId(id));
3387 groupBuilder.setGroupId(new GroupId(id));
3388 groupBuilder.setGroupName(groupName);
3389 groupBuilder.setGroupType(GroupTypes.GroupAll);
3390 groupBuilder.setKey(key);
3391 group = getGroup(groupBuilder, nodeBuilder);
3396 if (groupActionAdded) {
3397 /* modify the action bucket in group */
3398 groupBuilder = new GroupBuilder(group);
3399 Buckets buckets = groupBuilder.getBuckets();
3400 List<Action> bucketActions = new ArrayList<Action>();
3401 for (Bucket bucket : buckets.getBucket()) {
3403 boolean isPortDeleted = false;
3404 bucketActions = bucket.getAction();
3405 for (Action action : bucketActions) {
3406 if (action.getAction() instanceof OutputActionCase) {
3407 OutputActionCase opAction = (OutputActionCase)action.getAction();
3408 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3409 /* Find the output port in action list and remove */
3410 index = bucketActions.indexOf(action);
3411 bucketActions.remove(action);
3412 isPortDeleted = true;
3417 if (isPortDeleted && !bucketActions.isEmpty()) {
3418 for (int i = index; i< bucketActions.size(); i++) {
3419 Action action = bucketActions.get(i);
3420 if (action.getOrder() != i) {
3421 /* Shift the action order */
3422 ab = new ActionBuilder();
3423 ab.setAction(action.getAction());
3425 ab.setKey(new ActionKey(i));
3426 Action actionNewOrder = ab.build();
3427 bucketActions.remove(action);
3428 bucketActions.add(i, actionNewOrder);
3432 } else if (bucketActions.isEmpty()) {
3433 /* remove bucket with empty action list */
3434 buckets.getBucket().remove(bucket);
3438 if (!buckets.getBucket().isEmpty()) {
3439 /* rewrite the group to group table */
3440 /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3441 BucketsBuilder bucketsBuilder = new BucketsBuilder();
3442 List<Bucket> bucketList = new ArrayList<Bucket>();
3443 BucketBuilder bucketBuilder = new BucketBuilder();
3444 bucketBuilder.setBucketId(new BucketId((long) 1));
3445 bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3446 bucketBuilder.setAction(bucketActions);
3447 bucketList.add(bucketBuilder.build());
3448 bucketsBuilder.setBucket(bucketList);
3449 groupBuilder.setBuckets(bucketsBuilder.build());
3450 logger.debug("removeOutputPortFromGroup: bucketList {}", bucketList);
3452 writeGroup(groupBuilder, nodeBuilder);
3453 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3454 aab.setAction(actionList);
3455 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3458 /* remove group with empty bucket. return true to delete flow */
3459 removeGroup(groupBuilder, nodeBuilder);
3463 /* no group for port list. flow can be removed */
3469 * Remove Output Port from Instruction
3471 * @param ib Map InstructionBuilder without any instructions
3472 * @param dpidLong Long the datapath ID of a switch/node
3473 * @param port Long representing a port on a switch/node
3474 * @return ib InstructionBuilder Map with instructions
3476 protected static boolean removeOutputPortFromInstructions(InstructionBuilder ib,
3477 Long dpidLong, Long port , List<Instruction> instructions) {
3479 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3480 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3482 List<Action> actionList = new ArrayList<Action>();
3485 List<Action> existingActions = null;
3486 if (instructions != null) {
3487 for (Instruction in : instructions) {
3488 if (in.getInstruction() instanceof ApplyActionsCase) {
3489 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3490 actionList.addAll(existingActions);
3496 int numOutputPort = 0;
3498 boolean isPortDeleted = false;
3499 for (Action action : actionList) {
3500 if (action.getAction() instanceof OutputActionCase) {
3502 OutputActionCase opAction = (OutputActionCase)action.getAction();
3503 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3504 /* Find the output port in action list and remove */
3505 index = actionList.indexOf(action);
3506 actionList.remove(action);
3507 isPortDeleted = true;
3514 if (isPortDeleted) {
3515 for (int i = index; i< actionList.size(); i++) {
3516 Action action = actionList.get(i);
3517 if (action.getOrder() != i) {
3518 /* Shift the action order */
3519 ab = new ActionBuilder();
3520 ab.setAction(action.getAction());
3522 ab.setKey(new ActionKey(i));
3523 Action actionNewOrder = ab.build();
3524 actionList.remove(action);
3525 actionList.add(i, actionNewOrder);
3530 /* Put new action list in Apply Action instruction */
3531 if (numOutputPort > 0) {
3532 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3533 aab.setAction(actionList);
3534 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3535 logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
3538 /* if all output port are removed. Return true to indicate flow remove */
3544 * Create Set Vlan ID Instruction - This includes push vlan action, and set field -> vlan vid action
3546 * @param ib Map InstructionBuilder without any instructions
3547 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
3548 * @return ib Map InstructionBuilder with instructions
3550 protected static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
3552 List<Action> actionList = new ArrayList<Action>();
3553 ActionBuilder ab = new ActionBuilder();
3555 /* First we push vlan header */
3556 PushVlanActionBuilder vlan = new PushVlanActionBuilder();
3557 vlan.setEthernetType(new Integer(0x8100));
3558 ab.setAction(new PushVlanActionCaseBuilder().setPushVlanAction(vlan.build()).build());
3560 actionList.add(ab.build());
3562 /* Then we set vlan id value as vlanId */
3563 SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
3564 vl.setVlanId(vlanId);
3565 ab = new ActionBuilder();
3566 ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
3568 actionList.add(ab.build());
3569 // Create an Apply Action
3570 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3571 aab.setAction(actionList);
3573 // Wrap our Apply Action in an Instruction
3574 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3580 * Create Pop Vlan Instruction - this remove vlan header
3582 * @param ib Map InstructionBuilder without any instructions
3583 * @return ib Map InstructionBuilder with instructions
3585 protected static InstructionBuilder createPopVlanInstructions(InstructionBuilder ib) {
3587 List<Action> actionList = new ArrayList<Action>();
3588 ActionBuilder ab = new ActionBuilder();
3590 PopVlanActionBuilder popVlanActionBuilder = new PopVlanActionBuilder();
3591 ab.setAction(new PopVlanActionCaseBuilder().setPopVlanAction(popVlanActionBuilder.build()).build());
3593 actionList.add(ab.build());
3595 // Create an Apply Action
3596 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3597 aab.setAction(actionList);
3599 // Wrap our Apply Action in an Instruction
3600 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3606 * Create Set IPv4 Source Instruction
3608 * @param ib Map InstructionBuilder without any instructions
3609 * @param prefixsrc String containing an IPv4 prefix
3610 * @return ib Map InstructionBuilder with instructions
3612 protected static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
3614 List<Action> actionList = new ArrayList<Action>();
3615 ActionBuilder ab = new ActionBuilder();
3617 SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
3618 Ipv4Builder ipsrc = new Ipv4Builder();
3619 ipsrc.setIpv4Address(prefixsrc);
3620 setNwsrcActionBuilder.setAddress(ipsrc.build());
3621 ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
3622 actionList.add(ab.build());
3624 // Create an Apply Action
3625 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3626 aab.setAction(actionList);
3628 // Wrap our Apply Action in an Instruction
3629 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3635 * Create Set IPv4 Destination Instruction
3637 * @param ib Map InstructionBuilder without any instructions
3638 * @param prefixdst String containing an IPv4 prefix
3639 * @return ib Map InstructionBuilder with instructions
3641 protected static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
3643 List<Action> actionList = new ArrayList<Action>();
3644 ActionBuilder ab = new ActionBuilder();
3646 SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
3647 Ipv4Builder ipdst = new Ipv4Builder();
3648 ipdst.setIpv4Address(prefixdst);
3649 setNwDstActionBuilder.setAddress(ipdst.build());
3650 ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
3651 actionList.add(ab.build());
3653 // Create an Apply Action
3654 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3655 aab.setAction(actionList);
3657 // Wrap our Apply Action in an Instruction
3658 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3664 * Create Drop Instruction
3666 * @param ib Map InstructionBuilder without any instructions
3667 * @return ib Map InstructionBuilder with instructions
3669 protected static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
3671 DropActionBuilder dab = new DropActionBuilder();
3672 DropAction dropAction = dab.build();
3673 ActionBuilder ab = new ActionBuilder();
3674 ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
3677 // Add our drop action to a list
3678 List<Action> actionList = new ArrayList<Action>();
3679 actionList.add(ab.build());
3681 // Create an Apply Action
3682 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3683 aab.setAction(actionList);
3685 // Wrap our Apply Action in an Instruction
3686 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3692 * Create GOTO Table Instruction Builder
3694 * @param ib Map InstructionBuilder without any instructions
3695 * @param tableId short representing a flow table ID short representing a flow table ID
3696 * @return ib Map InstructionBuilder with instructions
3698 protected static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
3700 GoToTableBuilder gttb = new GoToTableBuilder();
3701 gttb.setTableId(tableId);
3703 // Wrap our Apply Action in an InstructionBuilder
3704 ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
3710 * Create Set Tunnel ID Instruction Builder
3712 * @param ib Map InstructionBuilder without any instructions
3713 * @param tunnelId BigInteger representing a tunnel ID
3714 * @return ib Map InstructionBuilder with instructions
3716 protected static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
3718 List<Action> actionList = new ArrayList<Action>();
3719 ActionBuilder ab = new ActionBuilder();
3720 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3722 // Build the Set Tunnel Field Action
3723 TunnelBuilder tunnel = new TunnelBuilder();
3724 tunnel.setTunnelId(tunnelId);
3725 setFieldBuilder.setTunnel(tunnel.build());
3726 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3728 actionList.add(ab.build());
3730 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3731 aab.setAction(actionList);
3733 // Wrap the Apply Action in an InstructionBuilder and return
3734 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3740 * Create Set Source TCP Port Instruction
3742 * @param ib Map InstructionBuilder without any instructions
3743 * @param tcpport Integer representing a source TCP port
3744 * @return ib Map InstructionBuilder with instructions
3746 protected static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3748 List<Action> actionList = new ArrayList<Action>();
3749 ActionBuilder ab = new ActionBuilder();
3750 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3752 // Build the Destination TCP Port
3753 PortNumber tcpsrcport = new PortNumber(tcpport);
3754 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3755 tcpmatch.setTcpSourcePort(tcpsrcport);
3757 setFieldBuilder.setLayer4Match(tcpmatch.build());
3758 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3759 ab.setKey(new ActionKey(1));
3760 actionList.add(ab.build());
3762 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3763 aab.setAction(actionList);
3764 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3770 * Create Set Destination TCP Port Instruction
3772 * @param ib Map InstructionBuilder without any instructions
3773 * @param tcpport Integer representing a source TCP port
3774 * @return ib Map InstructionBuilder with instructions
3776 protected static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3778 List<Action> actionList = new ArrayList<Action>();
3779 ActionBuilder ab = new ActionBuilder();
3780 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3782 // Build the Destination TCP Port
3783 PortNumber tcpdstport = new PortNumber(tcpport);
3784 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3785 tcpmatch.setTcpDestinationPort(tcpdstport);
3787 setFieldBuilder.setLayer4Match(tcpmatch.build());
3788 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3789 ab.setKey(new ActionKey(1));
3790 actionList.add(ab.build());
3792 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3793 aab.setAction(actionList);
3794 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3800 * Create Set Source UDP Port Instruction
3802 * @param ib Map InstructionBuilder without any instructions
3803 * @param udpport Integer representing a source UDP port
3804 * @return ib Map InstructionBuilder with instructions
3806 protected static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
3808 List<Action> actionList = new ArrayList<Action>();
3809 ActionBuilder ab = new ActionBuilder();
3810 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3812 // Build the Destination TCP Port
3813 PortNumber udpsrcport = new PortNumber(udpport);
3814 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3815 udpmatch.setUdpSourcePort(udpsrcport);
3817 setFieldBuilder.setLayer4Match(udpmatch.build());
3818 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3819 ab.setKey(new ActionKey(1));
3820 actionList.add(ab.build());
3822 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3823 aab.setAction(actionList);
3824 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3830 * Create Set Destination UDP Port Instruction
3832 * @param ib Map InstructionBuilder without any instructions
3833 * @param udpport Integer representing a destination UDP port
3834 * @return ib Map InstructionBuilder with instructions
3836 protected static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
3838 List<Action> actionList = new ArrayList<Action>();
3839 ActionBuilder ab = new ActionBuilder();
3840 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3842 // Build the Destination TCP Port
3843 PortNumber udpdstport = new PortNumber(udpport);
3844 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3845 udpmatch.setUdpDestinationPort(udpdstport);
3847 setFieldBuilder.setLayer4Match(udpmatch.build());
3848 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3849 ab.setKey(new ActionKey(1));
3850 actionList.add(ab.build());
3852 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3853 aab.setAction(actionList);
3854 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3860 * Create Set ICMP Code Instruction
3862 * @param ib Map InstructionBuilder without any instructions
3863 * @param code short repesenting an ICMP code
3864 * @return ib Map InstructionBuilder with instructions
3867 private static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
3869 List<Action> actionList = new ArrayList<Action>();
3870 ActionBuilder ab = new ActionBuilder();
3871 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3872 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3874 // Build the ICMPv4 Code Match
3875 icmpv4match.setIcmpv4Code(code);
3876 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3878 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3879 ab.setKey(new ActionKey(0));
3880 actionList.add(ab.build());
3881 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3882 aab.setAction(actionList);
3884 // Wrap our Apply Action in an Instruction
3885 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3891 * Create Set ICMP Code Instruction
3893 * @param ib Map InstructionBuilder without any instructions
3894 * @return ib Map InstructionBuilder with instructions
3896 private static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
3898 List<Action> actionList = new ArrayList<Action>();
3899 ActionBuilder ab = new ActionBuilder();
3900 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3901 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3903 // Build the ICMPv4 Code Match
3904 icmpv4match.setIcmpv4Code(type);
3905 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3907 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3908 ab.setKey(new ActionKey(1));
3909 actionList.add(ab.build());
3910 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3911 aab.setAction(actionList);
3913 // Wrap our Apply Action in an Instruction
3914 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3920 * Create Decrement TTL Instruction
3922 * @param ib Map InstructionBuilder without any instructions
3923 * @return ib Map InstructionBuilder with instructions
3925 private static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
3926 DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
3927 DecNwTtl decNwTtl = decNwTtlBuilder.build();
3928 ActionBuilder ab = new ActionBuilder();
3929 ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
3931 // Add our drop action to a list
3932 List<Action> actionList = new ArrayList<Action>();
3933 actionList.add(ab.build());
3935 // Create an Apply Action
3936 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3937 aab.setAction(actionList);
3939 // Wrap our Apply Action in an Instruction
3940 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3948 private static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
3950 List<Action> actionList = new ArrayList<Action>();
3951 ActionBuilder ab = new ActionBuilder();
3953 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3954 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3955 ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
3956 arpsrc.setAddress(macsrc);
3957 arpmatch.setArpSourceHardwareAddress(arpsrc.build());
3958 setFieldBuilder.setLayer3Match(arpmatch.build());
3959 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3960 ab.setKey(new ActionKey(0));
3961 actionList.add(ab.build());
3963 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3964 aab.setAction(actionList);
3972 private static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
3974 List<Action> actionList = new ArrayList<Action>();
3975 ActionBuilder ab = new ActionBuilder();
3976 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3978 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3979 ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
3980 arpdst.setAddress(macdst);
3981 setFieldBuilder.setLayer3Match(arpmatch.build());
3982 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3983 ab.setKey(new ActionKey(0));
3984 actionList.add(ab.build());
3986 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3987 aab.setAction(actionList);
3995 private static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
3997 List<Action> actionList = new ArrayList<Action>();
3998 ActionBuilder ab = new ActionBuilder();
3999 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
4001 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
4002 arpmatch.setArpTargetTransportAddress(dstiparp);
4003 setFieldBuilder.setLayer3Match(arpmatch.build());
4004 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
4005 ab.setKey(new ActionKey(0));
4006 actionList.add(ab.build());
4008 ApplyActionsBuilder aab = new ApplyActionsBuilder();
4009 aab.setAction(actionList);
4017 private static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
4019 List<Action> actionList = new ArrayList<Action>();
4020 ActionBuilder ab = new ActionBuilder();
4021 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
4023 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
4024 arpmatch.setArpSourceTransportAddress(srciparp);
4025 setFieldBuilder.setLayer3Match(arpmatch.build());
4026 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
4027 ab.setKey(new ActionKey(0));
4028 actionList.add(ab.build());
4030 ApplyActionsBuilder aab = new ApplyActionsBuilder();
4031 aab.setAction(actionList);
4037 public void initializeOFFlowRules(Node openflowNode) {
4038 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
4039 List<Node> ovsNodes = connectionService.getNodes();
4040 if (ovsNodes == null) return;
4041 for (Node ovsNode : ovsNodes) {
4042 Long brIntDpid = this.getIntegrationBridgeOFDPID(ovsNode);
4043 Long brExDpid = this.getExternalBridgeDpid(ovsNode);
4044 logger.debug("Compare openflowNode to OVS node {} vs {} and {}", openflowNode.getID(), brIntDpid, brExDpid);
4045 String openflowID = openflowNode.getID().toString();
4046 if (openflowID.contains(brExDpid.toString())) {
4047 this.initializeFlowRules(ovsNode, adminConfigManager.getExternalBridgeName());
4048 this.triggerInterfaceUpdates(ovsNode);
4050 if (openflowID.contains(brIntDpid.toString())) {
4051 this.initializeFlowRules(ovsNode, adminConfigManager.getIntegrationBridgeName());
4052 this.triggerInterfaceUpdates(ovsNode);
4057 private NodeBuilder createNodeBuilder(String nodeId) {
4058 NodeBuilder builder = new NodeBuilder();
4059 builder.setId(new NodeId(nodeId));
4060 builder.setKey(new NodeKey(builder.getId()));
4064 private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeBuilderToInstanceId(NodeBuilder
4066 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
4067 node.getKey()).toInstance();
4070 private String getInternalBridgeUUID (Node node, String bridgeName) {
4072 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
4073 Map<String, Row> bridgeTable = ovsdbTable.getRows(node, ovsdbTable.getTableName(node, Bridge.class));
4074 if (bridgeTable == null) return null;
4075 for (String key : bridgeTable.keySet()) {
4076 Bridge bridge = ovsdbTable.getTypedRow(node, Bridge.class, bridgeTable.get(key));
4077 if (bridge.getName().equals(bridgeName)) return key;
4079 } catch (Exception e) {
4080 logger.error("Error getting Bridge Identifier for {} / {}", node, bridgeName, e);