blob: fd27e56c3d01ff58be7f33ad20dda0b7cf2b3516 [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) {
62 this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
63 this.topologyService = context.getServiceImpl(ITopologyService.class);
64 this.mutableTopology = topologyService.getTopology();
65 this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
Sangho Shineb083032014-09-22 16:11:34 -070066 this.srManager = sr;
67
Sangho Shineb083032014-09-22 16:11:34 -070068 }
69
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070070 public void processPacketIn(Switch sw, Port inPort, Ethernet payload) {
Sangho Shineb083032014-09-22 16:11:34 -070071 // TODO Auto-generated method stub
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070072 log.debug("GenericIPHandler: Received a IP packet {} from sw {} ",
73 payload.toString(), sw.getDpid());
74 IPv4 ipv4 = (IPv4)payload.getPayload();
75 int destinationAddress = ipv4.getDestinationAddress();
Sangho Shineb083032014-09-22 16:11:34 -070076
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070077 // Check if the destination is any host known to TopologyService
78 for (net.onrc.onos.core.topology.Host host: mutableTopology.getHosts()) {
79 IPv4Address hostIpAddress = IPv4Address.of(host.getIpAddress());
80 if (hostIpAddress != null && hostIpAddress.getInt() == destinationAddress) {
81 byte[] destinationMacAddress = host.getMacAddress().toBytes();
82 addRouteToHost(sw, destinationAddress, destinationMacAddress);
83 return;
Sangho Shineb083032014-09-22 16:11:34 -070084 }
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070085 }
Sangho Shineb083032014-09-22 16:11:34 -070086
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070087 // Check if the destination is within subnets of the swtich
88 if (isWithinSubnets(sw, IPv4Address.of(destinationAddress).toString())) {
Sangho Shin463bee52014-09-29 15:14:43 -070089 srManager.addPacket(ipv4);
Srikanth Vavilapallib1fce732014-09-24 14:09:50 -070090 srManager.sendArpRequest(sw, destinationAddress, inPort);
Sangho Shineb083032014-09-22 16:11:34 -070091 }
92 }
93
94 private boolean isWithinSubnets(Switch sw, String ipAddress) {
95
96 return true;
97 }
98
99
100 /**
101 * Add routing rules to forward packets to known hosts
102 *
103 * @param sw Switch
104 * @param hostIp Host IP address to forwards packets to
105 */
106 public void addRouteToHost(Switch sw, int destinationAddress, byte[] destinationMacAddress) {
107
Sangho Shin9c0f4c32014-09-26 16:02:38 -0700108 // If we do not know the host, then we cannot set the forwarding rule
109 net.onrc.onos.core.topology.Host host = mutableTopology.getHostByMac(MACAddress.valueOf(destinationMacAddress));
110 if (host == null) {
111 return;
112 }
113
Sangho Shineb083032014-09-22 16:11:34 -0700114 IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
115 OFFactory factory = ofSwitch.getFactory();
116
117
118 OFOxmEthType ethTypeIp = factory.oxms()
119 .ethType(EthType.IPv4);
120 OFOxmIpv4DstMasked ipPrefix = factory.oxms()
121 .ipv4DstMasked(
122 IPv4Address.of(destinationAddress),
123 IPv4Address.NO_MASK); // host addr should be /32
124 OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
125 OFMatchV3 match = factory.buildMatchV3()
126 .setOxmList(oxmListSlash32).build();
127 OFAction setDmac = null;
128 OFOxmEthDst dmac = factory.oxms()
129 .ethDst(MacAddress.of(destinationMacAddress));
130 setDmac = factory.actions().buildSetField()
131 .setField(dmac).build();
132
133 OFAction decTtl = factory.actions().decNwTtl();
134
135 // Set the source MAC address with the switch MAC address
136 String switchMacAddress = sw.getStringAttribute("routerMac");
137 OFOxmEthSrc srcAddr = factory.oxms().ethSrc(MacAddress.of(switchMacAddress));
138 OFAction setSA = factory.actions().buildSetField()
139 .setField(srcAddr).build();
140
141 List<OFAction> actionList = new ArrayList<OFAction>();
142 actionList.add(setDmac);
143 actionList.add(decTtl);
144 actionList.add(setSA);
145
146
147 /* 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
Sangho Shin9c0f4c32014-09-26 16:02:38 -0700168 for (Port port: host.getAttachmentPoints()) {
169 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)
188 //.setXid(getNextTransactionId())
189 .build();
190
191 log.debug("Sending 'Routing information' OF message to the switch {}.", sw.getDpid().toString());
192
193 flowPusher.add(sw.getDpid(), myIpEntry);
194
195 }
196
197
198}