sangho
Committed by Gerrit Code Review

Add ICMP handler in bgp router app

Change-Id: I22a1dcdf5285e08c691767eb1ca41437e7ce1874
...@@ -138,6 +138,8 @@ public class BgpRouter { ...@@ -138,6 +138,8 @@ public class BgpRouter {
138 138
139 private TunnellingConnectivityManager connectivityManager; 139 private TunnellingConnectivityManager connectivityManager;
140 140
141 + private IcmpHandler icmpHandler;
142 +
141 private InternalTableHandler provisionStaticTables = new InternalTableHandler(); 143 private InternalTableHandler provisionStaticTables = new InternalTableHandler();
142 144
143 @Activate 145 @Activate
...@@ -154,10 +156,14 @@ public class BgpRouter { ...@@ -154,10 +156,14 @@ public class BgpRouter {
154 packetService, 156 packetService,
155 flowService); 157 flowService);
156 158
159 + icmpHandler = new IcmpHandler(configService, packetService);
160 +
157 routingService.start(new InternalFibListener()); 161 routingService.start(new InternalFibListener());
158 162
159 connectivityManager.start(); 163 connectivityManager.start();
160 164
165 + icmpHandler.start();
166 +
161 log.info("BgpRouter started"); 167 log.info("BgpRouter started");
162 } 168 }
163 169
...@@ -165,6 +171,7 @@ public class BgpRouter { ...@@ -165,6 +171,7 @@ public class BgpRouter {
165 protected void deactivate() { 171 protected void deactivate() {
166 routingService.stop(); 172 routingService.stop();
167 connectivityManager.stop(); 173 connectivityManager.stop();
174 + icmpHandler.stop();
168 provisionStaticTables.provision(false, configService.getInterfaces()); 175 provisionStaticTables.provision(false, configService.getInterfaces());
169 176
170 groupService.removeListener(groupListener); 177 groupService.removeListener(groupListener);
...@@ -186,6 +193,7 @@ public class BgpRouter { ...@@ -186,6 +193,7 @@ public class BgpRouter {
186 deviceId = s.interfaceAddresses().get(0).connectPoint().deviceId(); 193 deviceId = s.interfaceAddresses().get(0).connectPoint().deviceId();
187 break; 194 break;
188 } 195 }
196 +
189 log.info("Router dpid: {}", deviceId); 197 log.info("Router dpid: {}", deviceId);
190 log.info("Control Plane OVS dpid: {}", ctrlDeviceId); 198 log.info("Control Plane OVS dpid: {}", ctrlDeviceId);
191 } 199 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.bgprouter;
17 +
18 +import java.nio.ByteBuffer;
19 +
20 +import org.onlab.packet.Ethernet;
21 +import org.onlab.packet.ICMP;
22 +import org.onlab.packet.IPv4;
23 +import org.onlab.packet.IpAddress;
24 +import org.onosproject.net.ConnectPoint;
25 +import org.onosproject.net.flow.DefaultTrafficTreatment;
26 +import org.onosproject.net.flow.TrafficTreatment;
27 +import org.onosproject.net.host.InterfaceIpAddress;
28 +import org.onosproject.net.packet.DefaultOutboundPacket;
29 +import org.onosproject.net.packet.InboundPacket;
30 +import org.onosproject.net.packet.OutboundPacket;
31 +import org.onosproject.net.packet.PacketContext;
32 +import org.onosproject.net.packet.PacketProcessor;
33 +import org.onosproject.net.packet.PacketService;
34 +import org.onosproject.routing.config.Interface;
35 +import org.onosproject.routing.config.RoutingConfigurationService;
36 +import org.slf4j.Logger;
37 +import org.slf4j.LoggerFactory;
38 +
39 +public class IcmpHandler {
40 +
41 + private static final Logger log = LoggerFactory.getLogger(IcmpHandler.class);
42 +
43 + private final PacketService packetService;
44 + private final RoutingConfigurationService configService;
45 +
46 + private final IcmpProcessor processor = new IcmpProcessor();
47 +
48 +
49 + public IcmpHandler(RoutingConfigurationService configService,
50 + PacketService packetService) {
51 + this.configService = configService;
52 + this.packetService = packetService;
53 + }
54 +
55 + public void start() {
56 + packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 4);
57 + }
58 +
59 + public void stop() {
60 + packetService.removeProcessor(processor);
61 + }
62 +
63 + private void processPacketIn(InboundPacket pkt) {
64 +
65 + boolean ipMatches = false;
66 + Ethernet ethernet = pkt.parsed();
67 + IPv4 ipv4 = (IPv4) ethernet.getPayload();
68 + ConnectPoint connectPoint = pkt.receivedFrom();
69 + IpAddress destIpAddress = IpAddress.valueOf(ipv4.getDestinationAddress());
70 + Interface targetInterface = configService.getMatchingInterface(destIpAddress);
71 +
72 + if (targetInterface == null) {
73 + log.trace("No matching interface for {}", destIpAddress);
74 + return;
75 + }
76 +
77 + for (InterfaceIpAddress interfaceIpAddress: targetInterface.ipAddresses()) {
78 + if (interfaceIpAddress.ipAddress().equals(destIpAddress)) {
79 + ipMatches = true;
80 + break;
81 + }
82 + }
83 +
84 + if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST &&
85 + ipMatches) {
86 + sendICMPResponse(ethernet, connectPoint);
87 + }
88 + }
89 +
90 + private void sendICMPResponse(Ethernet icmpRequest, ConnectPoint outport) {
91 +
92 + Ethernet icmpReplyEth = new Ethernet();
93 +
94 + IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload();
95 + IPv4 icmpReplyIpv4 = new IPv4();
96 +
97 + int destAddress = icmpRequestIpv4.getDestinationAddress();
98 + icmpReplyIpv4.setDestinationAddress(icmpRequestIpv4.getSourceAddress());
99 + icmpReplyIpv4.setSourceAddress(destAddress);
100 + icmpReplyIpv4.setTtl((byte) 64);
101 + icmpReplyIpv4.setChecksum((short) 0);
102 +
103 + ICMP icmpReply = (ICMP) icmpRequestIpv4.getPayload().clone();
104 + icmpReply.setIcmpType(ICMP.TYPE_ECHO_REPLY);
105 + icmpReply.setIcmpCode(ICMP.SUBTYPE_ECHO_REPLY);
106 + icmpReply.setChecksum((short) 0);
107 +
108 + icmpReplyIpv4.setPayload(icmpReply);
109 +
110 + icmpReplyEth.setPayload(icmpReplyIpv4);
111 + icmpReplyEth.setEtherType(Ethernet.TYPE_IPV4);
112 + icmpReplyEth.setDestinationMACAddress(icmpRequest.getSourceMACAddress());
113 + icmpReplyEth.setSourceMACAddress(icmpRequest.getDestinationMACAddress());
114 + icmpReplyEth.setVlanID(icmpRequest.getVlanID());
115 +
116 + sendPacketOut(outport, icmpReplyEth);
117 +
118 + }
119 +
120 + private void sendPacketOut(ConnectPoint outport, Ethernet payload) {
121 + TrafficTreatment treatment = DefaultTrafficTreatment.builder().
122 + setOutput(outport.port()).build();
123 + OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
124 + treatment, ByteBuffer.wrap(payload.serialize()));
125 + packetService.emit(packet);
126 + }
127 +
128 + /**
129 + * Packet processor responsible receiving and filtering ICMP packets.
130 + */
131 + private class IcmpProcessor implements PacketProcessor {
132 +
133 + @Override
134 + public void process(PacketContext context) {
135 + // Stop processing if the packet has been handled, since we
136 + // can't do any more to it.
137 +
138 + if (context.isHandled()) {
139 + return;
140 + }
141 +
142 + Ethernet packet = context.inPacket().parsed();
143 +
144 + if (packet == null) {
145 + return;
146 + }
147 +
148 + if (packet.getEtherType() == Ethernet.TYPE_IPV4) {
149 + IPv4 ipv4Packet = (IPv4) packet.getPayload();
150 + if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_ICMP) {
151 + processPacketIn(context.inPacket());
152 + }
153 + }
154 + }
155 + }
156 +
157 +}
...@@ -29,6 +29,10 @@ public class ICMP extends BasePacket { ...@@ -29,6 +29,10 @@ public class ICMP extends BasePacket {
29 protected byte icmpCode; 29 protected byte icmpCode;
30 protected short checksum; 30 protected short checksum;
31 31
32 + public static final byte TYPE_ECHO_REQUEST = 0x08;
33 + public static final byte TYPE_ECHO_REPLY = 0x00;
34 + public static final byte SUBTYPE_ECHO_REPLY = 0x00;
35 +
32 /** 36 /**
33 * @return the icmpType 37 * @return the icmpType
34 */ 38 */
......