blob: 078414434fb58bafdffb0e7b8363d691bff976be [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
107 IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
108 OFFactory factory = ofSwitch.getFactory();
109
110
111 OFOxmEthType ethTypeIp = factory.oxms()
112 .ethType(EthType.IPv4);
113 OFOxmIpv4DstMasked ipPrefix = factory.oxms()
114 .ipv4DstMasked(
115 IPv4Address.of(destinationAddress),
116 IPv4Address.NO_MASK); // host addr should be /32
117 OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
118 OFMatchV3 match = factory.buildMatchV3()
119 .setOxmList(oxmListSlash32).build();
120 OFAction setDmac = null;
121 OFOxmEthDst dmac = factory.oxms()
122 .ethDst(MacAddress.of(destinationMacAddress));
123 setDmac = factory.actions().buildSetField()
124 .setField(dmac).build();
125
126 OFAction decTtl = factory.actions().decNwTtl();
127
128 // Set the source MAC address with the switch MAC address
129 String switchMacAddress = sw.getStringAttribute("routerMac");
130 OFOxmEthSrc srcAddr = factory.oxms().ethSrc(MacAddress.of(switchMacAddress));
131 OFAction setSA = factory.actions().buildSetField()
132 .setField(srcAddr).build();
133
134 List<OFAction> actionList = new ArrayList<OFAction>();
135 actionList.add(setDmac);
136 actionList.add(decTtl);
137 actionList.add(setSA);
138
139
140 /* TODO : need to check the config file for all packets
141 String subnets = sw.getStringAttribute("subnets");
142 try {
143 JSONArray arry = new JSONArray(subnets);
144 for (int i = 0; i < arry.length(); i++) {
145 String subnetIp = (String) arry.getJSONObject(i).get("subnetIp");
146 int portNo = (int) arry.getJSONObject(i).get("portNo");
147
148 if (netMatch(subnetIp, IPv4Address.of(hostIp.getDestinationAddress()).toString())) {
149 OFAction out = factory.actions().buildOutput()
150 .setPort(OFPort.of(portNo)).build();
151 actionList.add(out);
152 }
153 }
154 } catch (JSONException e) {
155 // TODO Auto-generated catch block
156 e.printStackTrace();
157 }
158 */
159
160 // Set output port
161 net.onrc.onos.core.topology.Host host = mutableTopology.getHostByMac(MACAddress.valueOf(destinationMacAddress));
162 if (host != null) {
163 for (Port port: host.getAttachmentPoints()) {
164 OFAction out = factory.actions().buildOutput()
165 .setPort(OFPort.of(port.getPortNumber().shortValue())).build();
166 actionList.add(out);
167 }
168 }
169
170 OFInstruction writeInstr = factory.instructions().buildWriteActions()
171 .setActions(actionList).build();
172
173 List<OFInstruction> instructions = new ArrayList<OFInstruction>();
174 instructions.add(writeInstr);
175
176 OFMessage myIpEntry = factory.buildFlowAdd()
177 .setTableId(TableId.of(TABLE_IPv4_UNICAST))
178 .setMatch(match)
179 .setInstructions(instructions)
180 .setPriority(MAX_PRIORITY)
181 .setBufferId(OFBufferId.NO_BUFFER)
182 .setIdleTimeout(0)
183 .setHardTimeout(0)
184 //.setXid(getNextTransactionId())
185 .build();
186
187 log.debug("Sending 'Routing information' OF message to the switch {}.", sw.getDpid().toString());
188
189 flowPusher.add(sw.getDpid(), myIpEntry);
190
191 }
192
193
194}