private Timer timer;
private Timer arp_refresh_timer;
private String containerName = null;
-
+ private ExecutorService executor;
private static class ARPPending {
protected InetAddress hostIP;
protected short sent_count;
timer = new Timer();
timer.schedule(new OutStandingARPHandler(), 4000, 4000);
-
+ executor = Executors.newFixedThreadPool(2);
/* ARP Refresh Timer to go off every 5 seconds to implement ARP aging */
arp_refresh_timer = new Timer();
arp_refresh_timer.schedule(new ARPRefreshHandler(), 5000, 5000);
@Override
public Future<HostNodeConnector> discoverHost(InetAddress networkAddress) {
- ExecutorService executor = Executors.newFixedThreadPool(1);
if (executor == null) {
logger.error("discoverHost: Null executor");
return null;
logger.debug("hostFind(): Host found for IP: {}", networkAddress.getHostAddress());
return host;
}
+
/* host is not found, initiate a discovery */
+
hostFinder.find(networkAddress);
+
/* Also add this host to ARPPending List for any potential retries */
+
AddtoARPPendingList(networkAddress);
logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...",
networkAddress.getHostAddress());
private void replaceHost(InetAddress networkAddr, HostNodeConnector removedHost, HostNodeConnector newHost) {
newHost.initArpSendCountDown();
if (hostsDB.replace(networkAddr, removedHost, newHost)) {
- logger.debug("Host move occurred. Old Host:{}, New Host: {}", removedHost, newHost);
+ logger.debug("Host move occurred: Old Host IP:{}, New Host IP: {}", removedHost.getNetworkAddress()
+ .getHostAddress(), newHost.getNetworkAddress().getHostAddress());
+ logger.debug("Old Host MAC: {}, New Host MAC: {}",
+ HexEncode.bytesToHexString(removedHost.getDataLayerAddressBytes()),
+ HexEncode.bytesToHexString(newHost.getDataLayerAddressBytes()));
+ // Display the Old and New HostNodeConnectors also
+ logger.debug("Old {}, New {}", removedHost, newHost);
} else {
/*
* Host replacement has failed, do the recovery
@Override
public void hostListener(HostNodeConnector host) {
+ logger.debug("ARP received for Host: IP {}, MAC {}, {}", host.getNetworkAddress().getHostAddress(),
+ HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host);
if (hostExists(host)) {
- logger.debug("ARP received for Host: {}", host);
HostNodeConnector existinghost = hostsDB.get(host.getNetworkAddress());
existinghost.initArpSendCountDown();
return;
private void notifyHostLearnedOrRemoved(HostNodeConnector host, boolean add) {
// Update listeners if any
if (newHostNotify != null) {
+ logger.debug("Notifying Applications for Host {} Being {}", host.getNetworkAddress().getHostAddress(),
+ add ? "Added" : "Deleted");
synchronized (this.newHostNotify) {
for (IfNewHostNotify ta : newHostNotify) {
try {
}
if (topologyManager != null && p != null && h != null) {
+ logger.debug("Notifying Topology Manager for Host {} Being {}", h.getNetworkAddress().getHostAddress(),
+ add ? "Added" : "Deleted");
if (add == true) {
Tier tier = new Tier(1);
switchManager.setNodeProp(node, tier);
for (int i = 0; i < failedARPReqList.size(); i++) {
ARPPending arphost;
arphost = failedARPReqList.get(i);
- logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
- hostFinder.find(arphost.getHostIP());
+ if (hostFinder == null) {
+ logger.warn("ARPHandler Services are not available on subnet addition");
+ continue;
+ }
+ logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+ hostFinder.find(arphost.getHostIP());
}
}
}
if (arphost.getSent_count() < switchManager.getHostRetryCount()) {
/*
* No reply has been received of first ARP Req, send the
- * next one
+ * next one. Before sending the ARP, check if ARPHandler
+ * is available or not
*/
+ if (hostFinder == null) {
+ logger.warn("ARPHandler Services are not available for Outstanding ARPs");
+ continue;
+ }
hostFinder.find(arphost.getHostIP());
arphost.sent_count++;
logger.debug("ARP Sent from ARPPending List, IP: {}", arphost.getHostIP().getHostAddress());
} else if (arphost.getSent_count() >= switchManager.getHostRetryCount()) {
/*
- * Two ARP requests have been sent without receiving a
+ * ARP requests have been sent without receiving a
* reply, remove this from the pending list
*/
removePendingARPFromList(i);
- logger.debug("ARP reply not received after two attempts, removing from Pending List IP: {}",
+ logger.debug("ARP reply not received after multiple attempts, removing from Pending List IP: {}",
arphost.getHostIP().getHostAddress());
/*
* Add this host to a different list which will be processed
HexEncode.bytesToHexString(host.getDataLayerAddressBytes()) });
}
host.setArpSendCountDown(arp_cntdown);
+ if (hostFinder == null) {
+ /*
+ * If hostfinder is not available, then can't send the
+ * probe. However, continue the age out the hosts since
+ * we don't know if the host is indeed out there or not.
+ */
+ logger.warn("ARPHandler is not avaialable, can't send the probe");
+ continue;
+ }
hostFinder.probe(host);
}
}
for (int i = 0; i < failedARPReqList.size(); i++) {
arphost = failedARPReqList.get(i);
logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+ if (hostFinder == null) {
+ logger.warn("ARPHandler is not available at interface up");
+ logger.warn("Since this event is missed, host(s) connected to interface {} may not be discovered",
+ nodeConnector);
+ continue;
+ }
hostFinder.find(arphost.getHostIP());
}
HostNodeConnector host = inactiveStaticHosts.get(nodeConnector);
*
*/
void stop() {
+ executor.shutdown();
}
@Override
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.State;
import org.opendaylight.controller.sal.core.Tier;
import org.opendaylight.controller.sal.core.UpdateType;
import org.opendaylight.controller.sal.packet.ARP;
import org.opendaylight.controller.sal.utils.SingletonTask;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.switchmanager.IInventoryListener;
import org.opendaylight.controller.switchmanager.ISwitchManager;
import org.opendaylight.controller.topologymanager.ITopologyManager;
import org.opendaylight.controller.topologymanager.ITopologyManagerAware;
* @author readams
*/
public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
- IListenDataPacket, ITopologyManagerAware, IfIptoHost {
+ IListenDataPacket, ITopologyManagerAware, IfIptoHost,
+ IInventoryListener {
protected static Logger logger = LoggerFactory
.getLogger(DeviceManagerImpl.class);
*/
protected ConcurrentHashMap<Long, Device> deviceMap;
+ protected ConcurrentHashMap<NodeConnector, Entity> inactiveStaticDevices;
/**
* Counter used to generate device keys
*/
/**
* Using the IfNewHostNotify to notify listeners of host changes.
*/
- private Set<IfNewHostNotify> newHostNotify = Collections.synchronizedSet(new HashSet<IfNewHostNotify>());
+ private Set<IfNewHostNotify> newHostNotify = Collections
+ .synchronizedSet(new HashSet<IfNewHostNotify>());
+
/**
* A device update event to be dispatched
*/
// Dependency injection
// ********************
- void setNewHostNotify(IfNewHostNotify obj){
+ void setNewHostNotify(IfNewHostNotify obj) {
this.newHostNotify.add(obj);
}
- void unsetNewHostNotify(IfNewHostNotify obj){
+ void unsetNewHostNotify(IfNewHostNotify obj) {
this.newHostNotify.remove(obj);
}
secondaryIndexMap = new HashMap<EnumSet<DeviceField>, DeviceIndex>();
deviceMap = new ConcurrentHashMap<Long, Device>();
+ inactiveStaticDevices = new ConcurrentHashMap<NodeConnector, Entity>();
classStateMap = new ConcurrentHashMap<String, ClassState>();
apComparator = new AttachmentPointComparator();
if (inPkt == null) {
return PacketResult.IGNORED;
}
-// try {
-// throw new Exception("Sample");
-// } catch (Exception e) {
-// logger.error("Sample stack trace", e);
-// }
+ // try {
+ // throw new Exception("Sample");
+ // } catch (Exception e) {
+ // logger.error("Sample stack trace", e);
+ // }
Packet formattedPak = this.dataPacketService.decodeDataPacket(inPkt);
Ethernet eth;
protected void notifyListeners(List<IDeviceListener> listeners,
DeviceUpdate update) {
- // Topology update is for some reason outside of listeners registry
- // logic
+ // Topology update is for some reason outside of listeners registry
+ // logic
Entity[] ents = update.device.getEntities();
- Entity e = ents[ents.length-1];
+ Entity e = ents[ents.length - 1];
+
NodeConnector p = e.getPort();
Node node = p.getNode();
Host h = null;
try {
+
byte[] mac = NetUtils.longToByteArray6(e.getMacAddress());
DataLinkAddress dla = new EthernetAddress(
mac);
} catch (ConstructionException ce) {
p = null;
h = null;
- } catch (UnknownHostException ue){
+ } catch (UnknownHostException ue) {
p = null;
h = null;
}
return;
}
/**
- * TODO: IfNewHostNotify is needed for current controller API.
- * Adding logic so that existing apps (like SimpleForwardingManager)
- * work. IDeviceListener adds additional methods and uses IListener's
- * callback ordering. The two interfaces need to be merged.
+ * TODO: IfNewHostNotify is needed for current controller API. Adding
+ * logic so that existing apps (like SimpleForwardingManager) work.
+ * IDeviceListener adds additional methods and uses IListener's callback
+ * ordering. The two interfaces need to be merged.
*/
- for (IfNewHostNotify notify : newHostNotify){
+ for (IfNewHostNotify notify : newHostNotify) {
switch (update.change) {
case ADD:
notify.notifyHTClient(update.device.toHostNodeConnector());
break;
case DELETE:
- notify.notifyHTClientHostRemoved(update.device.toHostNodeConnector());
+ notify.notifyHTClientHostRemoved(update.device
+ .toHostNodeConnector());
break;
case CHANGE:
}
}
}
}
+
/**
- * Send update notifications to listeners.
- * IfNewHostNotify listeners need to remove old device and add new device.
+ * Send update notifications to listeners. IfNewHostNotify listeners need to
+ * remove old device and add new device.
+ *
* @param device
* @param oldDevice
*/
- protected void sendDeviceMovedNotification(Device device, Device oldDevice){
- for (IfNewHostNotify notify : newHostNotify){
- notify.notifyHTClientHostRemoved(oldDevice.toHostNodeConnector());
- notify.notifyHTClient(device.toHostNodeConnector());
- }
- sendDeviceMovedNotification(device);
+ protected void sendDeviceMovedNotification(Device device, Device oldDevice) {
+ for (IfNewHostNotify notify : newHostNotify) {
+ notify.notifyHTClientHostRemoved(oldDevice.toHostNodeConnector());
+ notify.notifyHTClient(device.toHostNodeConnector());
}
+ sendDeviceMovedNotification(device);
+ }
/**
* this method will reclassify and reconcile a device - possibilities are -
return mac;
}
- /**
+ /**
* Accepts an IPv4 address in a byte array and returns the corresponding
* 32-bit integer value.
*
Set<HostNodeConnector> nc = new HashSet<HostNodeConnector>();
while (i.hasNext()) {
Device device = i.next();
- if(device.isStaticHost())
+ if (device.isStaticHost())
nc.add(device.toHostNodeConnector());
}
return nc;
@Override
public Set<HostNodeConnector> getInactiveStaticHosts() {
- // TODO Auto-generated method stub
- return null;
+ Collection<Entity> devices = Collections
+ .unmodifiableCollection(inactiveStaticDevices.values());
+ Iterator<Entity> i = devices.iterator();
+ Set<HostNodeConnector> nc = new HashSet<HostNodeConnector>();
+ while (i.hasNext()) {
+ Entity ent = i.next();
+ nc.add(ent.toHostNodeConnector());
+
+ }
+ return nc;
}
@Override
public Status addStaticHost(String networkAddress, String dataLayerAddress,
NodeConnector nc, String vlan) {
Long mac = HexEncode.stringToLong(dataLayerAddress);
- try{
+ try {
InetAddress addr = InetAddress.getByName(networkAddress);
int ip = toIPv4Address(addr.getAddress());
Entity e = new Entity(mac, Short.valueOf(vlan), ip, nc, new Date());
- Device d = this.learnDeviceByEntity(e);
- d.setStaticHost(true);
+
+ if (switchManager.isNodeConnectorEnabled(e.getPort())) {
+ Device d = this.learnDeviceByEntity(e);
+ d.setStaticHost(true);
+ } else {
+ logger.debug(
+ "Switch or switchport is not up, adding host {} to inactive list",
+ addr.getHostName());
+ inactiveStaticDevices.put(e.getPort(), e);
+ }
return new Status(StatusCode.SUCCESS);
- }catch(UnknownHostException e){
+ } catch (UnknownHostException e) {
return new Status(StatusCode.INTERNALERROR);
}
}
public Status removeStaticHost(String networkAddress) {
Integer addr;
try {
- addr = toIPv4Address(InetAddress.getByName(networkAddress).getAddress());
+ addr = toIPv4Address(InetAddress.getByName(networkAddress)
+ .getAddress());
} catch (UnknownHostException e) {
return new Status(StatusCode.NOTFOUND, "Host does not exist");
}
- Iterator<Device> di = this.getDeviceIteratorForQuery(null, null, addr, null);
- List<IDeviceListener> listeners = deviceListeners
- .getOrderedListeners();
- while(di.hasNext()){
+ Iterator<Device> di = this.getDeviceIteratorForQuery(null, null, addr,
+ null);
+ List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
+ while (di.hasNext()) {
Device d = di.next();
- if(d.isStaticHost()){
+ if (d.isStaticHost()) {
deleteDevice(d);
for (IfNewHostNotify notify : newHostNotify)
notify.notifyHTClientHostRemoved(d.toHostNodeConnector());
for (IDeviceListener listener : listeners)
- listener.deviceRemoved(d);
+ listener.deviceRemoved(d);
+ }
+ }
+ //go through inactive entites.
+ Set<HostNodeConnector> inactive = this.getInactiveStaticHosts();
+ for(HostNodeConnector nc : inactive){
+ Integer ip =toIPv4Address(nc.getNetworkAddress().getAddress());
+ if(ip.equals(addr)){
+ this.inactiveStaticDevices.remove(nc.getnodeConnector());
}
}
+
+
return new Status(StatusCode.SUCCESS);
}
+ @Override
+ public void notifyNode(Node node, UpdateType type,
+ Map<String, Property> propMap) {
+ if (node == null)
+ return;
+ List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
+ switch (type) {
+ case REMOVED:
+ logger.debug("Received removed node {}", node);
+ for (Entry<Long, Device> d : deviceMap.entrySet()) {
+ Device device = d.getValue();
+ HostNodeConnector host = device.toHostNodeConnector();
+ if (host.getnodeconnectorNode().equals(node)) {
+ logger.debug("Node: {} is down, remove from Hosts_DB", node);
+ deleteDevice(device);
+ for (IfNewHostNotify notify : newHostNotify)
+ notify.notifyHTClientHostRemoved(host);
+ for (IDeviceListener listener : listeners)
+ listener.deviceRemoved(device);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void notifyNodeConnector(NodeConnector nodeConnector,
+ UpdateType type, Map<String, Property> propMap) {
+ if (nodeConnector == null)
+ return;
+ List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
+ boolean up = false;
+ switch (type) {
+ case ADDED:
+ up = true;
+ break;
+ case REMOVED:
+ break;
+ case CHANGED:
+ State state = (State) propMap.get(State.StatePropName);
+ if ((state != null) && (state.getValue() == State.EDGE_UP)) {
+ up = true;
+ }
+ break;
+ default:
+ return;
+ }
+
+ if (up) {
+ logger.debug("handleNodeConnectorStatusUp {}", nodeConnector);
+
+ Entity ent = inactiveStaticDevices.get(nodeConnector);
+ Device device = this.learnDeviceByEntity(ent);
+ if(device!=null){
+ HostNodeConnector host = device.toHostNodeConnector();
+ if (host != null) {
+ inactiveStaticDevices.remove(nodeConnector);
+ for (IfNewHostNotify notify : newHostNotify)
+ notify.notifyHTClient(host);
+ for (IDeviceListener listener : listeners)
+ listener.deviceAdded(device);
+ } else {
+ logger.debug("handleNodeConnectorStatusDown {}", nodeConnector);
+ }
+ }
+ }else{
+ // remove all devices on the node that went down.
+ for (Entry<Long, Device> entry : deviceMap.entrySet()) {
+ Device device = entry.getValue();
+ HostNodeConnector host = device.toHostNodeConnector();
+ if (host.getnodeConnector().equals(nodeConnector)) {
+ deleteDevice(device);
+ for (IfNewHostNotify notify : newHostNotify)
+ notify.notifyHTClientHostRemoved(host);
+ for (IDeviceListener listener : listeners)
+ listener.deviceRemoved(device);
+ }
+ }
+
+ }
+ }
+
+
/**
* For testing: consolidate the store NOW
*/
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
* This Class forms the vendor specific IPv6 Flow Match messages as well as
* processes the vendor specific IPv6 Stats Reply message.
*
- * For message creation, it parses the user entered IPv6 match fields, creates
- * a sub-message for each field which are later used to form the complete
- * message.
+ * For message creation, it parses the user entered IPv6 match fields, creates a
+ * sub-message for each field which are later used to form the complete message.
*
* For message processing, it parses the incoming message and reads each field
* of the message and stores in appropriate field of V6Match object.
protected short inputPortMask;
protected byte[] dataLayerSourceMask;
protected byte[] dataLayerDestinationMask;
- protected short dataLayerVirtualLanMask;
- protected byte dataLayerVirtualLanPriorityCodePointMask;
+ protected int dataLayerVirtualLanTCIMask;
protected short dataLayerTypeMask;
protected byte networkTypeOfServiceMask;
protected byte networkProtocolMask;
protected MatchFieldState inputPortState;
protected MatchFieldState dlSourceState;
protected MatchFieldState dlDestState;
- protected MatchFieldState dlVlanState;
+ protected MatchFieldState dlVlanIDState;
+ protected MatchFieldState dlVlanPCPState;
+ protected MatchFieldState dlVlanTCIState;
protected MatchFieldState ethTypeState;
protected MatchFieldState nwTosState;
protected MatchFieldState nwProtoState;
this.dataLayerSourceMask = null;
this.dataLayerDestinationMask = null;
this.dataLayerTypeMask = 0;
- this.dataLayerVirtualLanMask = 0;
- this.dataLayerVirtualLanPriorityCodePointMask = 0;
+ this.dataLayerVirtualLanTCIMask = 0;
this.networkTypeOfServiceMask = 0;
this.networkProtocolMask = 0;
this.transportSourceMask = 0;
this.inputPortState = MatchFieldState.MATCH_ABSENT;
this.dlSourceState = MatchFieldState.MATCH_ABSENT;
this.dlDestState = MatchFieldState.MATCH_ABSENT;
- this.dlVlanState = MatchFieldState.MATCH_ABSENT;
+ this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
+ this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
+ this.dlVlanTCIState = MatchFieldState.MATCH_ABSENT;
this.ethTypeState = MatchFieldState.MATCH_ABSENT;
this.nwTosState = MatchFieldState.MATCH_ABSENT;
this.nwProtoState = MatchFieldState.MATCH_ABSENT;
if (match.getNetworkSource() != 0) {
InetAddress address = NetUtils.getInetAddress(match.getNetworkSource());
InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkSourceMaskLen(), false);
- this.setNetworkDestination(address, mask);
+ this.setNetworkSource(address, mask);
} else {
this.nwSrcState = MatchFieldState.MATCH_ABSENT;
}
}
this.dataLayerSourceMask = null;
- if (match.getDataLayerSource() != null && !NetUtils.isZeroMAC(match.getDataLayerSource())) {
+ if (match.getDataLayerSource() != null
+ && !NetUtils.isZeroMAC(match.getDataLayerSource())) {
this.setDataLayerSource(match.getDataLayerSource(), null);
} else {
this.dlSourceState = MatchFieldState.MATCH_ABSENT;
}
this.dataLayerDestinationMask = null;
- if (match.getDataLayerDestination() != null && !NetUtils.isZeroMAC(match.getDataLayerDestination())) {
+ if (match.getDataLayerDestination() != null
+ && !NetUtils.isZeroMAC(match.getDataLayerDestination())) {
this.setDataLayerDestination(match.getDataLayerDestination(), null);
} else {
this.dlDestState = MatchFieldState.MATCH_ABSENT;
this.ethTypeState = MatchFieldState.MATCH_ABSENT;
}
- this.dataLayerVirtualLanMask = 0;
+ this.dataLayerVirtualLanTCIMask = 0;
+ this.dlVlanTCIState = MatchFieldState.MATCH_ABSENT;
if (match.getDataLayerVirtualLan() != 0) {
this.setDataLayerVirtualLan(match.getDataLayerVirtualLan(),
(short) 0);
} else {
this.dataLayerVirtualLan = 0;
- this.dlVlanState = MatchFieldState.MATCH_ABSENT;
+ this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
}
- this.dataLayerVirtualLanPriorityCodePointMask = 0;
if (match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
- this.setDataLayerVirtualLanPriorityCodePoint(match
- .getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
+ this.setDataLayerVirtualLanPriorityCodePoint(
+ match.getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
} else {
this.dataLayerVirtualLanPriorityCodePoint = 0;
+ this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
}
this.networkProtocolMask = 0;
if (match.getNetworkProtocol() != 0) {
- this.setNetworkProtocol(this.networkProtocol = match
- .getNetworkProtocol(), (byte) 0);
+ this.setNetworkProtocol(
+ this.networkProtocol = match.getNetworkProtocol(), (byte) 0);
} else {
this.networkProtocol = 0;
this.nwProtoState = MatchFieldState.MATCH_ABSENT;
this.networkTypeOfServiceMask = 0;
if (match.getNetworkTypeOfService() != 0) {
- this.setNetworkTypeOfService(this.networkTypeOfService = match
- .getNetworkTypeOfService(), (byte) 0);
+ this.setNetworkTypeOfService(
+ this.networkTypeOfService = match.getNetworkTypeOfService(),
+ (byte) 0);
} else {
this.networkTypeOfService = match.getNetworkTypeOfService();
this.nwTosState = MatchFieldState.MATCH_ABSENT;
return (ipv6ext_etype_msg.array());
}
- private byte[] getIPv6ExtensionVlanIDMatchMsg(short VLAN) {
- ByteBuffer ipv6ext_vlanid_msg = ByteBuffer.allocate(6);
+ private byte[] getVlanTCI(short dataLayerVirtualLanID,
+ byte dataLayerVirtualLanPriorityCodePoint) {
+ ByteBuffer vlan_tci = ByteBuffer.allocate(2);
+ int cfi = 1 << 12; // the cfi bit is in position 12
+ int pcp = dataLayerVirtualLanPriorityCodePoint << 13; // the pcp fields
+ // have to move by
+ // 13
+ int vlan_tci_int = pcp + cfi + dataLayerVirtualLanID;
+ vlan_tci.put((byte) (vlan_tci_int >> 8)); // bits 8 to 15
+ vlan_tci.put((byte) vlan_tci_int); // bits 0 to 7
+ return vlan_tci.array();
+ }
+
+ private byte[] getIPv6ExtensionVlanTCIMatchMsg(short dataLayerVirtualLanID,
+ byte dataLayerVirtualLanPriorityCodePoint) {
+ ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(6);
int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 0, 2);
- ipv6ext_vlanid_msg.putInt(nxm_header);
- ipv6ext_vlanid_msg.putShort(VLAN);
- return (ipv6ext_vlanid_msg.array());
+ ipv6ext_vlan_tci_msg.putInt(nxm_header);
+ ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLanID,
+ dataLayerVirtualLanPriorityCodePoint));
+ return (ipv6ext_vlan_tci_msg.array());
+ }
+
+ private byte[] getIPv6ExtensionVlanTCIMatchWithMaskMsg(
+ short dataLayerVirtualLan,
+ byte dataLayerVirtualLanPriorityCodePoint,
+ int dataLayerVirtualLanTCIMask) {
+ ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(8);
+ int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
+ OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 1, 4);
+ ipv6ext_vlan_tci_msg.putInt(nxm_header);
+ ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLan,
+ dataLayerVirtualLanPriorityCodePoint));
+ ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask >> 8)); // bits
+ // 8
+ // to
+ // 15
+ ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask)); // bits 0
+ // to 7
+ return (ipv6ext_vlan_tci_msg.array());
}
private byte[] getIPv6ExtensionSrcIPv6MatchMsg(byte[] srcIpv6) {
ipv6ext_proto_msg.putInt(nxm_header);
if (protocol == IPProtocols.ICMP.getValue()) {
/*
- * The front end passes the same protocol type values for IPv4
- * and IPv6 flows. For the Protocol types we allow in our GUI
- * (ICMP, TCP, UDP), ICMP is the only one which is different for
- * IPv6. It is 1 for v4 and 58 for v6 Therefore, we overwrite it
- * here.
+ * The front end passes the same protocol type values for IPv4 and
+ * IPv6 flows. For the Protocol types we allow in our GUI (ICMP,
+ * TCP, UDP), ICMP is the only one which is different for IPv6. It
+ * is 1 for v4 and 58 for v6 Therefore, we overwrite it here.
*/
protocol = IPProtocols.ICMPV6.getValue();
}
}
/**
- * Sets this (V6Match) object's member variables based on a comma-separated key=value pair similar to OFMatch's fromString.
+ * Sets this (V6Match) object's member variables based on a comma-separated
+ * key=value pair similar to OFMatch's fromString.
*
- * @param match a key=value comma separated string.
+ * @param match
+ * a key=value comma separated string.
*/
@Override
public void fromString(String match) throws IllegalArgumentException {
this.dataLayerType = U16.t(Integer.valueOf(values[1]
.replaceFirst("0x", ""), 16));
} else {
+
this.dataLayerType = U16.t(Integer.valueOf(values[1]));
}
ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
match_len += 6;
} else if (values[0].equals(STR_DL_VLAN)) {
this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1]));
- dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 6;
+ this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
+ // the variable dlVlanIDState is not really used as a flag
+ // for serializing and deserializing. Rather it is used as a
+ // flag
+ // to check if the vlan id is being set so that we can set the
+ // dlVlanTCIState appropriately.
+ if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
+ match_len -= 2;
+ } else {
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+ this.dataLayerVirtualLanTCIMask = 0x1fff;
+ match_len += 8;
+ }
+ this.wildcards &= ~OFPFW_DL_VLAN;
} else if (values[0].equals(STR_DL_VLAN_PCP)) {
this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short
.valueOf(values[1]));
+ this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
+ // the variable dlVlanPCPState is not really used as a flag
+ // for serializing and deserializing. Rather it is used as a
+ // flag
+ // to check if the vlan pcp is being set so that we can set the
+ // dlVlanTCIState appropriately.
+ if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
+ match_len -= 2;
+ } else {
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+ this.dataLayerVirtualLanTCIMask = 0xf000;
+ match_len += 8;
+ }
this.wildcards &= ~OFPFW_DL_VLAN_PCP;
} else if (values[0].equals(STR_NW_DST)
|| values[0].equals("ip_dst")) {
}
this.setNetworkDestination(address, mask);
} catch (UnknownHostException e) {
- logger.error("",e);
+ logger.error("", e);
}
} else if (values[0].equals(STR_NW_SRC)
|| values[0].equals("ip_src")) {
}
this.setNetworkSource(address, mask);
} catch (UnknownHostException e) {
- logger.error("",e);
+ logger.error("", e);
}
} else if (values[0].equals(STR_NW_PROTO)) {
this.networkProtocol = U8.t(Short.valueOf(values[1]));
}
/*
- * In a V6 extension message action list should be preceded by a padding of 0 to
- * 7 bytes based upon following formula.
+ * In a V6 extension message action list should be preceded by a padding
+ * of 0 to 7 bytes based upon following formula.
*/
pad_size = (short) (((match_len + 7) / 8) * 8 - match_len);
byte[] ipv6ext_srcmac_msg = getIPv6ExtensionSrcMacMatchMsg(this.dataLayerSource);
data.put(ipv6ext_srcmac_msg);
}
- if (dlVlanState == MatchFieldState.MATCH_FIELD_ONLY) {
- byte[] ipv6ext_vlan_id_msg = getIPv6ExtensionVlanIDMatchMsg(this.dataLayerVirtualLan);
- data.put(ipv6ext_vlan_id_msg);
+ if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_ONLY) {
+ byte[] ipv6ext_vlan_tci_msg = getIPv6ExtensionVlanTCIMatchMsg(
+ this.dataLayerVirtualLan,
+ this.dataLayerVirtualLanPriorityCodePoint);
+ data.put(ipv6ext_vlan_tci_msg);
+ } else if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
+ byte[] ipv6ext_vlan_tci_msg_with_mask = getIPv6ExtensionVlanTCIMatchWithMaskMsg(
+ this.dataLayerVirtualLan,
+ this.dataLayerVirtualLanPriorityCodePoint,
+ this.dataLayerVirtualLanTCIMask);
+ data.put(ipv6ext_vlan_tci_msg_with_mask);
}
if (nwSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
byte[] ipv6ext_src_ipv6_msg = getIPv6ExtensionSrcIPv6MatchMsg(this.nwSrc
this.match_len += 6;
}
+ private short getVlanID(byte firstByte, byte secondByte) {
+ short vlan_id_mask_firstByte = 0x0f;// this is the mask for the first
+ // byte
+ short vlan_id_mask_secondByte = 0xff;// this is the mask for the second
+ // byte
+ int vlanPart1 = (firstByte & vlan_id_mask_firstByte) << 8;
+ int vlanPart2 = secondByte & vlan_id_mask_secondByte;
+ return (short) (vlanPart1 + vlanPart2);
+ }
+
+ private byte getVlanPCP(byte pcpByte) {
+ short vlan_pcp_mask = 0xe0;// this is the vlan pcp mask
+ int pcp_int = pcpByte & vlan_pcp_mask;
+ return (byte) (pcp_int >> 5);
+ }
+
private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) {
- short vlan_mask = 0xfff;
if (hasMask) {
if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) {
return;
- } else {
- short vlan = data.getShort();
- vlan &= vlan_mask;
- super.setDataLayerVirtualLan(vlan);
- this.dataLayerVirtualLanMask = data.getShort();
- this.dlVlanState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+ }
+ else {
+ byte firstByte = data.get();
+ byte secondByte = data.get();
+ this.dataLayerVirtualLanTCIMask = data.getShort() & 0xffff; // we
+ // need
+ // the
+ // last
+ // 16
+ // bits
+ // check the mask now
+ if ((this.dataLayerVirtualLanTCIMask & 0x0fff) != 0) {
+ // if its a vlan id mask
+ // extract the vlan id
+ super.setDataLayerVirtualLan(getVlanID(firstByte,
+ secondByte));
+ } else {
+ this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
+ }
+ if ((this.dataLayerVirtualLanTCIMask & 0xe000) != 0) {
+ // else if its a vlan pcp mask
+ // extract the vlan pcp
+ super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
+ } else {
+ this.wildcards ^= (1 << 20);
+ }
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
this.match_len += 8;
- this.wildcards ^= (1 << 20);
}
} else {
if ((nxmLen != 2) || (data.remaining() < 2)) {
return;
- } else {
- short vlan = data.getShort();
- vlan &= vlan_mask;
- super.setDataLayerVirtualLan(vlan);
- this.dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
+ }
+ else {
+ // get the vlan pcp
+ byte firstByte = data.get();
+ byte secondByte = data.get();
+ super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
+ super.setDataLayerVirtualLan(getVlanID(firstByte, secondByte));
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 6;
}
}
-
- this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
}
private void readIpTos(ByteBuffer data, int nxmLen, boolean hasMask) {
super.setNetworkSource(address);
this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 8;
- this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
+ this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0
+ // Match
}
}
}
this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
this.match_len += 12;
int prefixlen = getNetworkMaskPrefixLength(mbytes);
- this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
- this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0 Match
+ this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
+ // Match
+ this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0
+ // Match
}
} else {
if ((nxmLen != 4) || (data.remaining() < 4)) {
int address = NetUtils.byteArray4ToInt(dbytes);
super.setNetworkDestination(address);
this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
- this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
+ this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
+ // Match
this.match_len += 8;
}
}
+ HexEncode.bytesToHexStringFormat(dataLayerSourceMask)
+ ", dataLayerDestinationMask="
+ HexEncode.bytesToHexStringFormat(dataLayerDestinationMask)
- + ", dataLayerVirtualLanMask=" + dataLayerVirtualLanMask
- + ", dataLayerVirtualLanPriorityCodePointMask="
- + dataLayerVirtualLanPriorityCodePointMask
+ + ", dataLayerVirtualLanTCIMask=" + dataLayerVirtualLanTCIMask
+ ", dataLayerTypeMask=" + dataLayerTypeMask
+ ", networkTypeOfServiceMask=" + networkTypeOfServiceMask
+ ", networkProtocolMask=" + networkProtocolMask
+ ", dstIPv6SubnetMaskbits=" + dstIPv6SubnetMaskbits
+ ", inputPortState=" + inputPortState + ", dlSourceState="
+ dlSourceState + ", dlDestState=" + dlDestState
- + ", dlVlanState=" + dlVlanState + ", ethTypeState="
+ + ", dlVlanTCIState=" + dlVlanTCIState + ", ethTypeState="
+ ethTypeState + ", nwTosState=" + nwTosState
+ ", nwProtoState=" + nwProtoState + ", nwSrcState="
+ nwSrcState + ", nwDstState=" + nwDstState + ", tpSrcState="
/**
* Read the data corresponding to the match field (received from the wire)
- * Input: data: match field(s). Since match field is of variable length, the whole data that are passed in
- * are assumed to fem0tbd.be the match fields.
+ * Input: data: match field(s). Since match field is of variable length, the
+ * whole data that are passed in are assumed to fem0tbd.be the match fields.
+ *
* @param data
*/
@Override
/*
* at least 4 bytes for each match header
*/
- logger.error("Invalid Vendor Extension Header. Size {}", data
- .remaining());
+ logger.error("Invalid Vendor Extension Header. Size {}",
+ data.remaining());
return;
}
/*
// Sync with 0F 1.0 Match
if (super.getDataLayerType() == 0x800) {
if (((this.wildcards >> 8) & 0x3f) == 0x3f) {
- //ipv4 src processing
+ // ipv4 src processing
this.wildcards ^= (((1 << 5) - 1) << 8);
}
if (((this.wildcards >> 14) & 0x3f) == 0x3f) {
- //ipv4 dest processing
+ // ipv4 dest processing
this.wildcards ^= (((1 << 5) - 1) << 14);
}
} else {
}
}
- public short getDataLayerVirtualLanMask() {
- return dataLayerVirtualLanMask;
- }
-
public void setDataLayerVirtualLan(short vlan, short mask) {
+ // mask is ignored as the code sets the appropriate mask
super.dataLayerVirtualLan = vlan;
- if (mask == 0) {
- this.dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += 6;
+ this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
+ // the variable dlVlanIDState is not really used as a flag
+ // for serializing and deserializing. Rather it is used as a flag
+ // to check if the vlan id is being set so that we can set the
+ // dlVlanTCIState appropriately.
+ if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
+ match_len -= 2;
} else {
- this.dataLayerVirtualLanMask = mask;
- this.dlVlanState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += 8;
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+ this.dataLayerVirtualLanTCIMask = 0x1fff;
+ match_len += 8;
}
}
public void setDataLayerVirtualLanPriorityCodePoint(byte pcp, byte mask) {
+ // mask is ignored as the code sets the appropriate mask
super.dataLayerVirtualLanPriorityCodePoint = pcp;
+ this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
+ // the variable dlVlanPCPState is not really used as a flag
+ // for serializing and deserializing. Rather it is used as a flag
+ // to check if the vlan pcp is being set so that we can set the
+ // dlVlanTCIState appropriately.
+ if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
+ match_len -= 2;
+ } else {
+ this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+ this.dataLayerVirtualLanTCIMask = 0xf000;
+ match_len += 8;
+ }
}
public void setDataLayerType(short ethType, short mask) {
result = prime * result + Arrays.hashCode(dataLayerDestinationMask);
result = prime * result + Arrays.hashCode(dataLayerSourceMask);
result = prime * result + dataLayerTypeMask;
- result = prime * result + dataLayerVirtualLanMask;
- result = prime * result + dataLayerVirtualLanPriorityCodePointMask;
- result = prime * result + ((dlDestState == null) ? 0 : dlDestState.hashCode());
- result = prime * result + ((dlSourceState == null) ? 0 : dlSourceState.hashCode());
- result = prime * result + ((dlVlanState == null) ? 0 : dlVlanState.hashCode());
+ result = prime * result + dataLayerVirtualLanTCIMask;
+ result = prime * result
+ + ((dlDestState == null) ? 0 : dlDestState.hashCode());
+ result = prime * result
+ + ((dlSourceState == null) ? 0 : dlSourceState.hashCode());
+ result = prime * result
+ + ((dlVlanTCIState == null) ? 0 : dlVlanTCIState.hashCode());
result = prime * result + dstIPv6SubnetMaskbits;
- result = prime * result + ((ethTypeState == null) ? 0 : ethTypeState.hashCode());
+ result = prime * result
+ + ((ethTypeState == null) ? 0 : ethTypeState.hashCode());
result = prime * result + inputPortMask;
- result = prime * result + ((inputPortState == null) ? 0 : inputPortState.hashCode());
+ result = prime * result
+ + ((inputPortState == null) ? 0 : inputPortState.hashCode());
result = prime * result + match_len;
result = prime * result + networkProtocolMask;
result = prime * result + networkTypeOfServiceMask;
result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
- result = prime * result + ((nwDstState == null) ? 0 : nwDstState.hashCode());
- result = prime * result + ((nwProtoState == null) ? 0 : nwProtoState.hashCode());
+ result = prime * result
+ + ((nwDstState == null) ? 0 : nwDstState.hashCode());
+ result = prime * result
+ + ((nwProtoState == null) ? 0 : nwProtoState.hashCode());
result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
- result = prime * result + ((nwSrcState == null) ? 0 : nwSrcState.hashCode());
- result = prime * result + ((nwTosState == null) ? 0 : nwTosState.hashCode());
+ result = prime * result
+ + ((nwSrcState == null) ? 0 : nwSrcState.hashCode());
+ result = prime * result
+ + ((nwTosState == null) ? 0 : nwTosState.hashCode());
result = prime * result + pad_size;
result = prime * result + srcIPv6SubnetMaskbits;
- result = prime * result + ((tpDstState == null) ? 0 : tpDstState.hashCode());
- result = prime * result + ((tpSrcState == null) ? 0 : tpSrcState.hashCode());
+ result = prime * result
+ + ((tpDstState == null) ? 0 : tpDstState.hashCode());
+ result = prime * result
+ + ((tpSrcState == null) ? 0 : tpSrcState.hashCode());
result = prime * result + transportDestinationMask;
result = prime * result + transportSourceMask;
return result;
if (dataLayerTypeMask != other.dataLayerTypeMask) {
return false;
}
- if (dataLayerVirtualLanMask != other.dataLayerVirtualLanMask) {
+ if (dataLayerVirtualLanTCIMask != other.dataLayerVirtualLanTCIMask) {
return false;
}
- if (dataLayerVirtualLanPriorityCodePointMask != other.dataLayerVirtualLanPriorityCodePointMask) {
- return false;
- }
- if (dlDestState != other.dlDestState) {
+ if (dlVlanTCIState != other.dlVlanTCIState) {
return false;
}
if (dlSourceState != other.dlSourceState) {
return false;
}
- if (dlVlanState != other.dlVlanState) {
- return false;
- }
if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) {
return false;
}