blob: b0b8cb346b516f3c64c95f765b73574c461cce3c [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())) {
89 srManager.sendArpRequest(sw, destinationAddress, inPort);
Sangho Shineb083032014-09-22 16:11:34 -070090 }
91 }
92
93 private boolean isWithinSubnets(Switch sw, String ipAddress) {
94
95 return true;
96 }
97
98
99 /**
100 * Add routing rules to forward packets to known hosts
101 *
102 * @param sw Switch
103 * @param hostIp Host IP address to forwards packets to
104 */
105 public void addRouteToHost(Switch sw, int destinationAddress, byte[] destinationMacAddress) {
106
Sangho Shin9c0f4c32014-09-26 16:02:38 -0700107 // If we do not know the host, then we cannot set the forwarding rule
108 net.onrc.onos.core.topology.Host host = mutableTopology.getHostByMac(MACAddress.valueOf(destinationMacAddress));
109 if (host == null) {
110 return;
111 }
112
Sangho Shineb083032014-09-22 16:11:34 -0700113 IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
114 OFFactory factory = ofSwitch.getFactory();
115
116
117 OFOxmEthType ethTypeIp = factory.oxms()
118 .ethType(EthType.IPv4);
119 OFOxmIpv4DstMasked ipPrefix = factory.oxms()
120 .ipv4DstMasked(
121 IPv4Address.of(destinationAddress),
122 IPv4Address.NO_MASK); // host addr should be /32
123 OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
124 OFMatchV3 match = factory.buildMatchV3()
125 .setOxmList(oxmListSlash32).build();
126 OFAction setDmac = null;
127 OFOxmEthDst dmac = factory.oxms()
128 .ethDst(MacAddress.of(destinationMacAddress));
129 setDmac = factory.actions().buildSetField()
130 .setField(dmac).build();
131
132 OFAction decTtl = factory.actions().decNwTtl();
133
134 // Set the source MAC address with the switch MAC address
135 String switchMacAddress = sw.getStringAttribute("routerMac");
136 OFOxmEthSrc srcAddr = factory.oxms().ethSrc(MacAddress.of(switchMacAddress));
137 OFAction setSA = factory.actions().buildSetField()
138 .setField(srcAddr).build();
139
140 List<OFAction> actionList = new ArrayList<OFAction>();
141 actionList.add(setDmac);
142 actionList.add(decTtl);
143 actionList.add(setSA);
144
145
146 /* TODO : need to check the config file for all packets
147 String subnets = sw.getStringAttribute("subnets");
148 try {
149 JSONArray arry = new JSONArray(subnets);
150 for (int i = 0; i < arry.length(); i++) {
151 String subnetIp = (String) arry.getJSONObject(i).get("subnetIp");
152 int portNo = (int) arry.getJSONObject(i).get("portNo");
153
154 if (netMatch(subnetIp, IPv4Address.of(hostIp.getDestinationAddress()).toString())) {
155 OFAction out = factory.actions().buildOutput()
156 .setPort(OFPort.of(portNo)).build();
157 actionList.add(out);
158 }
159 }
160 } catch (JSONException e) {
161 // TODO Auto-generated catch block
162 e.printStackTrace();
163 }
164 */
165
166 // Set output port
Sangho Shin9c0f4c32014-09-26 16:02:38 -0700167 for (Port port: host.getAttachmentPoints()) {
168 OFAction out = factory.actions().buildOutput()
169 .setPort(OFPort.of(port.getPortNumber().shortValue())).build();
170 actionList.add(out);
Sangho Shineb083032014-09-22 16:11:34 -0700171 }
172
173 OFInstruction writeInstr = factory.instructions().buildWriteActions()
174 .setActions(actionList).build();
175
176 List<OFInstruction> instructions = new ArrayList<OFInstruction>();
177 instructions.add(writeInstr);
178
179 OFMessage myIpEntry = factory.buildFlowAdd()
180 .setTableId(TableId.of(TABLE_IPv4_UNICAST))
181 .setMatch(match)
182 .setInstructions(instructions)
183 .setPriority(MAX_PRIORITY)
184 .setBufferId(OFBufferId.NO_BUFFER)
185 .setIdleTimeout(0)
186 .setHardTimeout(0)
187 //.setXid(getNextTransactionId())
188 .build();
189
190 log.debug("Sending 'Routing information' OF message to the switch {}.", sw.getDpid().toString());
191
192 flowPusher.add(sw.getDpid(), myIpEntry);
193
194 }
195
196
197}