blob: eac5ba92aefb67ed038826267a6b886820fb6a66 [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;
24import org.onosproject.net.flow.DefaultTrafficSelector;
25import org.onosproject.net.flow.DefaultTrafficTreatment;
26import org.onosproject.net.flow.TrafficSelector;
27import org.onosproject.net.flow.TrafficTreatment;
28import org.onosproject.net.packet.DefaultOutboundPacket;
29import org.onosproject.net.packet.OutboundPacket;
30import org.onosproject.net.packet.PacketContext;
31import org.onosproject.net.packet.PacketPriority;
32import org.onosproject.net.packet.PacketProcessor;
33import org.onosproject.net.packet.PacketService;
34import org.onosproject.routingapi.config.BgpPeer;
35import org.onosproject.routingapi.config.BgpSpeaker;
36import org.onosproject.routingapi.config.InterfaceAddress;
37import org.onosproject.routingapi.config.RoutingConfigurationService;
38import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
41
42/**
43 * Manages connectivity between peers by tunnelling BGP traffic through
44 * OpenFlow packet-ins and packet-outs.
45 */
46public class TunnellingConnectivityManager {
47
48 private static final short BGP_PORT = 179;
49
50 private final ApplicationId appId;
51
52 private final PacketService packetService;
53 private final RoutingConfigurationService configService;
54
55 private final BgpProcessor processor = new BgpProcessor();
56
57 public TunnellingConnectivityManager(ApplicationId appId,
58 RoutingConfigurationService configService,
59 PacketService packetService) {
60 this.appId = appId;
61 this.configService = configService;
62 this.packetService = packetService;
63 }
64
65 public void start() {
66 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 3);
67
68 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
69
70 // Request packets with BGP port as their TCP source port
71 selector.matchEthType(Ethernet.TYPE_IPV4);
72 selector.matchIPProtocol(IPv4.PROTOCOL_TCP);
73 selector.matchTcpSrc(BGP_PORT);
74
75 packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
76 appId);
77
78 selector = DefaultTrafficSelector.builder();
79
80 // Request packets with BGP port as their TCP destination port
81 selector.matchEthType(Ethernet.TYPE_IPV4);
82 selector.matchIPProtocol(IPv4.PROTOCOL_TCP);
83 selector.matchTcpDst(BGP_PORT);
84
85 packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
86 appId);
87 }
88
89 public void stop() {
90 packetService.removeProcessor(processor);
91 // Should revoke packet requests in the future
92 }
93
94 /**
95 * Forwards a BGP packet to another connect point.
96 *
97 * @param context the packet context of the incoming packet
98 */
99 private void forward(PacketContext context) {
100
101 ConnectPoint outputPort = null;
102 Logger log = LoggerFactory.getLogger(getClass());
103
104
105 IPv4 ipv4 = (IPv4) context.inPacket().parsed().getPayload();
106 IpAddress dstAddress = IpAddress.valueOf(ipv4.getDestinationAddress());
107
108 for (BgpSpeaker speaker : configService.getBgpSpeakers().values()) {
109 if (context.inPacket().receivedFrom().equals(speaker.connectPoint())) {
110 BgpPeer peer = configService.getBgpPeers().get(dstAddress);
111 if (peer != null) {
112 outputPort = peer.connectPoint();
113 }
114 break;
115 }
116 for (InterfaceAddress addr : speaker.interfaceAddresses()) {
117 if (addr.ipAddress().equals(dstAddress) && !context.inPacket()
118 .receivedFrom().equals(speaker.connectPoint())) {
119 outputPort = speaker.connectPoint();
120 }
121 }
122 }
123
124 if (outputPort != null) {
125 TrafficTreatment t = DefaultTrafficTreatment.builder()
126 .setOutput(outputPort.port()).build();
127 OutboundPacket o = new DefaultOutboundPacket(
128 outputPort.deviceId(), t, context.inPacket().unparsed());
129 packetService.emit(o);
130 }
131 }
132
133 /**
134 * Packet processor responsible receiving and filtering BGP packets.
135 */
136 private class BgpProcessor implements PacketProcessor {
137
138 @Override
139 public void process(PacketContext context) {
140 // Stop processing if the packet has been handled, since we
141 // can't do any more to it.
142 if (context.isHandled()) {
143 return;
144 }
145
146 Ethernet packet = context.inPacket().parsed();
147
148 if (packet == null) {
149 return;
150 }
151
152 if (packet.getEtherType() == Ethernet.TYPE_IPV4) {
153 IPv4 ipv4Packet = (IPv4) packet.getPayload();
154 if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_TCP) {
155 TCP tcpPacket = (TCP) ipv4Packet.getPayload();
156
157 if (tcpPacket.getDestinationPort() == BGP_PORT ||
158 tcpPacket.getSourcePort() == BGP_PORT) {
159 forward(context);
160 }
161 }
162 }
163 }
164 }
165}