blob: a1327c0ce0e2029bf3f9053a401044ad6b031d8a [file] [log] [blame]
sanghob35a6192015-04-01 13:05:26 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
sanghob35a6192015-04-01 13:05:26 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.segmentrouting;
17
sanghob35a6192015-04-01 13:05:26 -070018import org.onlab.packet.Ethernet;
19import org.onlab.packet.ICMP;
Pier Ventre735b8c82016-12-02 08:16:05 -080020import org.onlab.packet.ICMP6;
sanghob35a6192015-04-01 13:05:26 -070021import org.onlab.packet.IPv4;
Pier Ventre735b8c82016-12-02 08:16:05 -080022import org.onlab.packet.IPv6;
sanghob35a6192015-04-01 13:05:26 -070023import org.onlab.packet.Ip4Address;
Pier Ventref4b5fce2016-11-28 16:48:06 -080024import org.onlab.packet.Ip6Address;
Pier Ventree0ae7a32016-11-23 09:57:42 -080025import org.onlab.packet.IpAddress;
sanghob35a6192015-04-01 13:05:26 -070026import org.onlab.packet.IpPrefix;
27import org.onlab.packet.MPLS;
Pier Ventref4b5fce2016-11-28 16:48:06 -080028import org.onlab.packet.MacAddress;
29import org.onlab.packet.VlanId;
Pier Ventre735b8c82016-12-02 08:16:05 -080030import org.onlab.packet.ndp.NeighborSolicitation;
Pier Ventre10bd8d12016-11-26 21:05:22 -080031import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
Pier Ventref4b5fce2016-11-28 16:48:06 -080032import org.onosproject.incubator.net.neighbour.NeighbourMessageType;
sanghob35a6192015-04-01 13:05:26 -070033import org.onosproject.net.ConnectPoint;
34import org.onosproject.net.DeviceId;
35import org.onosproject.net.flow.DefaultTrafficTreatment;
36import org.onosproject.net.flow.TrafficTreatment;
Pier Ventref4b5fce2016-11-28 16:48:06 -080037import org.onosproject.net.host.HostService;
sanghob35a6192015-04-01 13:05:26 -070038import org.onosproject.net.packet.DefaultOutboundPacket;
Pier Luigi7dad71c2017-02-01 13:50:04 -080039import org.onosproject.net.packet.InboundPacket;
sanghob35a6192015-04-01 13:05:26 -070040import org.onosproject.net.packet.OutboundPacket;
Pier Luigi7dad71c2017-02-01 13:50:04 -080041import org.onosproject.net.packet.PacketContext;
Charles Chan0b4e6182015-11-03 10:42:14 -080042import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
Pier Ventref4b5fce2016-11-28 16:48:06 -080043import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
sanghob35a6192015-04-01 13:05:26 -070044import org.slf4j.Logger;
45import org.slf4j.LoggerFactory;
46
Jonathan Hart2a655752015-04-07 16:46:33 -070047import java.nio.ByteBuffer;
Saurav Das837e0bb2015-10-30 17:45:38 -070048import java.util.Set;
Jonathan Hart2a655752015-04-07 16:46:33 -070049
Charles Chane849c192016-01-11 18:28:54 -080050/**
51 * Handler of ICMP packets that responses or forwards ICMP packets that
52 * are sent to the controller.
53 */
Pier Ventre735b8c82016-12-02 08:16:05 -080054public class IcmpHandler extends SegmentRoutingNeighbourHandler {
sanghob35a6192015-04-01 13:05:26 -070055
56 private static Logger log = LoggerFactory.getLogger(IcmpHandler.class);
sanghob35a6192015-04-01 13:05:26 -070057
58 /**
59 * Creates an IcmpHandler object.
60 *
61 * @param srManager SegmentRoutingManager object
62 */
63 public IcmpHandler(SegmentRoutingManager srManager) {
Pier Ventre735b8c82016-12-02 08:16:05 -080064 super(srManager);
65 }
66
67 /**
68 * Utility function to send packet out.
69 *
70 * @param outport the output port
71 * @param payload the packet to send
72 * @param sid the segment id
73 * @param destIpAddress the destination ip address
74 * @param allowedHops the hop limit/ttl
75 */
76 private void sendPacketOut(ConnectPoint outport,
77 Ethernet payload,
78 int sid,
79 IpAddress destIpAddress,
80 byte allowedHops) {
81 int destSid;
82 if (destIpAddress.isIp4()) {
83 destSid = config.getIPv4SegmentId(payload.getDestinationMAC());
84 } else {
85 destSid = config.getIPv6SegmentId(payload.getDestinationMAC());
86 }
87
88 if (sid == -1 || destSid == sid ||
89 config.inSameSubnet(outport.deviceId(), destIpAddress)) {
90 TrafficTreatment treatment = DefaultTrafficTreatment.builder().
91 setOutput(outport.port()).build();
92 OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
93 treatment, ByteBuffer.wrap(payload.serialize()));
94 srManager.packetService.emit(packet);
95 } else {
96 log.debug("Send a MPLS packet as a ICMP response");
97 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
98 .setOutput(outport.port())
99 .build();
100
101 payload.setEtherType(Ethernet.MPLS_UNICAST);
102 MPLS mplsPkt = new MPLS();
103 mplsPkt.setLabel(sid);
104 mplsPkt.setTtl(allowedHops);
105 mplsPkt.setPayload(payload.getPayload());
106 payload.setPayload(mplsPkt);
107
108 OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
109 treatment, ByteBuffer.wrap(payload.serialize()));
110
111 srManager.packetService.emit(packet);
112 }
sanghob35a6192015-04-01 13:05:26 -0700113 }
114
Pier Ventref4b5fce2016-11-28 16:48:06 -0800115 //////////////////////////////////////
116 // ICMP Echo/Reply Protocol //
117 //////////////////////////////////////
118
sanghob35a6192015-04-01 13:05:26 -0700119 /**
120 * Process incoming ICMP packet.
121 * If it is an ICMP request to router or known host, then sends an ICMP response.
122 * If it is an ICMP packet to known host and forward the packet to the host.
123 * If it is an ICMP packet to unknown host in a subnet, then sends an ARP request
124 * to the subnet.
125 *
Pier Ventre735b8c82016-12-02 08:16:05 -0800126 * @param eth inbound ICMP packet
127 * @param inPort the input port
sanghob35a6192015-04-01 13:05:26 -0700128 */
Pier Ventre735b8c82016-12-02 08:16:05 -0800129 public void processIcmp(Ethernet eth, ConnectPoint inPort) {
130 DeviceId deviceId = inPort.deviceId();
131 IPv4 ipv4Packet = (IPv4) eth.getPayload();
132 Ip4Address destinationAddress = Ip4Address.valueOf(ipv4Packet.getDestinationAddress());
Pier Ventre10bd8d12016-11-26 21:05:22 -0800133 Set<IpAddress> gatewayIpAddresses = config.getPortIPs(deviceId);
Pier Ventree0ae7a32016-11-23 09:57:42 -0800134 IpAddress routerIp;
Charles Chan0b4e6182015-11-03 10:42:14 -0800135 try {
Pier Ventree0ae7a32016-11-23 09:57:42 -0800136 routerIp = config.getRouterIpv4(deviceId);
Charles Chan0b4e6182015-11-03 10:42:14 -0800137 } catch (DeviceConfigNotFoundException e) {
138 log.warn(e.getMessage() + " Aborting processPacketIn.");
139 return;
140 }
sanghob35a6192015-04-01 13:05:26 -0700141 // ICMP to the router IP or gateway IP
Pier Ventre735b8c82016-12-02 08:16:05 -0800142 if (((ICMP) ipv4Packet.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST &&
143 (destinationAddress.equals(routerIp.getIp4Address()) ||
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700144 gatewayIpAddresses.contains(destinationAddress))) {
Pier Ventre735b8c82016-12-02 08:16:05 -0800145 sendIcmpResponse(eth, inPort);
146 // We remove the packet from the queue
147 srManager.ipHandler.dequeuePacket(ipv4Packet, destinationAddress);
sanghob35a6192015-04-01 13:05:26 -0700148
149 // ICMP for any known host
150 } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
Saurav Das4ce45962015-11-24 23:21:05 -0800151 // TODO: known host packet should not be coming to controller - resend flows?
sanghob35a6192015-04-01 13:05:26 -0700152 srManager.ipHandler.forwardPackets(deviceId, destinationAddress);
153
154 // ICMP for an unknown host in the subnet of the router
155 } else if (config.inSameSubnet(deviceId, destinationAddress)) {
Pier Ventre735b8c82016-12-02 08:16:05 -0800156 srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, inPort);
sanghob35a6192015-04-01 13:05:26 -0700157
158 // ICMP for an unknown host
159 } else {
160 log.debug("ICMP request for unknown host {} ", destinationAddress);
Pier Ventre735b8c82016-12-02 08:16:05 -0800161 // We remove the packet from the queue
162 srManager.ipHandler.dequeuePacket(ipv4Packet, destinationAddress);
sanghob35a6192015-04-01 13:05:26 -0700163 }
164 }
165
Charles Chan68aa62d2015-11-09 16:37:23 -0800166 /**
167 * Sends an ICMP reply message.
168 *
169 * Note: we assume that packets sending from the edge switches to the hosts
170 * have untagged VLAN.
171 * @param icmpRequest the original ICMP request
172 * @param outport the output port where the ICMP reply should be sent to
173 */
Pier Ventree0ae7a32016-11-23 09:57:42 -0800174 private void sendIcmpResponse(Ethernet icmpRequest, ConnectPoint outport) {
Charles Chan68aa62d2015-11-09 16:37:23 -0800175 // Note: We assume that packets arrive at the edge switches have
176 // untagged VLAN.
Pier Ventre735b8c82016-12-02 08:16:05 -0800177 Ethernet icmpReplyEth = ICMP.buildIcmpReply(icmpRequest);
sanghob35a6192015-04-01 13:05:26 -0700178 IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload();
Pier Ventre735b8c82016-12-02 08:16:05 -0800179 IPv4 icmpReplyIpv4 = (IPv4) icmpReplyEth.getPayload();
180 Ip4Address destIpAddress = Ip4Address.valueOf(icmpRequestIpv4.getSourceAddress());
sangho666cd6d2015-04-14 16:27:13 -0700181 Ip4Address destRouterAddress = config.getRouterIpAddressForASubnetHost(destIpAddress);
Pier Ventree0ae7a32016-11-23 09:57:42 -0800182 int destSid = config.getIPv4SegmentId(destRouterAddress);
Charles Chan68aaad52016-12-09 12:54:49 -0800183 if (destSid < 0) {
Pier Ventre735b8c82016-12-02 08:16:05 -0800184 log.warn("Cannot find the Segment ID for {}", destIpAddress);
sanghob35a6192015-04-01 13:05:26 -0700185 return;
186 }
Pier Ventre735b8c82016-12-02 08:16:05 -0800187 sendPacketOut(outport, icmpReplyEth, destSid, destIpAddress, icmpReplyIpv4.getTtl());
sanghob35a6192015-04-01 13:05:26 -0700188 }
189
Pier Ventre735b8c82016-12-02 08:16:05 -0800190 ///////////////////////////////////////////
191 // ICMPv6 Echo/Reply Protocol //
192 ///////////////////////////////////////////
sanghob35a6192015-04-01 13:05:26 -0700193
Pier Ventre735b8c82016-12-02 08:16:05 -0800194 /**
195 * Process incoming ICMPv6 packet.
196 * If it is an ICMP request to router or known host, then sends an ICMP response.
197 * If it is an ICMP packet to known host and forward the packet to the host.
198 * If it is an ICMP packet to unknown host in a subnet, then sends an ARP request
199 * to the subnet.
200 *
201 * @param eth the incoming ICMPv6 packet
202 * @param inPort the input port
203 */
204 public void processIcmpv6(Ethernet eth, ConnectPoint inPort) {
205 DeviceId deviceId = inPort.deviceId();
206 IPv6 ipv6Packet = (IPv6) eth.getPayload();
207 Ip6Address destinationAddress = Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
208 Set<IpAddress> gatewayIpAddresses = config.getPortIPs(deviceId);
209 IpAddress routerIp;
210 try {
211 routerIp = config.getRouterIpv6(deviceId);
212 } catch (DeviceConfigNotFoundException e) {
213 log.warn(e.getMessage() + " Aborting processPacketIn.");
214 return;
sanghob35a6192015-04-01 13:05:26 -0700215 }
Pier Ventre735b8c82016-12-02 08:16:05 -0800216 ICMP6 icmp6 = (ICMP6) ipv6Packet.getPayload();
217 // ICMP to the router IP or gateway IP
218 if (icmp6.getIcmpType() == ICMP6.ECHO_REQUEST &&
219 (destinationAddress.equals(routerIp.getIp6Address()) ||
220 gatewayIpAddresses.contains(destinationAddress))) {
221 sendIcmpv6Response(eth, inPort);
222 // We remove the packet from the queue
223 srManager.ipHandler.dequeuePacket(ipv6Packet, destinationAddress);
224 // ICMP for any known host
225 } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
226 // TODO: known host packet should not be coming to controller - resend flows?
227 srManager.ipHandler.forwardPackets(deviceId, destinationAddress);
228 // ICMP for an unknown host in the subnet of the router
229 } else if (config.inSameSubnet(deviceId, destinationAddress)) {
230 sendNdpRequest(deviceId, destinationAddress, inPort);
231 // ICMP for an unknown host or not configured host
232 } else {
233 log.debug("ICMPv6 request for unknown host or not configured host {} ", destinationAddress);
234 // We remove the packet from the queue
235 srManager.ipHandler.dequeuePacket(ipv6Packet, destinationAddress);
236 }
237 }
238
239 /**
240 * Sends an ICMPv6 reply message.
241 *
242 * Note: we assume that packets sending from the edge switches to the hosts
243 * have untagged VLAN.
244 * @param ethRequest the original ICMP request
245 * @param outport the output port where the ICMP reply should be sent to
246 */
247 private void sendIcmpv6Response(Ethernet ethRequest, ConnectPoint outport) {
248 // Note: We assume that packets arrive at the edge switches have
249 // untagged VLAN.
250 Ethernet ethReply = ICMP6.buildIcmp6Reply(ethRequest);
251 IPv6 icmpRequestIpv6 = (IPv6) ethRequest.getPayload();
252 IPv6 icmpReplyIpv6 = (IPv6) ethRequest.getPayload();
253 Ip6Address destIpAddress = Ip6Address.valueOf(icmpRequestIpv6.getSourceAddress());
254 Ip6Address destRouterAddress = config.getRouterIpAddressForASubnetHost(destIpAddress);
255 int sid = config.getIPv6SegmentId(destRouterAddress);
256 if (sid < 0) {
257 log.warn("Cannot find the Segment ID for {}", destIpAddress);
258 return;
259 }
260 sendPacketOut(outport, ethReply, sid, destIpAddress, icmpReplyIpv6.getHopLimit());
sanghob35a6192015-04-01 13:05:26 -0700261 }
sangho666cd6d2015-04-14 16:27:13 -0700262
Pier Ventref4b5fce2016-11-28 16:48:06 -0800263 ///////////////////////////////////////////
264 // ICMPv6 Neighbour Discovery Protocol //
265 ///////////////////////////////////////////
sangho666cd6d2015-04-14 16:27:13 -0700266
Pier Ventref4b5fce2016-11-28 16:48:06 -0800267 /**
268 * Process incoming NDP packet.
269 *
270 * If it is an NDP request for the router or for the gateway, then sends a NDP reply.
271 * If it is an NDP request to unknown host flood in the subnet.
272 * If it is an NDP packet to known host forward the packet to the host.
273 *
274 * FIXME If the NDP packets use link local addresses we fail.
275 *
276 * @param pkt inbound packet
277 * @param hostService the host service
278 */
279 public void processPacketIn(NeighbourMessageContext pkt, HostService hostService) {
280 /*
281 * First we validate the ndp packet
282 */
283 SegmentRoutingAppConfig appConfig = srManager.cfgService
284 .getConfig(srManager.appId, SegmentRoutingAppConfig.class);
285 if (appConfig != null && appConfig.suppressSubnet().contains(pkt.inPort())) {
286 // Ignore NDP packets come from suppressed ports
287 pkt.drop();
288 return;
289 }
290 if (!validateSrcIp(pkt)) {
291 log.debug("Ignore NDP packet discovered on {} with unexpected src ip address {}.",
292 pkt.inPort(), pkt.sender());
293 pkt.drop();
294 return;
295 }
296
297 if (pkt.type() == NeighbourMessageType.REQUEST) {
298 handleNdpRequest(pkt, hostService);
299 } else {
300 handleNdpReply(pkt, hostService);
301 }
302
303 }
304
305 /**
306 * Utility function to verify if the src ip belongs to the same
307 * subnet configured on the port it is seen.
308 *
309 * @param pkt the ndp packet and context information
310 * @return true if the src ip is a valid address for the subnet configured
311 * for the connect point
312 */
313 private boolean validateSrcIp(NeighbourMessageContext pkt) {
314 ConnectPoint connectPoint = pkt.inPort();
315 IpPrefix subnet = config.getPortIPv6Subnet(
316 connectPoint.deviceId(),
317 connectPoint.port()
Pier Luigi0e358632017-01-31 09:35:05 -0800318 );
Pier Ventref4b5fce2016-11-28 16:48:06 -0800319 return subnet != null && subnet.contains(pkt.sender());
320 }
321
322 /**
323 * Helper method to handle the ndp requests.
324 *
325 * @param pkt the ndp packet request and context information
326 * @param hostService the host service
327 */
328 private void handleNdpRequest(NeighbourMessageContext pkt, HostService hostService) {
Charles Chan563a7812017-02-27 15:50:43 -0800329 // ND request for the gateway. We have to reply on behalf of the gateway.
Pier Ventref4b5fce2016-11-28 16:48:06 -0800330 if (isNdpForGateway(pkt)) {
331 log.debug("Sending NDP reply on behalf of the router");
Pier Ventre735b8c82016-12-02 08:16:05 -0800332 sendResponse(pkt, config.getRouterMacForAGatewayIp(pkt.target()), hostService);
Pier Ventref4b5fce2016-11-28 16:48:06 -0800333 } else {
Charles Chan563a7812017-02-27 15:50:43 -0800334 // NOTE: Ignore NDP packets except those target for the router
335 // We will reconsider enabling this when we have host learning support
Pier Ventref4b5fce2016-11-28 16:48:06 -0800336 /*
Charles Chan563a7812017-02-27 15:50:43 -0800337 // ND request for an host. We do a search by Ip.
Pier Ventref4b5fce2016-11-28 16:48:06 -0800338 Set<Host> hosts = hostService.getHostsByIp(pkt.target());
Charles Chan563a7812017-02-27 15:50:43 -0800339 // Possible misconfiguration ? In future this case
340 // should be handled we can have same hosts in different VLANs.
Pier Ventref4b5fce2016-11-28 16:48:06 -0800341 if (hosts.size() > 1) {
342 log.warn("More than one host with IP {}", pkt.target());
343 }
344 Host targetHost = hosts.stream().findFirst().orElse(null);
Charles Chan563a7812017-02-27 15:50:43 -0800345 // If we know the host forward to its attachment point.
Pier Ventref4b5fce2016-11-28 16:48:06 -0800346 if (targetHost != null) {
347 log.debug("Forward NDP request to the target host");
348 pkt.forward(targetHost.location());
349 } else {
Charles Chan563a7812017-02-27 15:50:43 -0800350 // Flood otherwise.
Pier Ventref4b5fce2016-11-28 16:48:06 -0800351 log.debug("Flood NDP request to the target subnet");
352 flood(pkt);
353 }
Charles Chan563a7812017-02-27 15:50:43 -0800354 */
Pier Ventref4b5fce2016-11-28 16:48:06 -0800355 }
356 }
357
358 /**
359 * Helper method to handle the ndp replies.
360 *
361 * @param pkt the ndp packet reply and context information
362 * @param hostService the host service
363 */
364 private void handleNdpReply(NeighbourMessageContext pkt, HostService hostService) {
365 if (isNdpForGateway(pkt)) {
366 log.debug("Forwarding all the ip packets we stored");
367 Ip6Address hostIpAddress = pkt.sender().getIp6Address();
368 srManager.ipHandler.forwardPackets(pkt.inPort().deviceId(), hostIpAddress);
369 } else {
Charles Chan563a7812017-02-27 15:50:43 -0800370 // NOTE: Ignore NDP packets except those target for the router
371 // We will reconsider enabling this when we have host learning support
372 /*
Pier Ventref4b5fce2016-11-28 16:48:06 -0800373 HostId hostId = HostId.hostId(pkt.dstMac(), pkt.vlan());
374 Host targetHost = hostService.getHost(hostId);
375 if (targetHost != null) {
376 log.debug("Forwarding the reply to the host");
377 pkt.forward(targetHost.location());
378 } else {
Charles Chan563a7812017-02-27 15:50:43 -0800379 // We don't have to flood towards spine facing ports.
Charles Chan59cc16d2017-02-02 16:20:42 -0800380 if (pkt.vlan().equals(SegmentRoutingManager.INTERNAL_VLAN)) {
Pier Ventref4b5fce2016-11-28 16:48:06 -0800381 return;
382 }
383 log.debug("Flooding the reply to the subnet");
384 flood(pkt);
385 }
Charles Chan563a7812017-02-27 15:50:43 -0800386 */
Pier Ventref4b5fce2016-11-28 16:48:06 -0800387 }
388 }
389
390 /**
391 * Utility to verify if the ND are for the gateway.
392 *
393 * @param pkt the ndp packet
394 * @return true if the ndp is for the gateway. False otherwise
395 */
396 private boolean isNdpForGateway(NeighbourMessageContext pkt) {
397 DeviceId deviceId = pkt.inPort().deviceId();
398 Set<IpAddress> gatewayIpAddresses = null;
399 try {
400 if (pkt.target().equals(config.getRouterIpv6(deviceId))) {
401 return true;
402 }
403 gatewayIpAddresses = config.getPortIPs(deviceId);
404 } catch (DeviceConfigNotFoundException e) {
405 log.warn(e.getMessage() + " Aborting check for router IP in processing ndp");
406 }
407 if (gatewayIpAddresses != null &&
408 gatewayIpAddresses.contains(pkt.target())) {
409 return true;
410 }
411 return false;
412 }
413
414 /**
Pier Ventre735b8c82016-12-02 08:16:05 -0800415 * Sends a NDP request for the target IP address to all ports except in-port.
Pier Ventref4b5fce2016-11-28 16:48:06 -0800416 *
Pier Ventre735b8c82016-12-02 08:16:05 -0800417 * @param deviceId Switch device ID
418 * @param targetAddress target IP address for ARP
419 * @param inPort in-port
Pier Ventref4b5fce2016-11-28 16:48:06 -0800420 */
Pier Ventre735b8c82016-12-02 08:16:05 -0800421 public void sendNdpRequest(DeviceId deviceId, IpAddress targetAddress, ConnectPoint inPort) {
422 byte[] senderMacAddress = new byte[MacAddress.MAC_ADDRESS_LENGTH];
423 byte[] senderIpAddress = new byte[Ip6Address.BYTE_LENGTH];
424 /*
425 * Retrieves device info.
426 */
Pier Luigia905c0c2017-01-29 12:38:48 -0800427 if (!getSenderInfo(senderMacAddress, senderIpAddress, deviceId, targetAddress)) {
428 log.warn("Aborting sendNdpRequest, we cannot get all the information needed");
429 return;
430 }
Pier Ventre735b8c82016-12-02 08:16:05 -0800431 /*
432 * We have to compute the dst mac address and dst
433 * ip address.
434 */
435 byte[] dstIp = IPv6.getSolicitNodeAddress(targetAddress.toOctets());
436 byte[] dstMac = IPv6.getMCastMacAddress(dstIp);
437 /*
438 * Creates the request.
439 */
440 Ethernet ndpRequest = NeighborSolicitation.buildNdpSolicit(
441 targetAddress.toOctets(),
442 senderIpAddress,
443 dstIp,
444 senderMacAddress,
445 dstMac,
446 VlanId.NONE
447 );
448 flood(ndpRequest, inPort, targetAddress);
Pier Ventref4b5fce2016-11-28 16:48:06 -0800449 }
450
Pier Luigi7dad71c2017-02-01 13:50:04 -0800451 /////////////////////////////////////////////////////////////////
452 // XXX Neighbour hacking, temporary workaround will be //
453 // removed as soon as possible, when the bridging will //
454 // be implemented. For now, it's fine to leave this //
455 /////////////////////////////////////////////////////////////////
456
Pier Luigi7dad71c2017-02-01 13:50:04 -0800457 // XXX Neighbour hacking, this method is used to handle
458 // the ICMPv6 protocols for the upstream port
459 public boolean handleUPstreamPackets(PacketContext packetContext) {
460 InboundPacket pkt = packetContext.inPacket();
461 Ethernet ethernet = pkt.parsed();
Pier Luigi721b6622017-02-03 13:34:21 -0800462 if (srManager.vRouterCP == null || srManager.upstreamCP == null) {
Pier Luigi7dad71c2017-02-01 13:50:04 -0800463 return false;
464 }
Pier Luigi721b6622017-02-03 13:34:21 -0800465 if (pkt.receivedFrom().equals(srManager.upstreamCP)) {
466 sendTo(ByteBuffer.wrap(ethernet.serialize()), srManager.vRouterCP);
Pier Luigi7dad71c2017-02-01 13:50:04 -0800467 return true;
468 }
469 return false;
470 }
471
Pier Luigi7dad71c2017-02-01 13:50:04 -0800472 // XXX Neigbour hack. To send out a packet
473 private void sendTo(ByteBuffer packet, ConnectPoint outPort) {
474 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
475 builder.setOutput(outPort.port());
476 srManager.packetService.emit(new DefaultOutboundPacket(outPort.deviceId(),
477 builder.build(), packet));
478 }
479
sanghob35a6192015-04-01 13:05:26 -0700480}