blob: a776eaa98eb5248076f4ac19c09f683bf027a0be [file] [log] [blame]
Jonathan Hartd857ad62013-12-14 18:08:17 -08001package net.onrc.onos.ofcontroller.devicemanager;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Date;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
9
10import net.floodlightcontroller.core.FloodlightContext;
11import net.floodlightcontroller.core.IFloodlightProviderService;
12import net.floodlightcontroller.core.IOFMessageListener;
13import net.floodlightcontroller.core.IOFSwitch;
14import net.floodlightcontroller.core.IUpdate;
15import net.floodlightcontroller.core.module.FloodlightModuleContext;
16import net.floodlightcontroller.core.module.FloodlightModuleException;
17import net.floodlightcontroller.core.module.IFloodlightModule;
18import net.floodlightcontroller.core.module.IFloodlightService;
19import net.floodlightcontroller.packet.ARP;
20import net.floodlightcontroller.packet.DHCP;
21import net.floodlightcontroller.packet.Ethernet;
22import net.floodlightcontroller.packet.IPv4;
23import net.floodlightcontroller.packet.UDP;
24import net.floodlightcontroller.util.MACAddress;
25import net.onrc.onos.ofcontroller.core.IDeviceStorage;
26import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
27
28import org.openflow.protocol.OFMessage;
29import org.openflow.protocol.OFPacketIn;
30import org.openflow.protocol.OFType;
31
32public class OnosDeviceManager implements IFloodlightModule, IOFMessageListener,
33 IOnosDeviceService {
34 private IDeviceStorage deviceStorage;
35
36 private IFloodlightProviderService floodlightProvider;
37
38 public class OnosDeviceUpdate implements IUpdate {
39 private OnosDevice device;
40
41 public OnosDeviceUpdate(OnosDevice device) {
42 this.device = device;
43 }
44
45 @Override
46 public void dispatch() {
47 deviceStorage.addOnosDevice(device);
48 }
49 }
50
51 @Override
52 public String getName() {
53 return "onosdevicemanager";
54 }
55
56 @Override
57 public boolean isCallbackOrderingPrereq(OFType type, String name) {
58 // TODO Auto-generated method stub
59 return false;
60 }
61
62 @Override
63 public boolean isCallbackOrderingPostreq(OFType type, String name) {
64 return type == OFType.PACKET_IN &&
65 ("proxyarpmanager".equals(name) || "onosforwarding".equals(name));
66 }
67
68 @Override
69 public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
70 if (msg.getType().equals(OFType.PACKET_IN)) {
71 OFPacketIn pi = (OFPacketIn) msg;
72
73 Ethernet eth = IFloodlightProviderService.bcStore.
74 get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
75
76 return processPacketIn(sw, pi, eth);
77 }
78
79 return Command.CONTINUE;
80 }
81
82 private Command processPacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
83
84 // Extract source entity information
85 OnosDevice srcDevice =
86 getSourceDeviceFromPacket(eth, sw.getId(), pi.getInPort());
87 if (srcDevice == null)
88 return Command.STOP;
89
90 floodlightProvider.publishUpdate(new OnosDeviceUpdate(srcDevice));
91
92 return Command.CONTINUE;
93 }
94
95 /**
96 * Get IP address from packet if the packet is either an ARP
97 * or a DHCP packet
98 * @param eth
99 * @param dlAddr
100 * @return
101 */
102 private int getSrcNwAddr(Ethernet eth, long dlAddr) {
103 if (eth.getPayload() instanceof ARP) {
104 ARP arp = (ARP) eth.getPayload();
105 if ((arp.getProtocolType() == ARP.PROTO_TYPE_IP) &&
106 (Ethernet.toLong(arp.getSenderHardwareAddress()) == dlAddr)) {
107 return IPv4.toIPv4Address(arp.getSenderProtocolAddress());
108 }
109 } else if (eth.getPayload() instanceof IPv4) {
110 IPv4 ipv4 = (IPv4) eth.getPayload();
111 if (ipv4.getPayload() instanceof UDP) {
112 UDP udp = (UDP)ipv4.getPayload();
113 if (udp.getPayload() instanceof DHCP) {
114 DHCP dhcp = (DHCP)udp.getPayload();
115 if (dhcp.getOpCode() == DHCP.OPCODE_REPLY) {
116 return ipv4.getSourceAddress();
117 }
118 }
119 }
120 }
121 return 0;
122 }
123
124 /**
125 * Parse an entity from an {@link Ethernet} packet.
126 * @param eth the packet to parse
127 * @param sw the switch on which the packet arrived
128 * @param pi the original packetin
129 * @return the entity from the packet
130 */
131 private OnosDevice getSourceDeviceFromPacket(Ethernet eth,
132 long swdpid,
133 short port) {
134 byte[] dlAddrArr = eth.getSourceMACAddress();
135 long dlAddr = Ethernet.toLong(dlAddrArr);
136
137 // Ignore broadcast/multicast source
138 if ((dlAddrArr[0] & 0x1) != 0)
139 return null;
140
141 short vlan = eth.getVlanID();
142 int nwSrc = getSrcNwAddr(eth, dlAddr);
143 return new OnosDevice(MACAddress.valueOf(dlAddr),
144 ((vlan >= 0) ? vlan : null),
145 ((nwSrc != 0) ? nwSrc : null),
146 swdpid,
147 port,
148 new Date());
149 }
150
151 @Override
152 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
153 List<Class<? extends IFloodlightService>> services =
154 new ArrayList<Class<? extends IFloodlightService>>();
155 services.add(IOnosDeviceService.class);
156 return services;
157 }
158
159 @Override
160 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
161 Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
162 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
163 impls.put(IOnosDeviceService.class, this);
164 return impls;
165 }
166
167 @Override
168 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
169 List<Class<? extends IFloodlightService>> dependencies =
170 new ArrayList<Class<? extends IFloodlightService>>();
171 dependencies.add(IFloodlightProviderService.class);
172 return dependencies;
173 }
174
175 @Override
176 public void init(FloodlightModuleContext context)
177 throws FloodlightModuleException {
178 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
179
180 deviceStorage = new DeviceStorageImpl();
181 deviceStorage.init("");
182 }
183
184 @Override
185 public void startUp(FloodlightModuleContext context) {
186 floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
187 }
188
189}