Changed configuration file format to separate 'interfaces' from BGP peers. Also implemented procative paths for BGP traffic within the SDN domain
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index 4b6e328..d3bb598 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -7,10 +7,8 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
@@ -21,6 +19,7 @@
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.devicemanager.IDeviceService;
 import net.floodlightcontroller.packet.Ethernet;
+import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.topology.ITopologyListener;
 import net.floodlightcontroller.topology.ITopologyService;
@@ -28,6 +27,7 @@
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
 import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
 import net.onrc.onos.ofcontroller.util.Port;
 import net.onrc.onos.ofcontroller.util.SwitchPort;
@@ -66,9 +66,7 @@
 	protected static Ptree ptree;
 	protected String bgpdRestIp;
 	protected String routerId;
-	protected String gatewaysFilename = "gateways.json";
-	
-	protected Set<InetAddress> routerIpAddresses;
+	protected String gatewaysFilename = "config.json";
 	
 	//We need to identify our flows somehow. But like it says in LearningSwitch.java,
 	//the controller/OS should hand out cookie IDs to prevent conflicts.
@@ -77,12 +75,22 @@
 	protected final long L2_FWD_COOKIE = APP_COOKIE + 1;
 	//Cookie for flows in ingress switches that rewrite the MAC address
 	protected final long MAC_RW_COOKIE = APP_COOKIE + 2;
+	//Cookie for flows that setup BGP paths
+	protected final long BGP_COOKIE = APP_COOKIE + 3;
 	//Forwarding uses priority 0, and the mac rewrite entries in ingress switches
 	//need to be higher priority than this otherwise the rewrite may not get done
 	protected final short SDNIP_PRIORITY = 10;
 	
+	protected final short BGP_PORT = 179;
+	
+	//Configuration stuff
 	protected Map<String, GatewayRouter> gatewayRouters;
 	protected List<String> switches;
+	protected Map<String, Interface> interfaces;
+	protected List<BgpPeer> bgpPeers;
+	//protected long bgpdAttachmentDpid;
+	//protected short bgpdAttachmentPort;
+	protected SwitchPort bgpdAttachmentPoint;
 	
 	//True when all switches have connected
 	protected volatile boolean switchesConnected = false;
@@ -98,10 +106,14 @@
 			
 			gatewayRouters = config.getGateways();
 			switches = config.getSwitches();
+			interfaces = config.getInterfaces();
+			bgpPeers = config.getPeers();
 			
-			for (String sw : switches){
-				log.debug("Switchjoin {}", sw);
-			}
+			bgpdAttachmentPoint = new SwitchPort(
+					new Dpid(config.getBgpdAttachmentDpid()),
+					new Port(config.getBgpdAttachmentPort()));
+			//bgpdAttachmentDpid = config.getBgpdAttachmentDpid();
+			//bgpdAttachmentPort = config.getBgpdAttachmentPort();
 			
 		} catch (JsonParseException e) {
 			log.error("Error in JSON file", e);
@@ -149,7 +161,7 @@
 	    
 	    ptree = new Ptree(32);
 	    
-	    routerIpAddresses = new HashSet<InetAddress>();
+	    //routerIpAddresses = new HashSet<InetAddress>();
 		
 		// Register floodlight provider and REST handler.
 		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
@@ -407,9 +419,6 @@
 	        
 	        match.setDataLayerSource(ingressRouter.getRouterMac().toBytes());
 	        match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
-	        
-	        //match.setDataLayerDestination(ingressRouter.getSdnRouterMac().toBytes());
-	        //match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
 
 	        InetAddress address = null;
 	        try {
@@ -429,7 +438,7 @@
 	        
 	        //Set up output action
 	        OFActionOutput outputAction = new OFActionOutput();
-	        outputAction.setMaxLength((short)0xffff); //TODO check what this is (and if needed for mac rewrite)
+	        outputAction.setMaxLength((short)0xffff);
 	        
 	        Port outputPort = shortestPath.flowEntries().get(0).outPort();
 	        outputAction.setPort(outputPort.value());
@@ -502,9 +511,6 @@
 	        match.setDataLayerSource(ingressRouter.getRouterMac().toBytes());
 	        match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
 	        
-	        //match.setDataLayerDestination(ingressRouter.getSdnRouterMac().toBytes());
-	        //match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
-
 	        InetAddress address = null;
 	        try {
 				address = InetAddress.getByAddress(node.key);
@@ -651,11 +657,137 @@
 		}
 	}
 	
+	private void setupBgpPaths(){
+		for (BgpPeer bgpPeer : bgpPeers){
+			Interface peerInterface = interfaces.get(bgpPeer.getInterfaceName());
+			
+			DataPath path = topoRouteService.getShortestPath(
+					peerInterface.getSwitchPort(), bgpdAttachmentPoint);
+			
+			if (path == null){
+				log.debug("Unable to compute path for BGP traffic for {}",
+							bgpPeer.getIpAddress());
+				continue;
+			}
+			
+			//Set up the flow mod
+			OFFlowMod fm =
+	                (OFFlowMod) floodlightProvider.getOFMessageFactory()
+	                                              .getMessage(OFType.FLOW_MOD);
+			
+	        OFActionOutput action = new OFActionOutput();
+	        action.setMaxLength((short)0xffff);
+	        List<OFAction> actions = new ArrayList<OFAction>();
+	        actions.add(action);
+	        
+	        fm.setIdleTimeout((short)0)
+	        .setHardTimeout((short)0)
+	        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+	        .setCookie(BGP_COOKIE)
+	        .setCommand(OFFlowMod.OFPFC_ADD)
+	        .setPriority(SDNIP_PRIORITY)
+	        .setActions(actions)
+	        .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+
+	        //Forward = gateway -> bgpd, reverse = bgpd -> gateway
+	        OFMatch forwardMatchSrc = new OFMatch();
+	        
+	        
+	        String interfaceCidrAddress = peerInterface.getIpAddress().getHostAddress() 
+	        					+ "/32";
+	        String peerCidrAddress = bgpPeer.getIpAddress().getHostAddress()
+	        					+ "/32";
+	        	        
+	        //Common match fields
+	        forwardMatchSrc.setDataLayerType(Ethernet.TYPE_IPv4);
+	        //forwardMatch.setWildcards(forwardMatch.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+	        forwardMatchSrc.setNetworkProtocol(IPv4.PROTOCOL_TCP);
+	        forwardMatchSrc.setTransportDestination(BGP_PORT);
+	        forwardMatchSrc.setWildcards(forwardMatchSrc.getWildcards() & ~OFMatch.OFPFW_IN_PORT
+	        				& ~OFMatch.OFPFW_DL_TYPE & ~OFMatch.OFPFW_NW_PROTO);
+	        
+	        
+	        OFMatch reverseMatchSrc = forwardMatchSrc.clone();
+	        
+	        forwardMatchSrc.setFromCIDR(peerCidrAddress, OFMatch.STR_NW_SRC);
+	        forwardMatchSrc.setFromCIDR(interfaceCidrAddress, OFMatch.STR_NW_DST);
+	        
+	        OFMatch forwardMatchDst = forwardMatchSrc.clone();
+	        
+	        forwardMatchSrc.setTransportSource(BGP_PORT);
+	        forwardMatchSrc.setWildcards(forwardMatchSrc.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
+	        forwardMatchDst.setTransportDestination(BGP_PORT);
+	        forwardMatchDst.setWildcards(forwardMatchDst.getWildcards() & ~OFMatch.OFPFW_TP_DST);
+	        
+	        reverseMatchSrc.setFromCIDR(interfaceCidrAddress, OFMatch.STR_NW_SRC);
+	        reverseMatchSrc.setFromCIDR(peerCidrAddress, OFMatch.STR_NW_DST);
+	        
+	        OFMatch reverseMatchDst = reverseMatchSrc.clone();
+	        
+	        reverseMatchSrc.setTransportSource(BGP_PORT);
+	        reverseMatchSrc.setWildcards(forwardMatchSrc.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
+	        reverseMatchDst.setTransportDestination(BGP_PORT);
+	        reverseMatchDst.setWildcards(forwardMatchDst.getWildcards() & ~OFMatch.OFPFW_TP_DST);
+	        
+	        fm.setMatch(forwardMatchSrc);
+	        
+			for (FlowEntry flowEntry : path.flowEntries()){
+				OFFlowMod forwardFlowModSrc, forwardFlowModDst;
+				OFFlowMod reverseFlowModSrc, reverseFlowModDst;
+				try {
+					forwardFlowModSrc = fm.clone();
+					forwardFlowModDst = fm.clone();
+					reverseFlowModSrc = fm.clone();
+					reverseFlowModDst = fm.clone();
+				} catch (CloneNotSupportedException e) {
+					log.warn("Clone failed", e);
+					continue;
+				}
+				
+				forwardMatchSrc.setInputPort(flowEntry.inPort().value());
+				forwardFlowModSrc.setMatch(forwardMatchSrc);
+				((OFActionOutput)forwardFlowModSrc.getActions().get(0))
+						.setPort(flowEntry.outPort().value());
+				
+				forwardMatchDst.setInputPort(flowEntry.inPort().value());
+				forwardFlowModDst.setMatch(forwardMatchDst);
+				((OFActionOutput)forwardFlowModDst.getActions().get(0))
+						.setPort(flowEntry.outPort().value());
+				
+				reverseMatchSrc.setInputPort(flowEntry.outPort().value());
+				reverseFlowModSrc.setMatch(reverseMatchSrc);
+				((OFActionOutput)reverseFlowModSrc.getActions().get(0))
+						.setPort(flowEntry.inPort().value());
+				
+				reverseMatchDst.setInputPort(flowEntry.outPort().value());
+				reverseFlowModDst.setMatch(reverseMatchDst);
+				((OFActionOutput)reverseFlowModDst.getActions().get(0))
+						.setPort(flowEntry.inPort().value());
+				
+				IOFSwitch sw = floodlightProvider.getSwitches().get(flowEntry.dpid().value());
+				
+				//Hopefully the switch is there
+				List<OFMessage> msgList = new ArrayList<OFMessage>(2);
+				msgList.add(forwardFlowModSrc);
+				msgList.add(forwardFlowModDst);
+				msgList.add(reverseFlowModSrc);
+				msgList.add(reverseFlowModDst);
+				
+				try {
+					sw.write(msgList, null);
+					sw.flush();
+				} catch (IOException e) {
+					log.error("Failure writing flow mod", e);
+				}
+			}
+		}
+	}
 	
 	private void beginRouting(){
 		log.debug("Topology is now ready, beginning routing function");
+		setupBgpPaths();
 		
-		//traverse ptree and create flows for all routes
+		//Traverse ptree and create flows for all routes
 		for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)){
 			if (node.rib != null){
 				prefixAdded(node);