// (c) Copyright 2013 Hewlett-Packard Development Company, L.P. // Autogenerated package com.mango.hm.impl; import java.util.UUID; import static com.hp.util.StringUtils.isEmpty; import com.mango.hm.model.DeviceHealth; import com.mango.hm.api.DeviceHealthService; import com.hp.api.NotFoundException; import java.util.EnumSet; import java.util.Map; import java.util.HashMap; import java.util.Collection; import java.util.Collections; import java.util.UUID; import com.hp.api.Id; import com.hp.of.ctl.ControllerService; import com.hp.of.ctl.DataPathEvent; import com.hp.of.ctl.DataPathListener; import com.hp.of.ctl.ErrorEvent; import com.hp.of.ctl.OpenflowEventType; import com.hp.of.ctl.QueueEvent; import com.hp.of.ctl.pkt.MessageContext; import com.hp.of.ctl.pkt.PacketListenerRole; import com.hp.of.ctl.pkt.SequencedPacketListener; import com.hp.of.lib.OpenflowException; import com.hp.of.lib.ProtocolVersion; import com.hp.of.lib.dt.BufferId; import com.hp.of.lib.instr.ActOutput; import com.hp.of.lib.instr.Action; import com.hp.of.lib.instr.ActionType; import com.hp.of.lib.msg.MessageFactory; import com.hp.of.lib.msg.MessageType; import com.hp.of.lib.msg.OfmMutablePacketOut; import com.hp.of.lib.msg.OfmPacketOut; import com.hp.util.ip.BigPortNumber; import com.hp.util.ip.EthernetType; import com.hp.util.ip.MacAddress; import com.hp.util.pkt.Arp; import com.hp.util.pkt.Arp.OpCode; import com.hp.util.pkt.Codec; import com.hp.util.pkt.Ethernet; import com.hp.util.pkt.Packet; import com.hp.util.pkt.ProtocolId; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.ReferencePolicy; import org.apache.felix.scr.annotations.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static com.hp.of.lib.instr.ActionFactory.createAction; /** * Sample DeviceHealth service implementation. */ @Component(metatype=true) @Service public class DeviceHealthManager implements DeviceHealthService { private final SequencedPacketListener arpDirector = new ArpAdvisor(); private final DataPathListener dpListener = new DpListener(); @Reference(name = "ControllerService", cardinality = ReferenceCardinality.MANDATORY_UNARY, policy = ReferencePolicy.DYNAMIC) private volatile ControllerService cs = null; MacAddress PROXY_ARP_MAC = MacAddress.valueOf("AC:16:2D:57:F8:D3"); int ALTITUDE = Integer.MAX_VALUE; private static final Logger log = LoggerFactory.getLogger(DeviceHealthManager.class); // Just for kicks in-memory store. private static final Map, DeviceHealth> store = new HashMap, DeviceHealth>(); /** * Registers ControllerService implementation via declarative service. * * @param ctlrServices the service being made available */ protected void bindControllerService(ControllerService ctlrServices) { cs = ctlrServices; init(); } @Activate void activate(Map properties) { log.info("ACTIVATE PROXY-ARP APP"); } private void init() { EnumSet pktInterest = EnumSet.of(ProtocolId.ARP, ProtocolId.IP); cs.addDataPathListener(dpListener); cs.addPacketListener(arpDirector, PacketListenerRole.DIRECTOR, ALTITUDE, pktInterest); } /** * Unregisters ControllerService implementation via declarative service. * * @param ctlrServices the service that is being revoked */ protected void unbindControllerService(ControllerService ctlrServices) { if (ctlrServices == cs) { cs.removePacketListener(arpDirector); cs = null; } } @Override public Collection getAll() { synchronized (store) { return Collections.unmodifiableCollection(store.values()); } } @Override public DeviceHealth create(String name) { synchronized (store) { DeviceHealth s = new DeviceHealth(name); if(isEmpty(s.name())){ s.setName("DeviceHealth-" + s.getId().getValue().toString()); } store.put(s.getId(), s); return s; } } @Override public DeviceHealth get(Id id) { synchronized (store) { DeviceHealth s = store.get(id); if (s == null) throw new NotFoundException("DeviceHealth with id " + id + " not found"); return s; } } @Override public void delete(Id id) { synchronized (store) { DeviceHealth s = store.remove(id); if (s == null) throw new NotFoundException("DeviceHealth with id " + id + " not found"); } } /** PROXY-ARP start * * @author HP * */ private class ArpAdvisor implements SequencedPacketListener { @Override public void errorEvent(ErrorEvent arg0) { } @Override public boolean event(MessageContext msgContxt) { log.info("PROXY-ARP APP : PKTIN_EVENT"); Packet pkt = msgContxt.decodedPacket(); if (pkt.has(ProtocolId.ARP)) { Arp arpPacket = pkt.get(ProtocolId.ARP); if (arpPacket.opCode().equals(OpCode.REQ)) { // create Arp-Reply Arp arpResponse = getArpResponse(arpPacket); // create Eth layer Ethernet ethLayer = new Ethernet.Builder() .srcAddr(PROXY_ARP_MAC) .dstAddr(arpPacket.senderMacAddr()) .type(EthernetType.ARP).build(); Packet pktSnd = new Packet(ethLayer, arpResponse); log.info("PROXY-ARP APP sending ARP packet response{}", pktSnd.toDebugString()); // create pktOut OfmPacketOut pktOut = getArpPktOut(msgContxt.getVersion(), pktSnd, msgContxt.getPacketIn() .getInPort()); try { cs.send(pktOut, msgContxt.srcEvent().dpid()); log.info("PROXY-ARP send ARP Reply success"); } catch (OpenflowException e) { // TODO Auto-generated catch block log.error("PROXY-ARP APP EXCEPTION!!"); e.printStackTrace(); } return true; } } log.info("PROXY-ARP APP IGNORING PKT_IN"); return false; } } private Arp getArpResponse(Arp arpIn) { Arp arpRespone = new Arp.Builder().opCode(OpCode.REPLY). senderIpAddr(arpIn.targetIpAddr()).hwType(arpIn.hwType()). senderMacAddr(PROXY_ARP_MAC). targetIpAddr(arpIn.senderIpAddr()). targetMacAddr(arpIn.senderMacAddr()).build(); return arpRespone; } private OfmPacketOut getArpPktOut(ProtocolVersion pv, Packet pkt, BigPortNumber inPort) { OfmMutablePacketOut pktOut = (OfmMutablePacketOut) MessageFactory. create(pv, MessageType.PACKET_OUT); pktOut.bufferId(BufferId.NO_BUFFER); pktOut.inPort(inPort); pktOut.data(Codec.encode(pkt)); Action outAction = createAction(pv, ActionType.OUTPUT, inPort, ActOutput.CONTROLLER_NO_BUFFER); pktOut.addAction(outAction); return (OfmPacketOut) pktOut.toImmutable(); } /** PROXY-ARP end * * @author HP * */ // Private Listener private class DpListener implements DataPathListener { @Override public void queueEvent(QueueEvent event) { } @Override public void event(DataPathEvent dpEvent) { OpenflowEventType type = dpEvent.type(); //process OpenFlow DataPath events switch (type) { case DATAPATH_CONNECTED: log.info("PROXY-ARP APP : DP_CONNECT"); break; case DATAPATH_DISCONNECTED: log.info("PROXY-ARP APP : DP_DISCONNECT"); break; default: break; } } } }