Update to work on Sodium SR1
[l2switch.git] / hosttracker / implementation / src / main / java / org / opendaylight / l2switch / hosttracker / plugin / internal / SimpleAddressObserver.java
1 /*
2  * Copyright (c) 2014 André Martins, Colin Dixon, Evan Zeller and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.l2switch.hosttracker.plugin.internal;
9
10 import java.math.BigInteger;
11 import java.util.Date;
12 import org.opendaylight.controller.sal.binding.api.NotificationService;
13 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.address.node.connector.Addresses;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.address.node.connector.AddressesBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.address.node.connector.AddressesKey;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketListener;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketReceived;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.arp.packet.received.packet.chain.packet.ArpPacket;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.PacketChain;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.packet.chain.packet.RawPacket;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.KnownEtherType;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.VlanId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.ethernet.packet.received.packet.chain.packet.EthernetPacket;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv4.rev140528.Ipv4PacketListener;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv4.rev140528.Ipv4PacketReceived;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv4.rev140528.ipv4.packet.received.packet.chain.packet.Ipv4Packet;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv6.rev140528.Ipv6PacketListener;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv6.rev140528.Ipv6PacketReceived;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv6.rev140528.ipv6.packet.received.packet.chain.packet.Ipv6Packet;
34
35 /**
36  * A Simple Address Observer based on l2switch address observer.
37  */
38 public class SimpleAddressObserver implements ArpPacketListener, Ipv4PacketListener, Ipv6PacketListener {
39
40     private static final String IPV4_IP_TO_IGNORE = "0.0.0.0";
41     private static final String IPV6_IP_TO_IGNORE = "0:0:0:0:0:0:0:0";
42
43     private final HostTrackerImpl hostTrackerImpl;
44     private final NotificationService notificationService;
45
46     public SimpleAddressObserver(HostTrackerImpl hostTrackerImpl, NotificationService notificationService) {
47         this.hostTrackerImpl = hostTrackerImpl;
48         this.notificationService = notificationService;
49
50     }
51
52     void registerAsNotificationListener() {
53         this.notificationService.registerNotificationListener(this);
54     }
55
56     @Override
57     public void onArpPacketReceived(ArpPacketReceived packetReceived) {
58         if (packetReceived == null || packetReceived.getPacketChain() == null) {
59             return;
60         }
61
62         RawPacket rawPacket = null;
63         EthernetPacket ethernetPacket = null;
64         ArpPacket arpPacket = null;
65         for (PacketChain packetChain : packetReceived.getPacketChain()) {
66             if (packetChain.getPacket() instanceof RawPacket) {
67                 rawPacket = (RawPacket) packetChain.getPacket();
68             } else if (packetChain.getPacket() instanceof EthernetPacket) {
69                 ethernetPacket = (EthernetPacket) packetChain.getPacket();
70             } else if (packetChain.getPacket() instanceof ArpPacket) {
71                 arpPacket = (ArpPacket) packetChain.getPacket();
72             }
73         }
74         if (rawPacket == null || ethernetPacket == null || arpPacket == null) {
75             return;
76         }
77         VlanId vlanId = null;
78         if (ethernetPacket.getEthertype().equals(KnownEtherType.VlanTagged)) {
79             vlanId = ethernetPacket.getHeader8021q().get(0).getVlan();
80         }
81         MacAddress sourceMac = ethernetPacket.getSourceMac();
82         IpAddress ipAddress = null;
83         if (arpPacket.getProtocolType().equals(KnownEtherType.Ipv4)) {
84             ipAddress = new IpAddress(new Ipv4Address(arpPacket.getSourceProtocolAddress()));
85         }
86         Addresses addrs = createAddresses(sourceMac, vlanId, ipAddress, ethernetPacket.getEthertype());
87         if (addrs == null) {
88             return;
89         }
90         NodeConnectorRef ingress = rawPacket.getIngress();
91         hostTrackerImpl.packetReceived(addrs, ingress.getValue());
92     }
93
94     @Override
95     public void onIpv4PacketReceived(Ipv4PacketReceived packetReceived) {
96         if (packetReceived == null || packetReceived.getPacketChain() == null) {
97             return;
98         }
99
100         RawPacket rawPacket = null;
101         EthernetPacket ethernetPacket = null;
102         Ipv4Packet ipv4Packet = null;
103         for (PacketChain packetChain : packetReceived.getPacketChain()) {
104             if (packetChain.getPacket() instanceof RawPacket) {
105                 rawPacket = (RawPacket) packetChain.getPacket();
106             } else if (packetChain.getPacket() instanceof EthernetPacket) {
107                 ethernetPacket = (EthernetPacket) packetChain.getPacket();
108             } else if (packetChain.getPacket() instanceof Ipv4Packet) {
109                 ipv4Packet = (Ipv4Packet) packetChain.getPacket();
110             }
111         }
112         if (rawPacket == null || ethernetPacket == null || ipv4Packet == null) {
113             return;
114         }
115
116         if (IPV4_IP_TO_IGNORE.equals(ipv4Packet.getSourceIpv4().getValue())) {
117             return;
118         }
119
120         VlanId vlanId = null;
121         if (ethernetPacket.getEthertype().equals(KnownEtherType.VlanTagged)) {
122             vlanId = ethernetPacket.getHeader8021q().get(0).getVlan();
123         }
124         MacAddress sourceMac = ethernetPacket.getSourceMac();
125         IpAddress ipAddress = new IpAddress(ipv4Packet.getSourceIpv4());
126
127         Addresses addrs = createAddresses(sourceMac, vlanId, ipAddress, ethernetPacket.getEthertype());
128         if (addrs == null) {
129             return;
130         }
131         NodeConnectorRef ingress = rawPacket.getIngress();
132         hostTrackerImpl.packetReceived(addrs, ingress.getValue());
133     }
134
135     @Override
136     public void onIpv6PacketReceived(Ipv6PacketReceived packetReceived) {
137         if (packetReceived == null || packetReceived.getPacketChain() == null) {
138             return;
139         }
140
141         RawPacket rawPacket = null;
142         EthernetPacket ethernetPacket = null;
143         Ipv6Packet ipv6Packet = null;
144         for (PacketChain packetChain : packetReceived.getPacketChain()) {
145             if (packetChain.getPacket() instanceof RawPacket) {
146                 rawPacket = (RawPacket) packetChain.getPacket();
147             } else if (packetChain.getPacket() instanceof EthernetPacket) {
148                 ethernetPacket = (EthernetPacket) packetChain.getPacket();
149             } else if (packetChain.getPacket() instanceof Ipv6Packet) {
150                 ipv6Packet = (Ipv6Packet) packetChain.getPacket();
151             }
152         }
153         if (rawPacket == null || ethernetPacket == null || ipv6Packet == null) {
154             return;
155         }
156         if (IPV6_IP_TO_IGNORE.equals(ipv6Packet.getSourceIpv6().getValue())) {
157             return;
158         }
159
160         VlanId vlanId = null;
161         if (ethernetPacket.getEthertype().equals(KnownEtherType.VlanTagged)) {
162             vlanId = ethernetPacket.getHeader8021q().get(0).getVlan();
163         }
164         MacAddress sourceMac = ethernetPacket.getSourceMac();
165         IpAddress ipAddress = new IpAddress(ipv6Packet.getSourceIpv6());
166
167         Addresses addrs = createAddresses(sourceMac, vlanId, ipAddress, ethernetPacket.getEthertype());
168         if (addrs == null) {
169             return;
170         }
171         NodeConnectorRef ingress = rawPacket.getIngress();
172         hostTrackerImpl.packetReceived(addrs, ingress.getValue());
173     }
174
175     private Addresses createAddresses(MacAddress srcMacAddr, VlanId vlanId, IpAddress srcIpAddr,
176             KnownEtherType ketype) {
177         AddressesBuilder addrs = new AddressesBuilder();
178         if (srcMacAddr == null || srcIpAddr == null) {
179             return null;
180         }
181         /*
182          * TODO: if this is used, use a ReadWriteTranscation to figure out if
183          * there is an already existing addresses that has the same MAC, IP,
184          * VLAN triple and use it’s ID then, if there’s none, then we make up
185          * our own Addresses
186          */
187         BigInteger id = BigInteger.valueOf(ketype.getIntValue()).abs()
188                 .add(BigInteger.valueOf(srcMacAddr.hashCode()).abs().shiftLeft(16));
189         addrs.setId(id);
190         addrs.withKey(new AddressesKey(addrs.getId()));
191         addrs.setVlan(vlanId);
192         addrs.setIp(srcIpAddr);
193         addrs.setMac(srcMacAddr);
194         // addrs.setFirstSeen(new Date().getTime());
195         addrs.setLastSeen(new Date().getTime());
196         return addrs.build();
197     }
198 }