package org.opennaas.extensions.opendaylight.vtn.capability; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.ws.rs.core.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.opennaas.core.resources.protocol.ProtocolException; import org.opennaas.core.resources.protocol.ProtocolSessionContext; import org.opennaas.extensions.opendaylight.vtn.model.Boundary; import org.opennaas.extensions.opendaylight.vtn.model.BoundaryMap; import org.opennaas.extensions.opendaylight.vtn.model.Link; import org.opennaas.extensions.opendaylight.vtn.model.OpenDaylightController; import org.opennaas.extensions.opendaylight.vtn.model.OpenDaylightvBridge; import org.opennaas.extensions.opendaylight.vtn.model.PortMap; import org.opennaas.extensions.opendaylight.vtn.model.Switch; import org.opennaas.extensions.opendaylight.vtn.model.VTN; import org.opennaas.extensions.opendaylight.vtn.model.vBridgeInterfaces; import org.opennaas.extensions.opendaylight.vtn.model.vLink; import org.opennaas.extensions.opendaylight.vtn.protocol.OpenDaylightProtocolSession; import org.opennaas.extensions.opendaylight.vtn.protocol.OpenDaylightProtocolSessionFactory; import org.opennaas.extensions.opendaylight.vtn.protocol.client.IOpenDaylightvtnAPIClient; import org.opennaas.extensions.opendaylight.vtn.protocol.client.wrappers.BoundaryWrapper; import org.opennaas.extensions.opendaylight.vtn.protocol.client.wrappers.LogicalPortsOFFlowsWrapper; import org.opennaas.extensions.opendaylight.vtn.protocol.client.wrappers.SwitchesWrapper; import org.opennaas.extensions.opendaylight.vtn.protocol.client.wrappers.vBridgeInterfacesWrapper; import org.opennaas.extensions.opendaylight.vtn.protocol.client.wrappers.vBridgesWrapper; import org.opennaas.extensions.opendaylight.vtn.protocol.client.wrappers.vLinksWrapper; //import org.opennaas.extensions.openflowswitch.utils.Utils; /** * * @author Josep Batallé (josep.batalle@i2cat.net) * */ public class VTNCapability implements IVTNCapability { Log log = LogFactory.getLog(VTNCapability.class); ProtocolSessionContext context; OpenDaylightProtocolSession session; IOpenDaylightvtnAPIClient client; private static final String SESSION_ID = "0001"; // private String PROTOCOL_URI = "http://192.168.254.72:8083/"; private String PROTOCOL_URI = "http://84.88.40.153:8083/"; private VTN vtn; private List<OpenDaylightController> controllers = new ArrayList<OpenDaylightController>(); private List<Boundary> boundaries = new ArrayList<Boundary>(); private Map<vBridgeInterfaces, String> mapPorts; public VTNCapability() { context = generateContext(); try { session = (OpenDaylightProtocolSession) new OpenDaylightProtocolSessionFactory().createProtocolSession(SESSION_ID, context); session.connect(); client = session.getOpenDaylightClientForUse(); } catch (ProtocolException ex) { Logger.getLogger(VTNCapability.class.getName()).log(Level.SEVERE, null, ex); } initConfig(); } private ProtocolSessionContext generateContext() { context = new ProtocolSessionContext(); context.addParameter(ProtocolSessionContext.PROTOCOL, OpenDaylightProtocolSession.OPENDAYLIGHT_PROTOCOL_TYPE); context.addParameter(ProtocolSessionContext.PROTOCOL_URI, PROTOCOL_URI); context.addParameter(ProtocolSessionContext.AUTH_TYPE, "noauth"); return context; } private void initConfig() { vtn = new VTN("vtn1"); Response response = createVTN(vtn.getVtn_name()); if (response.getEntity().equals("VTN is not accessible")) { log.error("VTN is not accesible, change the IP address"); return; } // String ctrl1_IP = "192.168.254.156"; // String ctrl2_IP = "192.168.254.221"; String ctrl1_IP = "84.88.36.100"; String ctrl2_IP = "84.88.41.171"; createController("ctrl1", ctrl1_IP, "odc", "floodlight"); createController("ctrl2", ctrl2_IP, "odc", "opendaylight"); OpenDaylightController ctrl1 = new OpenDaylightController("ctrl1", ctrl1_IP, "odc", "1.0", "enable", "floodlight"); controllers.add(ctrl1); ctrl1 = new OpenDaylightController("ctrl2", ctrl2_IP, "odc", "1.0", "enable", ""); controllers.add(ctrl1); log.error("Register Bridges"); vBridgesWrapper vbrs = getvBridges(vtn.getVtn_name());//get list if (vbrs.size() > 0) { for (OpenDaylightvBridge vbr : vbrs) { vtn.getvBridges().add(getvBridge(vtn.getVtn_name(), vbr.getVbr_name())); } } else { log.error("Creating vBridges"); createvBridge(vtn.getVtn_name(), "vbr1", controllers.get(0).getController_id(), "DEFAULT"); createvBridge(vtn.getVtn_name(), "vbr2", controllers.get(1).getController_id(), "DEFAULT"); } log.error("Register interfaces..."); updateInterfaces(); log.error("Creating boundary"); BoundaryWrapper bds = getBoundaries();//get list if (bds.size() > 0) { for (Boundary bound : bds) { boundaries.add(getBoundary(bound.getBoundary_id())); } } else { String borderPort1 = "PP-OF:00:00:64:87:88:58:f8:57-ge-1/0/3.0"; String borderPort2 = "PP-OF:00:00:00:00:00:00:00:03-eth1"; createBoundary("b1", controllers.get(0).getController_id(), "DEFAULT", borderPort1, controllers.get(1).getController_id(), "DEFAULT", borderPort2); } log.error("Creating vLinks"); vLinksWrapper vLinks = getvLinks(vtn.getVtn_name());//get list if (vLinks.size() > 0) { for (vLink vlk : vLinks) { vtn.getVlink().add(getvLink(vtn.getVtn_name(), vlk.getVlk_name())); } } else { createvLink(vtn.getVtn_name(), "vlink1", "vbr1", "if1", "vbr2", "if1", "b1", "50"); } log.error("------------- VTN summary -------------"); log.error("List of vbr (" + vtn.getvBridges().size() + ")"); for (OpenDaylightvBridge vbr : vtn.getvBridges()) { log.error("In vBridge " + vbr.getVbr_name() + ". List of ifaces (" + vbr.getIface().size() + ")"); } log.error("Number of vLinks: " + vtn.getVlink().size()); if (vtn.getVlink().size() > 0) { log.error("vLink: " + vtn.getVlink().get(0).getVlk_name() + " " + vtn.getVlink().get(0).getVnode1_name()); log.error("vLinkCont.: " + vtn.getVlink().get(0).getVnode2_name() + " " + vtn.getVlink().get(0).getBoundaryMap().getBoundary_id()); } log.error("Assign each iface to a physical port..."); checkPortMap(); } @Override public Response createVTN(String name) { log.info("Create VTN " + name); vtn = new VTN(name); Response response; try { response = client.createVTN(vtn); } catch (Exception e) { response = Response.ok("VTN is not accessible").build(); } return response; } @Override public Response removeVTN(String name) { return client.deleteVTN(name); } @Override public Response coordinatorAddress(String address, String port) { PROTOCOL_URI = "http://" + address + ":" + port; generateContext(); return Response.ok().build(); } @Override public Response createController(String name, String ipaddr, String type, String description) { OpenDaylightController ctrl = new OpenDaylightController(name, ipaddr, type, "1.0", "enable", description); Response response = client.createController(ctrl); log.error("Response "+response.getStatus()); if (response.getStatus() == Response.Status.CREATED.getStatusCode()) { controllers.add(ctrl); } return response; } @Override public Response createvBridge(String vtn_name, String name, String ctrl, String domain) { OpenDaylightvBridge vBridge = new OpenDaylightvBridge(name, ctrl, domain); Response response = client.createvBridge(vtn_name, vBridge); log.error("Response "+response.getStatus()); if (response.getStatus() == Response.Status.CREATED.getStatusCode()) { vtn.getvBridges().add(vBridge); } return response; } @Override public Response createInterfaces(String vtn_name, String vBridge, String iface) { vBridgeInterfaces inf = new vBridgeInterfaces(iface); Response response = client.createInterfaces(vtn_name, vBridge, inf); log.error("Create iface?: " + response.getStatus()); if (response.getStatus() == Response.Status.CREATED.getStatusCode()) { for (OpenDaylightvBridge vbr : vtn.getvBridges()) { if (vbr.getVbr_name().equals(vBridge)) { vbr.getIface().add(inf); } } } return response; } @Override public Response createBoundary(String id, String ctrl1, String domain1, String port1, String ctrl2, String domain2, String port2) { Boundary bound = new Boundary(id, new Link(ctrl1, domain1, port1, ctrl2, domain2, port2)); Response response = client.createBoundary(bound); if (response.getStatus() == Response.Status.CREATED.getStatusCode()) { boundaries.add(bound); } return response; } @Override public Response createvLink(String vtnName, String vlinkName, String vnode1, String if1, String vnode2, String if2, String boundId, String vlanId) { vLink vlink = new vLink(vlinkName, vnode1, if1, vnode2, if2, new BoundaryMap(boundId, vlanId)); Response response = client.createvLink(vtnName, vlink); if (response.getStatus() == Response.Status.CREATED.getStatusCode()) { if (!vtn.getVlink().contains(vlink)) { vtn.getVlink().add(vlink); } } return response; } @Override public Response mapPort(String vtnName, String vBridge, String iface, String port) { PortMap portMap = new PortMap(); portMap.setLogical_port_id(port); return client.configPortMap(vtnName, vBridge, iface, portMap); } @Override public Response ipreq(String DPID, String Port) { log.error("Requested route in VRF. Trying to map the ODL ports."); log.error("Req. information: " + DPID + " mapPort: " + Port); Response response; if (vtn == null) { return Response.status(500).entity("VTN no exists. Please create a VTN").build(); } if (Port == null) { return Response.accepted("Error. Destination port is null").build(); } String dstSw_num = DPID.substring(DPID.length() - 1); String outPort = "PP-OF:" + DPID + "-s" + dstSw_num + "-eth" + Port; // port = "PP-OF:00:00:00:00:00:00:00:05-s5-eth2"; String iface = "if2"; String vbrName = getvBridgeOfSwitch(DPID); for (vBridgeInterfaces inf : vtn.getvBridge(vbrName).getIface()) { // client.configPortMap(vtn.getVtn_name(), vbrName, inf.getIf_name()); for (PortMap pm : inf.getPortMaps()) { if (pm.getLogical_port_id() != null) { if (pm.getLogical_port_id().equals(outPort)) { iface = inf.getIf_name(); log.error("Set Iface: " + iface); break; } } } } if (vtn.getvBridge(vbrName).getIface().size() == 1) { createInterfaces(vtn.getVtn_name(), vbrName, iface); } log.error("iface: " + iface + " Port: " + outPort); response = mapPort(vtn.getVtn_name(), vbrName, iface, outPort); log.error("HTTP Code of ODL VTN - portMap: " + response.getStatus()); return response; } @Override public PortMap mapPort(String vtnName, String vBridge, String iface) { return client.configPortMap(vtnName, vBridge, iface); } @Override public LogicalPortsOFFlowsWrapper getLogicalPorts(String ctrl, String domain) { log.error("Get Logical Ports of ctrl " + ctrl + "and domain " + domain); LogicalPortsOFFlowsWrapper lp = client.getLogicalPorts(ctrl, "(" + domain + ")"); return lp; } /** * Analyze the vbr of OpenNaaS and assign the mapping(port-interface) of * each interface that contains each vbridge */ @Override public void checkPortMap() { log.error("Assing Port-Map Interface of each vBridge"); //for each vBridge and each interface check the mapping port PortMap pMap; for (OpenDaylightvBridge vbr : vtn.getvBridges()) { for (vBridgeInterfaces inf : vbr.getIface()) { pMap = client.configPortMap(vtn.getVtn_name(), vbr.getVbr_name(), inf.getIf_name()); inf.getPortMaps().add(pMap); log.error("Iface " + inf.getIf_name() + " from " + vbr.getVbr_name() + ". AddingMap " + pMap.getLogical_port_id()); } } } @Override public OpenDaylightvBridge getvBridge(String vtnName, String vBridge) { OpenDaylightvBridge vbr = client.getvBridge(vtnName, vBridge); return vbr; } @Override public vBridgesWrapper getvBridges(String vtnName) { vBridgesWrapper vbrs = client.getvBridges("vtn1"); return vbrs; } @Override public vBridgeInterfacesWrapper getInterfaces(String vtnName, String vBridge) { vBridgeInterfacesWrapper ifaces = client.getInterfaces(vtnName, vBridge); return ifaces; } @Override public Boundary getBoundary(String bound) { return client.getBoundary(bound); } @Override public BoundaryWrapper getBoundaries() { return client.getBoundaries(); } @Override public vLink getvLink(String vtnName, String bound) { return client.getvLink(vtnName, bound); } @Override public vLinksWrapper getvLinks(String vtnName) { return client.getvLinks(vtnName); } private int getNumInts(String controller_id) { LogicalPortsOFFlowsWrapper resp = getLogicalPorts(controller_id, "DEFAULT"); log.error(resp.size()); return resp.size(); } @Override public void updateInterfaces() { vBridgeInterfacesWrapper ifaces; for (OpenDaylightvBridge vbr : vtn.getvBridges()) { ifaces = getInterfaces(vtn.getVtn_name(), vbr.getVbr_name()); log.error("Get Interfaces. Ifaces bridge "+vbr.getVbr_name()+": " + ifaces.size()); if (ifaces.size() > 0) { for (vBridgeInterfaces iface : ifaces) { vbr.getIface().add(iface); } } else { log.error("Creating interfaces of vBridge " + vbr.getVbr_name()); // List<vBridgeInterfaces> ints = getPossibleInts(vbr.getVbr_name(), vbr.getController_id()); if (getODLController(vbr.getController_id()).getDescription().equals("floodlight")) { createInterfaces(vtn.getVtn_name(), vbr.getVbr_name(), "if1"); } else { int numInt = getNumInts(vbr.getController_id()); createInterfaces(vtn.getVtn_name(), vbr.getVbr_name(), "if1"); log.error("Number of possible interfaces of vBridge " + vbr.getVbr_name()); for (int i = 1; i < numInt; i++) { String ifName = "if" + (i + 1); createInterfaces(vtn.getVtn_name(), vbr.getVbr_name(), ifName); } } } } } @Override public void update() { vtn = new VTN("vtn1"); controllers = new ArrayList<OpenDaylightController>(); boundaries = new ArrayList<Boundary>(); initConfig(); } @Override public void cleanVTN() { client.deleteVTN("vtn1"); client.deleteBoundary("b1"); } private OpenDaylightController getODLController(String controller_id) { for (OpenDaylightController ctrl : controllers) { if (ctrl.getController_id().equals(controller_id)) { return ctrl; } } return null; } private String getvBridgeOfSwitch(String DPID) { String vbrName = "vbr2"; for (OpenDaylightvBridge vB : vtn.getvBridges()) { SwitchesWrapper listSw = client.getListSwitchs(vB.getController_id()); for (Switch sw : listSw) { if (sw.getSwitch_id().equals(DPID)) { return vB.getVbr_name(); } } } return vbrName; } }