blob: 8a9c065766f4541189470cfae692b99509189d50 [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;
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -07007import net.onrc.onos.core.util.Dpid;
8import net.onrc.onos.core.util.PortNumber;
Jonathan Hartf5bd2582014-04-09 17:43:41 -07009
Jonathan Harte6e63732014-04-16 14:29:49 -070010import com.google.common.collect.HashMultimap;
11import com.google.common.collect.Multimap;
12
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070013// TODO The generic broadcast packet shouldn't contain an IP address which is
14// only for ARP packets.
Ray Milkey269ffb92014-04-03 14:43:30 -070015
Jonathan Hart7804bea2014-01-07 10:50:52 -080016/**
17 * Notification to all ONOS instances to broadcast this packet out the edge of
18 * the network. The edge is defined as any port that doesn't have a link to
19 * another switch. The one exception is the port that the packet was received
20 * on.
Jonathan Hart7804bea2014-01-07 10:50:52 -080021 */
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070022public class BroadcastPacketOutNotification extends PacketOutNotification {
Jonathan Hart7804bea2014-01-07 10:50:52 -080023
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070024 private static final long serialVersionUID = 1L;
Jonathan Hart7804bea2014-01-07 10:50:52 -080025
TeruU7feef8a2014-04-03 00:15:49 -070026 private final int address;
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070027 private final long inSwitch;
28 private final short inPort;
Jonathan Hart7804bea2014-01-07 10:50:52 -080029
Jonathan Hart51dc5e12014-04-22 11:03:59 -070030 /**
31 * Default constructor, used for deserialization.
32 */
TeruU7feef8a2014-04-03 00:15:49 -070033 protected BroadcastPacketOutNotification() {
Ray Milkey269ffb92014-04-03 14:43:30 -070034 super();
Jonathan Hart51dc5e12014-04-22 11:03:59 -070035 this.address = 0;
36 this.inSwitch = 0;
37 this.inPort = 0;
TeruU7feef8a2014-04-03 00:15:49 -070038 }
Ray Milkey269ffb92014-04-03 14:43:30 -070039
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070040 /**
41 * Class constructor.
42 *
Ray Milkey269ffb92014-04-03 14:43:30 -070043 * @param packet packet data to send in the packet-out
44 * @param address target IP address if the packet is an ARP packet
45 * @param inSwitch dpid of the switch the packet was received on
46 * @param inPort port number of the receiving port
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070047 */
TeruU7feef8a2014-04-03 00:15:49 -070048 public BroadcastPacketOutNotification(byte[] packet, int address,
Ray Milkey269ffb92014-04-03 14:43:30 -070049 long inSwitch, short inPort) {
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070050 super(packet);
Jonathan Hart7804bea2014-01-07 10:50:52 -080051
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070052 this.address = address;
53 this.inSwitch = inSwitch;
54 this.inPort = inPort;
55 }
Ray Milkey269ffb92014-04-03 14:43:30 -070056
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070057 /**
58 * Get the dpid of the switch the packet was received on.
59 *
60 * @return receiving switch dpid
61 */
62 public long getInSwitch() {
63 return inSwitch;
64 }
65
66 /**
67 * Get the port number of the port the packet was received on.
68 *
69 * @return receiving port number
70 */
71 public short getInPort() {
72 return inPort;
73 }
74
75 /**
76 * Get the target IP address if the packet is an ARP packet.
77 *
78 * @return the target IP address for ARP packets, or null if the packet is
Ray Milkey269ffb92014-04-03 14:43:30 -070079 * not an ARP packet
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070080 */
TeruU7feef8a2014-04-03 00:15:49 -070081 public int getTargetAddress() {
Jonathan Hart7c9a2fb2014-03-27 09:51:41 -070082 return address;
83 }
Jonathan Harte6e63732014-04-16 14:29:49 -070084
85 @Override
Jonathan Hartf5bd2582014-04-09 17:43:41 -070086 public Multimap<Long, Short> calculateOutPorts(
Jonathan Harte37e4e22014-05-13 19:12:02 -070087 Multimap<Long, Short> localPorts, Topology topology) {
Jonathan Harte6e63732014-04-16 14:29:49 -070088 Multimap<Long, Short> outPorts = HashMultimap.create();
89
Jonathan Hartf5bd2582014-04-09 17:43:41 -070090 for (Map.Entry<Long, Short> entry : localPorts.entries()) {
91 Port globalPort;
Jonathan Harte37e4e22014-05-13 19:12:02 -070092 topology.acquireReadLock();
Jonathan Hartf5bd2582014-04-09 17:43:41 -070093 try {
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -070094 globalPort = topology.getPort(new Dpid(entry.getKey()),
95 new PortNumber(entry.getValue()));
Jonathan Hartf5bd2582014-04-09 17:43:41 -070096 } finally {
Jonathan Harte37e4e22014-05-13 19:12:02 -070097 topology.releaseReadLock();
Jonathan Hartf5bd2582014-04-09 17:43:41 -070098 }
99
100 if ((!entry.getKey().equals(inSwitch) ||
101 !entry.getValue().equals(inPort)) &&
102 globalPort != null &&
103 globalPort.getOutgoingLink() == null) {
104
Jonathan Harte6e63732014-04-16 14:29:49 -0700105 outPorts.put(entry.getKey(), entry.getValue());
106 }
107 }
108
109 return outPorts;
110 }
Jonathan Hart7804bea2014-01-07 10:50:52 -0800111}