blob: c1c631c27e5b3262c30c68ab148575222274cec5 [file] [log] [blame]
Jonathan Hart313fdf02014-04-10 14:09:46 -07001package net.onrc.onos.core.packetservice;
Jonathan Hart7804bea2014-01-07 10:50:52 -08002
Jonathan Harte6e63732014-04-16 14:29:49 -07003import java.util.Map;
TeruU7feef8a2014-04-03 00:15:49 -07004
Jonathan Harte37e4e22014-05-13 19:12:02 -07005import net.onrc.onos.core.topology.Topology;
Jonathan Hartf5bd2582014-04-09 17:43:41 -07006import net.onrc.onos.core.topology.Port;
7
Jonathan Harte6e63732014-04-16 14:29:49 -07008import com.google.common.collect.HashMultimap;
9import com.google.common.collect.Multimap;
10
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070011// TODO The generic broadcast packet shouldn't contain an IP address which is
12// only for ARP packets.
Ray Milkey269ffb92014-04-03 14:43:30 -070013
Jonathan Hart7804bea2014-01-07 10:50:52 -080014/**
15 * Notification to all ONOS instances to broadcast this packet out the edge of
16 * the network. The edge is defined as any port that doesn't have a link to
17 * another switch. The one exception is the port that the packet was received
18 * on.
Jonathan Hart7804bea2014-01-07 10:50:52 -080019 */
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070020public class BroadcastPacketOutNotification extends PacketOutNotification {
Jonathan Hart7804bea2014-01-07 10:50:52 -080021
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070022 private static final long serialVersionUID = 1L;
Jonathan Hart7804bea2014-01-07 10:50:52 -080023
TeruU7feef8a2014-04-03 00:15:49 -070024 private final int address;
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070025 private final long inSwitch;
26 private final short inPort;
Jonathan Hart7804bea2014-01-07 10:50:52 -080027
Jonathan Hart51dc5e12014-04-22 11:03:59 -070028 /**
29 * Default constructor, used for deserialization.
30 */
TeruU7feef8a2014-04-03 00:15:49 -070031 protected BroadcastPacketOutNotification() {
Ray Milkey269ffb92014-04-03 14:43:30 -070032 super();
Jonathan Hart51dc5e12014-04-22 11:03:59 -070033 this.address = 0;
34 this.inSwitch = 0;
35 this.inPort = 0;
TeruU7feef8a2014-04-03 00:15:49 -070036 }
Ray Milkey269ffb92014-04-03 14:43:30 -070037
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070038 /**
39 * Class constructor.
40 *
Ray Milkey269ffb92014-04-03 14:43:30 -070041 * @param packet packet data to send in the packet-out
42 * @param address target IP address if the packet is an ARP packet
43 * @param inSwitch dpid of the switch the packet was received on
44 * @param inPort port number of the receiving port
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070045 */
TeruU7feef8a2014-04-03 00:15:49 -070046 public BroadcastPacketOutNotification(byte[] packet, int address,
Ray Milkey269ffb92014-04-03 14:43:30 -070047 long inSwitch, short inPort) {
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070048 super(packet);
Jonathan Hart7804bea2014-01-07 10:50:52 -080049
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070050 this.address = address;
51 this.inSwitch = inSwitch;
52 this.inPort = inPort;
53 }
Ray Milkey269ffb92014-04-03 14:43:30 -070054
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070055 /**
56 * Get the dpid of the switch the packet was received on.
57 *
58 * @return receiving switch dpid
59 */
60 public long getInSwitch() {
61 return inSwitch;
62 }
63
64 /**
65 * Get the port number of the port the packet was received on.
66 *
67 * @return receiving port number
68 */
69 public short getInPort() {
70 return inPort;
71 }
72
73 /**
74 * Get the target IP address if the packet is an ARP packet.
75 *
76 * @return the target IP address for ARP packets, or null if the packet is
Ray Milkey269ffb92014-04-03 14:43:30 -070077 * not an ARP packet
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070078 */
TeruU7feef8a2014-04-03 00:15:49 -070079 public int getTargetAddress() {
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070080 return address;
81 }
Jonathan Harte6e63732014-04-16 14:29:49 -070082
83 @Override
Jonathan Hartf5bd2582014-04-09 17:43:41 -070084 public Multimap<Long, Short> calculateOutPorts(
Jonathan Harte37e4e22014-05-13 19:12:02 -070085 Multimap<Long, Short> localPorts, Topology topology) {
Jonathan Harte6e63732014-04-16 14:29:49 -070086 Multimap<Long, Short> outPorts = HashMultimap.create();
87
Jonathan Hartf5bd2582014-04-09 17:43:41 -070088 for (Map.Entry<Long, Short> entry : localPorts.entries()) {
89 Port globalPort;
Jonathan Harte37e4e22014-05-13 19:12:02 -070090 topology.acquireReadLock();
Jonathan Hartf5bd2582014-04-09 17:43:41 -070091 try {
Jonathan Harte37e4e22014-05-13 19:12:02 -070092 globalPort = topology.getPort(entry.getKey(),
Jonathan Hartf5bd2582014-04-09 17:43:41 -070093 entry.getValue().longValue());
94 } finally {
Jonathan Harte37e4e22014-05-13 19:12:02 -070095 topology.releaseReadLock();
Jonathan Hartf5bd2582014-04-09 17:43:41 -070096 }
97
98 if ((!entry.getKey().equals(inSwitch) ||
99 !entry.getValue().equals(inPort)) &&
100 globalPort != null &&
101 globalPort.getOutgoingLink() == null) {
102
Jonathan Harte6e63732014-04-16 14:29:49 -0700103 outPorts.put(entry.getKey(), entry.getValue());
104 }
105 }
106
107 return outPorts;
108 }
Jonathan Hart7804bea2014-01-07 10:50:52 -0800109}