/** * Check whether this entity has non-'zero' values in any of its key fields * @return true if any key fields have a non-null value */ public boolean hasNonZeroOrNonNullKeys() { for (DeviceField f : keyFields) { switch (f) { case MAC: /* We assume operation over Ethernet, thus all devices must have a MAC */ return true; case IPv4: if (!entity.ipv4Address.equals(IPv4Address.NONE)) return true; break; case IPv6: if (!entity.ipv6Address.equals(IPv6Address.NONE)) return true; break; case SWITCH: if (!entity.switchDPID.equals(DatapathId.NONE)) return true; break; case PORT: if (!entity.switchPort.equals(OFPort.ZERO)) return true; break; case VLAN: /* VLAN can still be null, meaning 'don't care'. VlanVid.ZERO means 'untagged' */ if (entity.vlan != null) return true; break; } } return false; }
private void generateDeviceEvent(IDevice device, String reason) { List<IPv4Address> ipv4Addresses = new ArrayList<IPv4Address>(Arrays.asList(device.getIPv4Addresses())); List<IPv6Address> ipv6Addresses = new ArrayList<IPv6Address>(Arrays.asList(device.getIPv6Addresses())); List<SwitchPort> oldAps = new ArrayList<SwitchPort>(Arrays.asList(device.getOldAP())); List<SwitchPort> currentAps = new ArrayList<SwitchPort>(Arrays.asList(device.getAttachmentPoints())); List<VlanVid> vlanIds = new ArrayList<VlanVid>(Arrays.asList(device.getVlanId())); debugEventCategory.newEventNoFlush(new DeviceEvent(device.getMACAddress(), ipv4Addresses, ipv6Addresses, oldAps, currentAps, vlanIds, reason)); }
/** * Parse an entity from an {@link Ethernet} packet. * @param eth the packet to parse * @param sw the switch on which the packet arrived * @param pi the original packetin * @return the entity from the packet */ protected Entity getSourceEntityFromPacket(Ethernet eth, DatapathId swdpid, OFPort port) { MacAddress dlAddr = eth.getSourceMACAddress(); // Ignore broadcast/multicast source if (dlAddr.isBroadcast() || dlAddr.isMulticast()) return null; // Ignore 0 source mac if (dlAddr.getLong() == 0) return null; VlanVid vlan = VlanVid.ofVlan(eth.getVlanID()); IPv4Address ipv4Src = getSrcIPv4AddrFromARP(eth, dlAddr); IPv6Address ipv6Src = ipv4Src.equals(IPv4Address.NONE) ? getSrcIPv6Addr(eth) : IPv6Address.NONE; return new Entity(dlAddr, vlan, ipv4Src, ipv6Src, swdpid, port, new Date()); }
/** * Construct a new device iterator over the key fields * @param subIterator an iterator over the full data structure to scan * @param entityClasses the entity classes to search for * @param macAddress The MAC address * @param vlan the VLAN * @param ipv4Address the ipv4 address * @param ipv6Address the ipv6 address * @param switchDPID the switch DPID * @param switchPort the switch port */ public DeviceIterator(Iterator<Device> subIterator, IEntityClass[] entityClasses, MacAddress macAddress, VlanVid vlan, IPv4Address ipv4Address, IPv6Address ipv6Address, DatapathId switchDPID, OFPort switchPort) { super(subIterator); this.entityClasses = entityClasses; this.subIterator = subIterator; this.macAddress = macAddress; this.vlan = vlan; this.ipv4Address = ipv4Address; this.ipv6Address = ipv6Address; this.switchDPID = switchDPID; this.switchPort = switchPort; }
@Test public void testLastSeen() throws Exception { Calendar c = Calendar.getInstance(); Date d1 = c.getTime(); Entity entity1 = new Entity(MacAddress.of(1L), VlanVid.ZERO /* untagged*/, IPv4Address.NONE, IPv6Address.NONE, DatapathId.NONE, OFPort.ZERO, d1); c.add(Calendar.SECOND, 1); Entity entity2 = new Entity(MacAddress.of(1L), VlanVid.ZERO /* untagged*/, IPv4Address.of(1), IPv6Address.NONE, DatapathId.NONE, OFPort.ZERO, c.getTime()); IDevice d = deviceManager.learnDeviceByEntity(entity2); assertEquals(c.getTime(), d.getLastSeen()); d = deviceManager.learnDeviceByEntity(entity1); assertEquals(c.getTime(), d.getLastSeen()); deviceManager.startUp(null); d = deviceManager.learnDeviceByEntity(entity1); assertEquals(d1, d.getLastSeen()); d = deviceManager.learnDeviceByEntity(entity2); assertEquals(c.getTime(), d.getLastSeen()); }
/** * Verify that the given device exactly matches the given fields. E.g., * if ip is not null we expect the device to have exactly one IP address. * swId and port are the attachment point port. * Vlan and ip are optional all other fields must be specified. * @return */ private static void verifyDevice(IDevice d, MacAddress mac, VlanVid vlan, IPv4Address ipv4, IPv6Address ipv6, DatapathId swId, OFPort port) { assertNotNull(d); if (!mac.equals(MacAddress.NONE)) { assertEquals(mac, d.getMACAddress()); } if (vlan != null) { assertArrayEquals(new VlanVid[] { vlan }, d.getVlanId()); } if (!ipv4.equals(IPv4Address.NONE)) { assertArrayEquals(new IPv4Address[] { ipv4 }, d.getIPv4Addresses()); } if (!ipv6.equals(IPv6Address.NONE)) { assertArrayEquals(new IPv6Address[] { ipv6 }, d.getIPv6Addresses()); } if (!swId.equals(DatapathId.NONE) && !port.equals(OFPort.ZERO)) { SwitchPort expectedAp = new SwitchPort(swId, port); assertArrayEquals(new SwitchPort[] { expectedAp }, d.getAttachmentPoints()); } }
@Test public void testGetSwitchPortVlanId() { Entity entity1 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(1), IPv4Address.NONE, IPv6Address.NONE, DatapathId.of(10L), OFPort.of(1), new Date()); Entity entity2 = new Entity(MacAddress.of(1L), VlanVid.ZERO, IPv4Address.NONE, IPv6Address.NONE, DatapathId.of(10L), OFPort.of(1), new Date()); Entity entity3 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(3), IPv4Address.NONE, IPv6Address.NONE, DatapathId.of(1L), OFPort.of(1), new Date()); Entity entity4 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(42), IPv4Address.NONE, IPv6Address.NONE, DatapathId.of(1L), OFPort.of(1), new Date()); Entity[] entities = new Entity[] { entity1, entity2, entity3, entity4 }; Device d = new Device(null,1L, null, null, null, Arrays.asList(entities), null); SwitchPort swp1x1 = new SwitchPort(DatapathId.of(1L), OFPort.of(1)); SwitchPort swp1x2 = new SwitchPort(DatapathId.of(1L), OFPort.of(2)); SwitchPort swp2x1 = new SwitchPort(DatapathId.of(2L), OFPort.of(1)); SwitchPort swp10x1 = new SwitchPort(DatapathId.of(10L), OFPort.of(1)); assertArrayEquals(new VlanVid[] { VlanVid.ZERO, VlanVid.ofVlan(1)}, d.getSwitchPortVlanIds(swp10x1)); assertArrayEquals(new VlanVid[] { VlanVid.ofVlan(3), VlanVid.ofVlan(42)}, d.getSwitchPortVlanIds(swp1x1)); assertArrayEquals(new VlanVid[0], d.getSwitchPortVlanIds(swp1x2)); assertArrayEquals(new VlanVid[0], d.getSwitchPortVlanIds(swp2x1)); }
@Override protected void setUp() throws Exception { super.setUp(); e1a = new Entity(MacAddress.of(1L), VlanVid.ofVlan(1), IPv4Address.of(1), IPv6Address.of(1, 1), DatapathId.of(1L), OFPort.of(1), new Date()); e1b = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(1), IPv6Address.of(1, 1), DatapathId.of(1L), OFPort.of(1), new Date()); List<Entity> d1Entities = new ArrayList<Entity>(2); d1Entities.add(e1a); d1Entities.add(e1b); d1 = new Device(null, Long.valueOf(1), null, null, null, d1Entities, null); // e2 and e2 alt match in MAC and VLAN e2 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(2), IPv6Address.of(2, 2), DatapathId.of(2L), OFPort.of(2), new Date()); e2alt = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.NONE, IPv6Address.NONE, DatapathId.NONE, OFPort.ZERO, Entity.NO_DATE); // IP is null e3 = new Entity(MacAddress.of(3L), VlanVid.ofVlan(3), IPv4Address.NONE, IPv6Address.NONE, DatapathId.of(3L), OFPort.of(3), new Date()); // IP and switch and port are null e4 = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), IPv4Address.NONE, IPv6Address.NONE, DatapathId.NONE, OFPort.ZERO, new Date()); }
/** * Learn a device using the given characteristics. * @param macAddress the MAC * @param vlan the VLAN (can be VlanVid.ZERO for untagged) * @param ipv4Address the IPv4 (can be IPv4Address.NONE) * @param ipv6Address the IPv6 (can be IPv6Address.NONE) * @param switchDPID the attachment point switch DPID (can be DatapathId.NONE) * @param switchPort the attachment point switch port (can be OFPort.ZERO) * @param processUpdates if false, will not send updates. Note that this * method is not thread safe if this is false * @return the device, either new or not */ public IDevice learnEntity(MacAddress macAddress, VlanVid vlan, IPv4Address ipv4Address, IPv6Address ipv6Address, DatapathId switchDPID, OFPort switchPort, boolean processUpdates) { List<IDeviceListener> listeners = deviceListeners.getOrderedListeners(); if (!processUpdates) { deviceListeners.clearListeners(); } /* Entity will enforce all but VLAN be non-null */ IDevice res = learnDeviceByEntity(new Entity(macAddress, vlan, ipv4Address, ipv6Address, switchDPID, switchPort, new Date())); // Restore listeners if (listeners != null) { for (IDeviceListener listener : listeners) { deviceListeners.addListener("device", listener); } } return res; }
@Test public void testSerializeWithoutPayload() { byte[] expected = new byte[] { 0x64, 0x2B, 0x16, (byte) 0x95, 0x00, 0x00, 0x11, (byte) 0xE1, (byte) 0xFE, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, (byte) 0xC5, (byte) 0xFF, (byte) 0xFE, 0x2E, 0x77, 0x35, (byte) 0xFE, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x5D, (byte) 0xFF, (byte) 0xFE, (byte) 0xC2, 0x30, (byte) 0xFD }; IPv6 packet = (new IPv6()) .setTrafficClass((byte) 0x42) .setFlowLabel(0xB1695) .setPayloadLength((short) 0) .setNextHeader(IpProtocol.of((short) 0x11)) .setHopLimit((byte) 0xE1) .setSourceAddress(IPv6Address.of("fe80::7a:c5ff:fe2e:7735")) .setDestinationAddress(IPv6Address.of("fe80::77:5dff:fec2:30fd")); byte[] actual = packet.serialize(); assertTrue(Arrays.equals(expected, actual)); }
public static void main(String []args){ IPv6Address srcAddr = IPv6Address.of(11L, 11L); IPv6Address dstAddr = IPv6Address.of(12L,12L); TransportPort srcPort = TransportPort.of(11); TransportPort dstPort = TransportPort.of(12); //int prot = 67; IpProtocol prot = IpProtocol.of((byte)67); byte tos = 1; int input= 1 ; int pkts=1212; int octs=123123; long first=System.currentTimeMillis(); long last= System.currentTimeMillis(); byte tcpflags= 11; int drops= 1223; int type =2;//因为何种原因而不再活跃 long timestamp= System.currentTimeMillis();// FlowPersistence f = new FlowPersistence(srcAddr,dstAddr,srcPort,dstPort,prot,tos,input,pkts ,octs,first,last,tcpflags,drops,type,timestamp); FlowStatisticsDAO fsDAO = new FlowStatisticsDAOImpl(); fsDAO.insertFlow(f); }
public FlowRecord(IPv6Address srcAddr, IPv6Address dstAddr, TransportPort srcPort, TransportPort dstPort, IpProtocol prot, byte tos, int input, int pkts, int octs, long first, long last, byte tcpflags, int drops, int type, long timestamp) { this.srcAddr = srcAddr; this.dstAddr = dstAddr; this.srcPort = srcPort; this.dstPort = dstPort; this.prot = prot; this.tos = tos; this.input = input; this.pkts = pkts; this.octs = octs; this.first = first; this.last = last; this.tcpflags = tcpflags; this.drops = drops; this.type = type; this.timestamp = timestamp; }
@Override public IPv6Address[] getIPv6Addresses() { TreeSet<IPv6Address> vals = new TreeSet<IPv6Address>(); for (Entity e : entities) { if (e.getIpv6Address().equals(IPv6Address.NONE)) continue; // We have an IP address only if among the devices within the class // we have the most recent entity with that IP. boolean validIP = true; Iterator<Device> devices = deviceManager.queryClassByEntity( entityClass, ipv6Fields, e); while (devices.hasNext()) { Device d = devices.next(); if (deviceKey.equals(d.getDeviceKey())) continue; for (Entity se : d.entities) { if (se.getIpv6Address() != null && se.getIpv6Address().equals(e.getIpv6Address()) && !se.getLastSeenTimestamp() .equals(Entity.NO_DATE) && 0 < se.getLastSeenTimestamp().compareTo( e.getLastSeenTimestamp())) { validIP = false; break; } } if (!validIP) break; } if (validIP) vals.add(e.getIpv6Address()); } return vals.toArray(new IPv6Address[vals.size()]); }
@Override public IDevice findDevice(@Nonnull MacAddress macAddress, VlanVid vlan, @Nonnull IPv4Address ipv4Address, @Nonnull IPv6Address ipv6Address, @Nonnull DatapathId switchDPID, @Nonnull OFPort switchPort) throws IllegalArgumentException { if (macAddress == null) { throw new IllegalArgumentException("MAC address cannot be null. Try MacAddress.NONE if intention is 'no MAC'"); } if (ipv4Address == null) { throw new IllegalArgumentException("IPv4 address cannot be null. Try IPv4Address.NONE if intention is 'no IPv4'"); } if (ipv6Address == null) { throw new IllegalArgumentException("IPv6 address cannot be null. Try IPv6Address.NONE if intention is 'no IPv6'"); } if (vlan == null) { throw new IllegalArgumentException("VLAN cannot be null. Try VlanVid.ZERO if intention is 'no VLAN / untagged'"); } if (switchDPID == null) { throw new IllegalArgumentException("Switch DPID cannot be null. Try DatapathId.NONE if intention is 'no DPID'"); } if (switchPort == null) { throw new IllegalArgumentException("Switch port cannot be null. Try OFPort.ZERO if intention is 'no port'"); } Entity e = new Entity(macAddress, vlan, ipv4Address, ipv6Address, switchDPID, switchPort, Entity.NO_DATE); /* * allKeyFieldsPresent() will check if the entity key fields (e.g. MAC and VLAN) * have non-"zero" values i.e. are not set to e.g. MacAddress.NONE and VlanVid.ZERO */ if (!allKeyFieldsPresent(e, entityClassifier.getKeyFields())) { throw new IllegalArgumentException("Not all key fields specified." + " Required fields: " + entityClassifier.getKeyFields()); } return findDeviceByEntity(e); }
@Override public IDevice findClassDevice(@Nonnull IEntityClass entityClass, @Nonnull MacAddress macAddress, @Nonnull VlanVid vlan, @Nonnull IPv4Address ipv4Address, @Nonnull IPv6Address ipv6Address) throws IllegalArgumentException { if (entityClass == null) { throw new IllegalArgumentException("Entity class cannot be null."); } if (macAddress == null) { throw new IllegalArgumentException("MAC address cannot be null. Try MacAddress.NONE if intention is 'no MAC'"); } if (ipv4Address == null) { throw new IllegalArgumentException("IPv4 address cannot be null. Try IPv4Address.NONE if intention is 'no IPv4'"); } if (ipv6Address == null) { throw new IllegalArgumentException("IPv6 address cannot be null. Try IPv6Address.NONE if intention is 'no IPv6'"); } if (vlan == null) { throw new IllegalArgumentException("VLAN cannot be null. Try VlanVid.ZERO if intention is 'no VLAN / untagged'"); } Entity e = new Entity(macAddress, vlan, ipv4Address, ipv6Address, DatapathId.NONE, OFPort.ZERO, Entity.NO_DATE); if (!allKeyFieldsPresent(e, entityClass.getKeyFields())) { throw new IllegalArgumentException("Not all key fields and/or " + " no source device specified. Required fields: " + entityClassifier.getKeyFields()); } return findDestByEntity(entityClass, e); }
/** * Get sender IPv6 address from packet if the packet is ND * * @param eth * @param dlAddr * @return */ private IPv6Address getSrcIPv6Addr(Ethernet eth) { if (eth.getPayload() instanceof IPv6) { IPv6 ipv6 = (IPv6) eth.getPayload(); return ipv6.getSourceAddress(); } return IPv6Address.NONE; }
/** * Learn device from ARP data in scenarios where the * Ethernet source MAC is different from the sender hardware * address in ARP data. */ protected void learnDeviceFromArpResponseData(Ethernet eth, DatapathId swdpid, OFPort port) { if (!(eth.getPayload() instanceof ARP)) return; ARP arp = (ARP) eth.getPayload(); MacAddress dlAddr = eth.getSourceMACAddress(); MacAddress senderAddr = arp.getSenderHardwareAddress(); if (dlAddr.equals(senderAddr)) return; // arp request // Ignore broadcast/multicast source if (senderAddr.isBroadcast() || senderAddr.isMulticast()) return; // Ignore zero sender mac if (senderAddr.equals(MacAddress.of(0))) return; VlanVid vlan = VlanVid.ofVlan(eth.getVlanID()); IPv4Address nwSrc = arp.getSenderProtocolAddress(); Entity e = new Entity(senderAddr, vlan, /* will either be a valid tag or VlanVid.ZERO if untagged */ nwSrc, IPv6Address.NONE, /* must be none for ARP */ swdpid, port, new Date()); learnDeviceByEntity(e); }
/** * Get a (partial) entity for the destination from the packet. * @param eth * @return */ protected Entity getDestEntityFromPacket(Ethernet eth) { MacAddress dlAddr = eth.getDestinationMACAddress(); VlanVid vlan = VlanVid.ofVlan(eth.getVlanID()); IPv4Address ipv4Dst = IPv4Address.NONE; IPv6Address ipv6Dst = IPv6Address.NONE; // Ignore broadcast/multicast destination if (dlAddr.isBroadcast() || dlAddr.isMulticast()) return null; // Ignore zero dest mac if (dlAddr.equals(MacAddress.of(0))) return null; if (eth.getPayload() instanceof IPv4) { IPv4 ipv4 = (IPv4) eth.getPayload(); ipv4Dst = ipv4.getDestinationAddress(); } else if (eth.getPayload() instanceof IPv6) { IPv6 ipv6 = (IPv6) eth.getPayload(); ipv6Dst = ipv6.getDestinationAddress(); } return new Entity(dlAddr, vlan, ipv4Dst, ipv6Dst, DatapathId.NONE, OFPort.ZERO, Entity.NO_DATE); }
/** * Check if the entity e has all the keyFields set. Returns false if not * @param e entity to check * @param keyFields the key fields to check e against * @return */ protected boolean allKeyFieldsPresent(Entity e, EnumSet<DeviceField> keyFields) { for (DeviceField f : keyFields) { switch (f) { case MAC: // MAC address is always present break; case IPv4: case IPv6: if (e.ipv4Address.equals(IPv4Address.NONE) && e.ipv6Address.equals(IPv6Address.NONE)) { return false; // mutually exclusive } break; case SWITCH: if (e.switchDPID.equals(DatapathId.NONE)) { return false; } break; case PORT: if (e.switchPort.equals(OFPort.ZERO)) { return false; } break; case VLAN: if (e.vlan == null) { /* VLAN is null for 'don't care' or 'unspecified'. It's VlanVid.ZERO for untagged. */ return false; /* For key field of VLAN, the VLAN **MUST** be set to either ZERO or some value. */ } break; default: // we should never get here. unless somebody extended // DeviceFields throw new IllegalStateException(); } } return true; }
private EnumSet<DeviceField> getEntityKeys(@Nonnull MacAddress macAddress, VlanVid vlan, /* A null VLAN means 'don't care'; VlanVid.ZERO means 'untagged' */ @Nonnull IPv4Address ipv4Address, @Nonnull IPv6Address ipv6Address, @Nonnull DatapathId switchDPID, @Nonnull OFPort switchPort) { EnumSet<DeviceField> keys = EnumSet.noneOf(DeviceField.class); if (!macAddress.equals(MacAddress.NONE)) keys.add(DeviceField.MAC); if (vlan != null) keys.add(DeviceField.VLAN); /* TODO verify fix. null means 'don't care' and will conduct full search; VlanVid.ZERO means 'untagged' and only uses untagged index */ if (!ipv4Address.equals(IPv4Address.NONE)) keys.add(DeviceField.IPv4); if (!ipv6Address.equals(IPv6Address.NONE)) keys.add(DeviceField.IPv6); if (!switchDPID.equals(DatapathId.NONE)) keys.add(DeviceField.SWITCH); if (!switchPort.equals(OFPort.ZERO)) keys.add(DeviceField.PORT); return keys; }
public DeviceEvent(MacAddress macAddress, List<IPv4Address> ipv4Addresses, List<IPv6Address> ipv6Addresses, List<SwitchPort> oldAttachmentPoints, List<SwitchPort> currentAttachmentPoints, List<VlanVid> vlanIds, String reason) { super(); this.macAddress = macAddress; this.ipv4Addresses = ipv4Addresses; this.ipv6Addresses = ipv6Addresses; this.oldAttachmentPoints = oldAttachmentPoints; this.currentAttachmentPoints = currentAttachmentPoints; this.vlanIds = vlanIds; this.reason = reason; }
/** * Create a new entity * * @param macAddress * @param vlan * @param ipv4Address * @param ipv6Address * @param switchDPID * @param switchPort * @param lastSeenTimestamp */ public Entity(@Nonnull MacAddress macAddress, VlanVid vlan, @Nonnull IPv4Address ipv4Address, @Nonnull IPv6Address ipv6Address, @Nonnull DatapathId switchDPID, @Nonnull OFPort switchPort, @Nonnull Date lastSeenTimestamp) { if (macAddress == null) { throw new IllegalArgumentException("MAC address cannot be null. Try MacAddress.NONE if intention is 'no MAC'"); } if (ipv4Address == null) { throw new IllegalArgumentException("IPv4 address cannot be null. Try IPv4Address.NONE if intention is 'no IPv4'"); } if (ipv6Address == null) { throw new IllegalArgumentException("IPv6 address cannot be null. Try IPv6Address.NONE if intention is 'no IPv6'"); } /* VLAN can be null for 'don't care' in query searches */ if (switchDPID == null) { throw new IllegalArgumentException("Switch DPID cannot be null. Try DatapathId.NONE if intention is 'no DPID'"); } if (switchPort == null) { throw new IllegalArgumentException("Switch port cannot be null. Try OFPort.ZERO if intention is 'no port'"); } if (lastSeenTimestamp == null) { throw new IllegalArgumentException("Last seen time stamp cannot be null. Try Entity.NO_DATE if intention is 'no time'"); } this.macAddress = macAddress; this.ipv4Address = ipv4Address; this.ipv6Address = ipv6Address; this.vlan = vlan; this.switchDPID = switchDPID; this.switchPort = switchPort; this.lastSeenTimestamp = lastSeenTimestamp; this.activeSince = lastSeenTimestamp; }
public Entity asEntity() { Entity e = new Entity(MacAddress.of(macAddress), VlanVid.ofVlan(vlan), IPv4Address.of(ipv4Address), IPv6Address.NONE, DatapathId.of(switchDPID), OFPort.of(switchPort), lastSeenTimestamp); e.setActiveSince(activeSince); return e; }