sangho
Committed by Gerrit Code Review

Add ICMP handler in bgp router app

Change-Id: I22a1dcdf5285e08c691767eb1ca41437e7ce1874
......@@ -138,6 +138,8 @@ public class BgpRouter {
private TunnellingConnectivityManager connectivityManager;
private IcmpHandler icmpHandler;
private InternalTableHandler provisionStaticTables = new InternalTableHandler();
@Activate
......@@ -154,10 +156,14 @@ public class BgpRouter {
packetService,
flowService);
icmpHandler = new IcmpHandler(configService, packetService);
routingService.start(new InternalFibListener());
connectivityManager.start();
icmpHandler.start();
log.info("BgpRouter started");
}
......@@ -165,6 +171,7 @@ public class BgpRouter {
protected void deactivate() {
routingService.stop();
connectivityManager.stop();
icmpHandler.stop();
provisionStaticTables.provision(false, configService.getInterfaces());
groupService.removeListener(groupListener);
......@@ -186,6 +193,7 @@ public class BgpRouter {
deviceId = s.interfaceAddresses().get(0).connectPoint().deviceId();
break;
}
log.info("Router dpid: {}", deviceId);
log.info("Control Plane OVS dpid: {}", ctrlDeviceId);
}
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.bgprouter;
import java.nio.ByteBuffer;
import org.onlab.packet.Ethernet;
import org.onlab.packet.ICMP;
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.host.InterfaceIpAddress;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.routing.config.Interface;
import org.onosproject.routing.config.RoutingConfigurationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IcmpHandler {
private static final Logger log = LoggerFactory.getLogger(IcmpHandler.class);
private final PacketService packetService;
private final RoutingConfigurationService configService;
private final IcmpProcessor processor = new IcmpProcessor();
public IcmpHandler(RoutingConfigurationService configService,
PacketService packetService) {
this.configService = configService;
this.packetService = packetService;
}
public void start() {
packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 4);
}
public void stop() {
packetService.removeProcessor(processor);
}
private void processPacketIn(InboundPacket pkt) {
boolean ipMatches = false;
Ethernet ethernet = pkt.parsed();
IPv4 ipv4 = (IPv4) ethernet.getPayload();
ConnectPoint connectPoint = pkt.receivedFrom();
IpAddress destIpAddress = IpAddress.valueOf(ipv4.getDestinationAddress());
Interface targetInterface = configService.getMatchingInterface(destIpAddress);
if (targetInterface == null) {
log.trace("No matching interface for {}", destIpAddress);
return;
}
for (InterfaceIpAddress interfaceIpAddress: targetInterface.ipAddresses()) {
if (interfaceIpAddress.ipAddress().equals(destIpAddress)) {
ipMatches = true;
break;
}
}
if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST &&
ipMatches) {
sendICMPResponse(ethernet, connectPoint);
}
}
private void sendICMPResponse(Ethernet icmpRequest, ConnectPoint outport) {
Ethernet icmpReplyEth = new Ethernet();
IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload();
IPv4 icmpReplyIpv4 = new IPv4();
int destAddress = icmpRequestIpv4.getDestinationAddress();
icmpReplyIpv4.setDestinationAddress(icmpRequestIpv4.getSourceAddress());
icmpReplyIpv4.setSourceAddress(destAddress);
icmpReplyIpv4.setTtl((byte) 64);
icmpReplyIpv4.setChecksum((short) 0);
ICMP icmpReply = (ICMP) icmpRequestIpv4.getPayload().clone();
icmpReply.setIcmpType(ICMP.TYPE_ECHO_REPLY);
icmpReply.setIcmpCode(ICMP.SUBTYPE_ECHO_REPLY);
icmpReply.setChecksum((short) 0);
icmpReplyIpv4.setPayload(icmpReply);
icmpReplyEth.setPayload(icmpReplyIpv4);
icmpReplyEth.setEtherType(Ethernet.TYPE_IPV4);
icmpReplyEth.setDestinationMACAddress(icmpRequest.getSourceMACAddress());
icmpReplyEth.setSourceMACAddress(icmpRequest.getDestinationMACAddress());
icmpReplyEth.setVlanID(icmpRequest.getVlanID());
sendPacketOut(outport, icmpReplyEth);
}
private void sendPacketOut(ConnectPoint outport, Ethernet payload) {
TrafficTreatment treatment = DefaultTrafficTreatment.builder().
setOutput(outport.port()).build();
OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
treatment, ByteBuffer.wrap(payload.serialize()));
packetService.emit(packet);
}
/**
* Packet processor responsible receiving and filtering ICMP packets.
*/
private class IcmpProcessor implements PacketProcessor {
@Override
public void process(PacketContext context) {
// Stop processing if the packet has been handled, since we
// can't do any more to it.
if (context.isHandled()) {
return;
}
Ethernet packet = context.inPacket().parsed();
if (packet == null) {
return;
}
if (packet.getEtherType() == Ethernet.TYPE_IPV4) {
IPv4 ipv4Packet = (IPv4) packet.getPayload();
if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_ICMP) {
processPacketIn(context.inPacket());
}
}
}
}
}
......@@ -29,6 +29,10 @@ public class ICMP extends BasePacket {
protected byte icmpCode;
protected short checksum;
public static final byte TYPE_ECHO_REQUEST = 0x08;
public static final byte TYPE_ECHO_REPLY = 0x00;
public static final byte SUBTYPE_ECHO_REPLY = 0x00;
/**
* @return the icmpType
*/
......