blob: 5895a8e4c6832276313deec4e2cee16cc7f709fa [file] [log] [blame]
Sangho Shineb083032014-09-22 16:11:34 -07001package net.onrc.onos.apps.segmentrouting;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import net.floodlightcontroller.core.IFloodlightProviderService;
7import net.floodlightcontroller.core.IOFSwitch;
8import net.floodlightcontroller.core.module.FloodlightModuleContext;
9import net.floodlightcontroller.util.MACAddress;
Sangho Shineb083032014-09-22 16:11:34 -070010import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
11import net.onrc.onos.core.packet.Ethernet;
12import net.onrc.onos.core.packet.IPv4;
13import net.onrc.onos.core.topology.ITopologyService;
14import net.onrc.onos.core.topology.MutableTopology;
15import net.onrc.onos.core.topology.Port;
16import net.onrc.onos.core.topology.Switch;
17
18import org.projectfloodlight.openflow.protocol.OFFactory;
19import org.projectfloodlight.openflow.protocol.OFMatchV3;
20import org.projectfloodlight.openflow.protocol.OFMessage;
21import org.projectfloodlight.openflow.protocol.OFOxmList;
22import org.projectfloodlight.openflow.protocol.action.OFAction;
23import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
24import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
25import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
26import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
27import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
28import org.projectfloodlight.openflow.types.EthType;
29import org.projectfloodlight.openflow.types.IPv4Address;
30import org.projectfloodlight.openflow.types.MacAddress;
31import org.projectfloodlight.openflow.types.OFBufferId;
32import org.projectfloodlight.openflow.types.OFPort;
33import org.projectfloodlight.openflow.types.TableId;
34import org.slf4j.Logger;
35import org.slf4j.LoggerFactory;
36
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070037public class GenericIpHandler {
Sangho Shineb083032014-09-22 16:11:34 -070038
39 private MutableTopology mutableTopology;
40 private ITopologyService topologyService;
41 private IFloodlightProviderService floodlightProvider;
42 private IFlowPusherService flowPusher;
Sangho Shineb083032014-09-22 16:11:34 -070043 private SegmentRoutingManager srManager;
44
45 private static final Logger log = LoggerFactory
46 .getLogger(GenericIpHandler.class);
47
48 private static final int TABLE_VLAN = 0;
49 private static final int TABLE_TMAC = 1;
50 private static final int TABLE_IPv4_UNICAST = 2;
51 private static final int TABLE_MPLS = 3;
52 private static final int TABLE_META = 4;
53 private static final int TABLE_ACL = 5;
54
55 private static final short MAX_PRIORITY = (short) 0xffff;
56 private static final short SLASH_24_PRIORITY = (short) 0xfff0;
57 private static final short SLASH_16_PRIORITY = (short) 0xff00;
58 private static final short SLASH_8_PRIORITY = (short) 0xf000;
59 private static final short MIN_PRIORITY = 0x0;
60
61 public GenericIpHandler(FloodlightModuleContext context, SegmentRoutingManager sr) {
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070062 this.floodlightProvider = context
63 .getServiceImpl(IFloodlightProviderService.class);
Sangho Shineb083032014-09-22 16:11:34 -070064 this.topologyService = context.getServiceImpl(ITopologyService.class);
65 this.mutableTopology = topologyService.getTopology();
66 this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
Sangho Shineb083032014-09-22 16:11:34 -070067 this.srManager = sr;
68
Sangho Shineb083032014-09-22 16:11:34 -070069 }
70
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070071 public void processPacketIn(Switch sw, Port inPort, Ethernet payload) {
Sangho Shineb083032014-09-22 16:11:34 -070072 // TODO Auto-generated method stub
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070073 log.debug("GenericIPHandler: Received a IP packet {} from sw {} ",
74 payload.toString(), sw.getDpid());
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070075 IPv4 ipv4 = (IPv4) payload.getPayload();
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070076 int destinationAddress = ipv4.getDestinationAddress();
Sangho Shineb083032014-09-22 16:11:34 -070077
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070078 // Check if the destination is any host known to TopologyService
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -070079 for (net.onrc.onos.core.topology.Host host : mutableTopology.getHosts()) {
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070080 IPv4Address hostIpAddress = IPv4Address.of(host.getIpAddress());
81 if (hostIpAddress != null && hostIpAddress.getInt() == destinationAddress) {
82 byte[] destinationMacAddress = host.getMacAddress().toBytes();
83 addRouteToHost(sw, destinationAddress, destinationMacAddress);
84 return;
Sangho Shineb083032014-09-22 16:11:34 -070085 }
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070086 }
Sangho Shineb083032014-09-22 16:11:34 -070087
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070088 // Check if the destination is within subnets of the swtich
89 if (isWithinSubnets(sw, IPv4Address.of(destinationAddress).toString())) {
Sangho Shin7330c032014-10-20 10:34:51 -070090 srManager.addPacketToPacketBuffer(ipv4);
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070091 srManager.sendArpRequest(sw, destinationAddress, inPort);
Sangho Shineb083032014-09-22 16:11:34 -070092 }
93 }
94
95 private boolean isWithinSubnets(Switch sw, String ipAddress) {
96
97 return true;
98 }
99
Sangho Shineb083032014-09-22 16:11:34 -0700100 /**
101 * Add routing rules to forward packets to known hosts
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -0700102 *
Sangho Shineb083032014-09-22 16:11:34 -0700103 * @param sw Switch
104 * @param hostIp Host IP address to forwards packets to
105 */
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -0700106 public void addRouteToHost(Switch sw, int destinationAddress,
107 byte[] destinationMacAddress) {
Sangho Shineb083032014-09-22 16:11:34 -0700108
Sangho Shin9c0f4c32014-09-26 16:02:38 -0700109 // If we do not know the host, then we cannot set the forwarding rule
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -0700110 net.onrc.onos.core.topology.Host host = mutableTopology.getHostByMac(MACAddress
111 .valueOf(destinationMacAddress));
Sangho Shin9c0f4c32014-09-26 16:02:38 -0700112 if (host == null) {
113 return;
114 }
115
Sangho Shineb083032014-09-22 16:11:34 -0700116 IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
117 OFFactory factory = ofSwitch.getFactory();
118
Sangho Shineb083032014-09-22 16:11:34 -0700119 OFOxmEthType ethTypeIp = factory.oxms()
120 .ethType(EthType.IPv4);
121 OFOxmIpv4DstMasked ipPrefix = factory.oxms()
122 .ipv4DstMasked(
123 IPv4Address.of(destinationAddress),
124 IPv4Address.NO_MASK); // host addr should be /32
125 OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
126 OFMatchV3 match = factory.buildMatchV3()
127 .setOxmList(oxmListSlash32).build();
128 OFAction setDmac = null;
129 OFOxmEthDst dmac = factory.oxms()
130 .ethDst(MacAddress.of(destinationMacAddress));
131 setDmac = factory.actions().buildSetField()
132 .setField(dmac).build();
133
134 OFAction decTtl = factory.actions().decNwTtl();
135
136 // Set the source MAC address with the switch MAC address
137 String switchMacAddress = sw.getStringAttribute("routerMac");
138 OFOxmEthSrc srcAddr = factory.oxms().ethSrc(MacAddress.of(switchMacAddress));
139 OFAction setSA = factory.actions().buildSetField()
140 .setField(srcAddr).build();
141
142 List<OFAction> actionList = new ArrayList<OFAction>();
143 actionList.add(setDmac);
144 actionList.add(decTtl);
145 actionList.add(setSA);
146
Sangho Shineb083032014-09-22 16:11:34 -0700147 /* TODO : need to check the config file for all packets
148 String subnets = sw.getStringAttribute("subnets");
149 try {
150 JSONArray arry = new JSONArray(subnets);
151 for (int i = 0; i < arry.length(); i++) {
152 String subnetIp = (String) arry.getJSONObject(i).get("subnetIp");
153 int portNo = (int) arry.getJSONObject(i).get("portNo");
154
155 if (netMatch(subnetIp, IPv4Address.of(hostIp.getDestinationAddress()).toString())) {
156 OFAction out = factory.actions().buildOutput()
157 .setPort(OFPort.of(portNo)).build();
158 actionList.add(out);
159 }
160 }
161 } catch (JSONException e) {
162 // TODO Auto-generated catch block
163 e.printStackTrace();
164 }
165 */
166
167 // Set output port
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -0700168 for (Port port : host.getAttachmentPoints()) {
Sangho Shin9c0f4c32014-09-26 16:02:38 -0700169 OFAction out = factory.actions().buildOutput()
170 .setPort(OFPort.of(port.getPortNumber().shortValue())).build();
171 actionList.add(out);
Sangho Shineb083032014-09-22 16:11:34 -0700172 }
173
174 OFInstruction writeInstr = factory.instructions().buildWriteActions()
175 .setActions(actionList).build();
176
177 List<OFInstruction> instructions = new ArrayList<OFInstruction>();
178 instructions.add(writeInstr);
179
180 OFMessage myIpEntry = factory.buildFlowAdd()
181 .setTableId(TableId.of(TABLE_IPv4_UNICAST))
182 .setMatch(match)
183 .setInstructions(instructions)
184 .setPriority(MAX_PRIORITY)
185 .setBufferId(OFBufferId.NO_BUFFER)
186 .setIdleTimeout(0)
187 .setHardTimeout(0)
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -0700188 // .setXid(getNextTransactionId())
Sangho Shineb083032014-09-22 16:11:34 -0700189 .build();
190
Srikanth Vavilapallif25c7b02014-10-01 14:30:43 -0700191 log.debug("Sending 'Routing information' OF message to the switch {}.", sw
192 .getDpid().toString());
Sangho Shineb083032014-09-22 16:11:34 -0700193
194 flowPusher.add(sw.getDpid(), myIpEntry);
195
196 }
197
Sangho Shineb083032014-09-22 16:11:34 -0700198}