blob: 270a4dabf8f7e87e62ddf5aec2a7ac5854557321 [file] [log] [blame]
Jonathan Hartf5829202015-02-12 09:37:02 -08001/*
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 */
16package org.onosproject.bgprouter;
17
18import org.onlab.packet.Ethernet;
19import org.onlab.packet.IPv4;
20import org.onlab.packet.IpAddress;
21import org.onlab.packet.TCP;
22import org.onosproject.core.ApplicationId;
23import org.onosproject.net.ConnectPoint;
Jonathan Hartf5829202015-02-12 09:37:02 -080024import org.onosproject.net.flow.DefaultTrafficTreatment;
Jonathan Hartf5829202015-02-12 09:37:02 -080025import org.onosproject.net.flow.TrafficTreatment;
26import org.onosproject.net.packet.DefaultOutboundPacket;
27import org.onosproject.net.packet.OutboundPacket;
28import org.onosproject.net.packet.PacketContext;
Jonathan Hartf5829202015-02-12 09:37:02 -080029import org.onosproject.net.packet.PacketProcessor;
30import org.onosproject.net.packet.PacketService;
Jonathan Hart2da1e602015-02-18 19:09:24 -080031import org.onosproject.routing.config.BgpPeer;
32import org.onosproject.routing.config.BgpSpeaker;
33import org.onosproject.routing.config.InterfaceAddress;
34import org.onosproject.routing.config.RoutingConfigurationService;
Jonathan Hartf5829202015-02-12 09:37:02 -080035import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
37
38
39/**
40 * Manages connectivity between peers by tunnelling BGP traffic through
41 * OpenFlow packet-ins and packet-outs.
42 */
43public class TunnellingConnectivityManager {
44
45 private static final short BGP_PORT = 179;
46
47 private final ApplicationId appId;
48
49 private final PacketService packetService;
50 private final RoutingConfigurationService configService;
51
52 private final BgpProcessor processor = new BgpProcessor();
53
54 public TunnellingConnectivityManager(ApplicationId appId,
55 RoutingConfigurationService configService,
56 PacketService packetService) {
57 this.appId = appId;
58 this.configService = configService;
59 this.packetService = packetService;
60 }
61
62 public void start() {
63 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 3);
Jonathan Hartf5829202015-02-12 09:37:02 -080064 }
65
66 public void stop() {
67 packetService.removeProcessor(processor);
68 // Should revoke packet requests in the future
69 }
70
71 /**
72 * Forwards a BGP packet to another connect point.
73 *
74 * @param context the packet context of the incoming packet
75 */
76 private void forward(PacketContext context) {
77
78 ConnectPoint outputPort = null;
79 Logger log = LoggerFactory.getLogger(getClass());
80
81
82 IPv4 ipv4 = (IPv4) context.inPacket().parsed().getPayload();
83 IpAddress dstAddress = IpAddress.valueOf(ipv4.getDestinationAddress());
84
85 for (BgpSpeaker speaker : configService.getBgpSpeakers().values()) {
86 if (context.inPacket().receivedFrom().equals(speaker.connectPoint())) {
87 BgpPeer peer = configService.getBgpPeers().get(dstAddress);
88 if (peer != null) {
89 outputPort = peer.connectPoint();
90 }
91 break;
92 }
93 for (InterfaceAddress addr : speaker.interfaceAddresses()) {
94 if (addr.ipAddress().equals(dstAddress) && !context.inPacket()
95 .receivedFrom().equals(speaker.connectPoint())) {
96 outputPort = speaker.connectPoint();
97 }
98 }
99 }
100
101 if (outputPort != null) {
102 TrafficTreatment t = DefaultTrafficTreatment.builder()
103 .setOutput(outputPort.port()).build();
104 OutboundPacket o = new DefaultOutboundPacket(
105 outputPort.deviceId(), t, context.inPacket().unparsed());
106 packetService.emit(o);
107 }
108 }
109
110 /**
111 * Packet processor responsible receiving and filtering BGP packets.
112 */
113 private class BgpProcessor implements PacketProcessor {
114
115 @Override
116 public void process(PacketContext context) {
117 // Stop processing if the packet has been handled, since we
118 // can't do any more to it.
119 if (context.isHandled()) {
120 return;
121 }
122
123 Ethernet packet = context.inPacket().parsed();
124
125 if (packet == null) {
126 return;
127 }
128
129 if (packet.getEtherType() == Ethernet.TYPE_IPV4) {
130 IPv4 ipv4Packet = (IPv4) packet.getPayload();
131 if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_TCP) {
132 TCP tcpPacket = (TCP) ipv4Packet.getPayload();
133
134 if (tcpPacket.getDestinationPort() == BGP_PORT ||
135 tcpPacket.getSourcePort() == BGP_PORT) {
136 forward(context);
137 }
138 }
139 }
140 }
141 }
142}