Jonathan Hart
Committed by Gerrit Code Review

FPM component that can decode routes from Quagga's FIB push interface.

Change-Id: I57bfd9273b81c8d368a59a3acea53486cb4acfc1
Showing 22 changed files with 1575 additions and 24 deletions
...@@ -16,19 +16,19 @@ ...@@ -16,19 +16,19 @@
16 package org.onosproject.routing; 16 package org.onosproject.routing;
17 17
18 /** 18 /**
19 - * Provides a way of interacting with the BGP protocol component. 19 + * A source of route updates.
20 */ 20 */
21 -public interface BgpService { 21 +public interface RouteSourceService {
22 22
23 /** 23 /**
24 - * Starts the BGP service. 24 + * Starts the route source.
25 * 25 *
26 * @param routeListener listener to send route updates to 26 * @param routeListener listener to send route updates to
27 */ 27 */
28 void start(RouteListener routeListener); 28 void start(RouteListener routeListener);
29 29
30 /** 30 /**
31 - * Stops the BGP service. 31 + * Stops the route source.
32 */ 32 */
33 void stop(); 33 void stop();
34 } 34 }
......
...@@ -34,7 +34,7 @@ import org.onlab.packet.Ip4Address; ...@@ -34,7 +34,7 @@ import org.onlab.packet.Ip4Address;
34 import org.onlab.packet.Ip4Prefix; 34 import org.onlab.packet.Ip4Prefix;
35 import org.onlab.packet.Ip6Prefix; 35 import org.onlab.packet.Ip6Prefix;
36 import org.onlab.packet.IpPrefix; 36 import org.onlab.packet.IpPrefix;
37 -import org.onosproject.routing.BgpService; 37 +import org.onosproject.routing.RouteSourceService;
38 import org.onosproject.routing.RouteListener; 38 import org.onosproject.routing.RouteListener;
39 import org.osgi.service.component.ComponentContext; 39 import org.osgi.service.component.ComponentContext;
40 import org.slf4j.Logger; 40 import org.slf4j.Logger;
...@@ -57,7 +57,7 @@ import static org.onlab.util.Tools.groupedThreads; ...@@ -57,7 +57,7 @@ import static org.onlab.util.Tools.groupedThreads;
57 */ 57 */
58 @Component(immediate = true, enabled = false) 58 @Component(immediate = true, enabled = false)
59 @Service 59 @Service
60 -public class BgpSessionManager implements BgpInfoService, BgpService { 60 +public class BgpSessionManager implements BgpInfoService, RouteSourceService {
61 private static final Logger log = 61 private static final Logger log =
62 LoggerFactory.getLogger(BgpSessionManager.class); 62 LoggerFactory.getLogger(BgpSessionManager.class);
63 63
......
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm;
18 +
19 +import org.jboss.netty.buffer.ChannelBuffer;
20 +import org.jboss.netty.channel.Channel;
21 +import org.jboss.netty.channel.ChannelHandlerContext;
22 +import org.jboss.netty.handler.codec.frame.FrameDecoder;
23 +import org.onosproject.routing.fpm.protocol.FpmHeader;
24 +
25 +/**
26 + * Frame decoder for FPM connections.
27 + */
28 +public class FpmFrameDecoder extends FrameDecoder {
29 +
30 + @Override
31 + protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer)
32 + throws Exception {
33 +
34 + if (!channel.isConnected()) {
35 + return null;
36 + }
37 +
38 + if (buffer.readableBytes() < FpmHeader.FPM_HEADER_LENGTH) {
39 + return null;
40 + }
41 +
42 + buffer.markReaderIndex();
43 +
44 + short version = buffer.readUnsignedByte();
45 + short type = buffer.readUnsignedByte();
46 + int length = buffer.readUnsignedShort();
47 +
48 + buffer.resetReaderIndex();
49 +
50 + if (buffer.readableBytes() < length) {
51 + // Not enough bytes to read a whole message
52 + return null;
53 + }
54 +
55 + byte[] fpmMessage = new byte[length];
56 + buffer.readBytes(fpmMessage);
57 +
58 + return FpmHeader.decode(fpmMessage, 0, fpmMessage.length);
59 + }
60 +}
1 +/*
2 + * Copyright 2016 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.routing.fpm;
17 +
18 +import org.apache.felix.scr.annotations.Activate;
19 +import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Service;
22 +import org.jboss.netty.bootstrap.ServerBootstrap;
23 +import org.jboss.netty.channel.Channel;
24 +import org.jboss.netty.channel.ChannelException;
25 +import org.jboss.netty.channel.ChannelFactory;
26 +import org.jboss.netty.channel.ChannelPipeline;
27 +import org.jboss.netty.channel.ChannelPipelineFactory;
28 +import org.jboss.netty.channel.Channels;
29 +import org.jboss.netty.channel.group.ChannelGroup;
30 +import org.jboss.netty.channel.group.DefaultChannelGroup;
31 +import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
32 +import org.onlab.packet.IpAddress;
33 +import org.onlab.packet.IpPrefix;
34 +import org.onosproject.routing.RouteEntry;
35 +import org.onosproject.routing.RouteListener;
36 +import org.onosproject.routing.RouteSourceService;
37 +import org.onosproject.routing.RouteUpdate;
38 +import org.onosproject.routing.fpm.protocol.FpmHeader;
39 +import org.onosproject.routing.fpm.protocol.Netlink;
40 +import org.onosproject.routing.fpm.protocol.RouteAttribute;
41 +import org.onosproject.routing.fpm.protocol.RouteAttributeDst;
42 +import org.onosproject.routing.fpm.protocol.RouteAttributeGateway;
43 +import org.onosproject.routing.fpm.protocol.RtNetlink;
44 +import org.slf4j.Logger;
45 +import org.slf4j.LoggerFactory;
46 +
47 +import java.net.InetSocketAddress;
48 +import java.util.Collections;
49 +import java.util.Map;
50 +import java.util.concurrent.ConcurrentHashMap;
51 +
52 +import static java.util.concurrent.Executors.newCachedThreadPool;
53 +import static org.onlab.util.Tools.groupedThreads;
54 +
55 +/**
56 + * Forwarding Plane Manager (FPM) route source.
57 + */
58 +@Service
59 +@Component(immediate = true, enabled = false)
60 +public class FpmManager implements RouteSourceService {
61 + private final Logger log = LoggerFactory.getLogger(getClass());
62 +
63 + private ServerBootstrap serverBootstrap;
64 + private Channel serverChannel;
65 + private ChannelGroup allChannels = new DefaultChannelGroup();
66 +
67 + private Map<IpPrefix, RouteEntry> fpmRoutes = new ConcurrentHashMap<>();
68 +
69 + private RouteListener routeListener;
70 +
71 + private static final int FPM_PORT = 2620;
72 +
73 + @Activate
74 + protected void activate() {
75 + log.info("Started");
76 + }
77 +
78 + @Deactivate
79 + protected void deactivate() {
80 + stopServer();
81 + log.info("Stopped");
82 + }
83 +
84 + private void startServer() {
85 + ChannelFactory channelFactory = new NioServerSocketChannelFactory(
86 + newCachedThreadPool(groupedThreads("onos/fpm", "sm-boss-%d")),
87 + newCachedThreadPool(groupedThreads("onos/fpm", "sm-worker-%d")));
88 + ChannelPipelineFactory pipelineFactory = () -> {
89 + // Allocate a new session per connection
90 + FpmSessionHandler fpmSessionHandler =
91 + new FpmSessionHandler(new InternalFpmListener());
92 + FpmFrameDecoder fpmFrameDecoder =
93 + new FpmFrameDecoder();
94 +
95 + // Setup the processing pipeline
96 + ChannelPipeline pipeline = Channels.pipeline();
97 + pipeline.addLast("FpmFrameDecoder", fpmFrameDecoder);
98 + pipeline.addLast("FpmSession", fpmSessionHandler);
99 + return pipeline;
100 + };
101 +
102 + InetSocketAddress listenAddress = new InetSocketAddress(FPM_PORT);
103 +
104 + serverBootstrap = new ServerBootstrap(channelFactory);
105 + serverBootstrap.setOption("child.reuseAddr", true);
106 + serverBootstrap.setOption("child.keepAlive", true);
107 + serverBootstrap.setOption("child.tcpNoDelay", true);
108 + serverBootstrap.setPipelineFactory(pipelineFactory);
109 + try {
110 + serverChannel = serverBootstrap.bind(listenAddress);
111 + allChannels.add(serverChannel);
112 + } catch (ChannelException e) {
113 + log.debug("Exception binding to FPM port {}: ",
114 + listenAddress.getPort(), e);
115 + stopServer();
116 + }
117 + }
118 +
119 + private void stopServer() {
120 + allChannels.close().awaitUninterruptibly();
121 + allChannels.clear();
122 + if (serverBootstrap != null) {
123 + serverBootstrap.releaseExternalResources();
124 + }
125 + }
126 +
127 + @Override
128 + public void start(RouteListener routeListener) {
129 + this.routeListener = routeListener;
130 +
131 + startServer();
132 + }
133 +
134 + @Override
135 + public void stop() {
136 + fpmRoutes.clear();
137 + stopServer();
138 + }
139 +
140 + private void fpmMessage(FpmHeader fpmMessage) {
141 + Netlink netlink = fpmMessage.netlink();
142 + RtNetlink rtNetlink = netlink.rtNetlink();
143 +
144 + if (log.isTraceEnabled()) {
145 + log.trace("Received FPM message: {}", fpmMessage);
146 + }
147 +
148 + IpAddress dstAddress = null;
149 + IpAddress gateway = null;
150 +
151 + for (RouteAttribute attribute : rtNetlink.attributes()) {
152 + if (attribute.type() == RouteAttribute.RTA_DST) {
153 + RouteAttributeDst raDst = (RouteAttributeDst) attribute;
154 + dstAddress = raDst.dstAddress();
155 + } else if (attribute.type() == RouteAttribute.RTA_GATEWAY) {
156 + RouteAttributeGateway raGateway = (RouteAttributeGateway) attribute;
157 + gateway = raGateway.gateway();
158 + }
159 + }
160 +
161 + if (dstAddress == null) {
162 + log.error("Dst address missing!");
163 + return;
164 + }
165 +
166 + IpPrefix prefix = IpPrefix.valueOf(dstAddress, rtNetlink.dstLength());
167 +
168 + RouteUpdate routeUpdate = null;
169 + RouteEntry entry;
170 + switch (netlink.type()) {
171 + case RTM_NEWROUTE:
172 + if (gateway == null) {
173 + // We ignore interface routes with no gateway for now.
174 + return;
175 + }
176 + entry = new RouteEntry(prefix, gateway);
177 +
178 + fpmRoutes.put(entry.prefix(), entry);
179 +
180 + routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, entry);
181 + break;
182 + case RTM_DELROUTE:
183 + RouteEntry existing = fpmRoutes.remove(prefix);
184 + if (existing == null) {
185 + log.warn("Got delete for non-existent prefix");
186 + return;
187 + }
188 +
189 + entry = new RouteEntry(prefix, existing.nextHop());
190 +
191 + routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, entry);
192 + break;
193 + case RTM_GETROUTE:
194 + default:
195 + break;
196 + }
197 +
198 + if (routeUpdate == null) {
199 + log.warn("Unsupported FPM message: {}", fpmMessage);
200 + return;
201 + }
202 +
203 + routeListener.update(Collections.singletonList(routeUpdate));
204 + }
205 +
206 + private class InternalFpmListener implements FpmMessageListener {
207 + @Override
208 + public void fpmMessage(FpmHeader fpmMessage) {
209 + FpmManager.this.fpmMessage(fpmMessage);
210 + }
211 + }
212 +
213 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm;
18 +
19 +import org.onosproject.routing.fpm.protocol.FpmHeader;
20 +
21 +/**
22 + * Listener for FPM messages.
23 + */
24 +public interface FpmMessageListener {
25 +
26 + /**
27 + * Handles an FPM message.
28 + *
29 + * @param fpmMessage FPM message
30 + */
31 + void fpmMessage(FpmHeader fpmMessage);
32 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm;
18 +
19 +import org.jboss.netty.channel.Channel;
20 +import org.jboss.netty.channel.ChannelHandlerContext;
21 +import org.jboss.netty.channel.ChannelStateEvent;
22 +import org.jboss.netty.channel.ExceptionEvent;
23 +import org.jboss.netty.channel.MessageEvent;
24 +import org.jboss.netty.channel.SimpleChannelHandler;
25 +import org.onosproject.routing.fpm.protocol.FpmHeader;
26 +import org.slf4j.Logger;
27 +import org.slf4j.LoggerFactory;
28 +
29 +import static com.google.common.base.Preconditions.checkNotNull;
30 +
31 +/**
32 + * Session handler for FPM protocol.
33 + */
34 +public class FpmSessionHandler extends SimpleChannelHandler {
35 +
36 + private static Logger log = LoggerFactory.getLogger(FpmSessionHandler.class);
37 +
38 + private final FpmMessageListener fpmListener;
39 +
40 + private Channel channel;
41 +
42 + /**
43 + * Class constructor.
44 + *
45 + * @param fpmListener listener for FPM messages
46 + */
47 + public FpmSessionHandler(FpmMessageListener fpmListener) {
48 + this.fpmListener = checkNotNull(fpmListener);
49 + }
50 +
51 + @Override
52 + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
53 + throws Exception {
54 + FpmHeader fpmMessage = (FpmHeader) e.getMessage();
55 + fpmListener.fpmMessage(fpmMessage);
56 + }
57 +
58 + @Override
59 + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
60 + throws Exception {
61 + log.error("Exception thrown while handling FPM message", e.getCause());
62 + channel.close();
63 + handleDisconnect();
64 + }
65 +
66 + @Override
67 + public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
68 + throws Exception {
69 + if (this.channel != null) {
70 + log.error("Received new FPM connection while already connected");
71 + ctx.getChannel().close();
72 + return;
73 + }
74 +
75 + this.channel = ctx.getChannel();
76 + }
77 +
78 + @Override
79 + public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
80 + throws Exception {
81 + super.channelConnected(ctx, e);
82 + }
83 +
84 + @Override
85 + public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e)
86 + throws Exception {
87 + handleDisconnect();
88 + }
89 +
90 + @Override
91 + public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
92 + throws Exception {
93 + handleDisconnect();
94 + }
95 +
96 + private void handleDisconnect() {
97 + this.channel = null;
98 + }
99 +}
1 +/*
2 + * Copyright 2016 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 +
17 +/**
18 + * Forwarding Plane Manager (FPM) implementation.
19 + */
20 +package org.onosproject.routing.fpm;
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +import com.google.common.base.MoreObjects;
20 +import org.onlab.packet.DeserializationException;
21 +
22 +import java.nio.ByteBuffer;
23 +
24 +import static org.onlab.packet.PacketUtils.checkInput;
25 +
26 +/**
27 + * FPM header.
28 + */
29 +public final class FpmHeader {
30 + public static final int FPM_HEADER_LENGTH = 4;
31 +
32 + public static final short FPM_VERSION_1 = 1;
33 + public static final short FPM_TYPE_NETLINK = 1;
34 +
35 + private static final String VERSION_NOT_SUPPORTED = "FPM version not supported: ";
36 + private static final String TYPE_NOT_SUPPORTED = "FPM type not supported: ";
37 +
38 + private final short version;
39 + private final short type;
40 + private final int length;
41 +
42 + private final Netlink netlink;
43 +
44 + /**
45 + * Class constructor.
46 + *
47 + * @param version version
48 + * @param type type
49 + * @param length length
50 + * @param netlink netlink header
51 + */
52 + private FpmHeader(short version, short type, int length, Netlink netlink) {
53 + this.version = version;
54 + this.type = type;
55 + this.length = length;
56 + this.netlink = netlink;
57 + }
58 +
59 + /**
60 + * Returns the protocol version.
61 + *
62 + * @return protocol version
63 + */
64 + public short version() {
65 + return version;
66 + }
67 +
68 + /**
69 + * Returns the type.
70 + *
71 + * @return type
72 + */
73 + public short type() {
74 + return type;
75 + }
76 +
77 + /**
78 + * Returns the message length.
79 + *
80 + * @return message length
81 + */
82 + public int length() {
83 + return length;
84 + }
85 +
86 + /**
87 + * Returns the netlink header.
88 + *
89 + * @return netlink header
90 + */
91 + public Netlink netlink() {
92 + return netlink;
93 + }
94 +
95 + @Override
96 + public String toString() {
97 + return MoreObjects.toStringHelper(getClass())
98 + .add("version", version)
99 + .add("type", type)
100 + .add("length", length)
101 + .add("netlink", netlink)
102 + .toString();
103 + }
104 +
105 + /**
106 + * Decodes an FPM header from an input buffer.
107 + *
108 + * @param buffer input buffer
109 + * @param start starting position the FPM header
110 + * @param length length of the message
111 + * @return FPM header
112 + * @throws DeserializationException if an FPM header could not be decoded
113 + * from the input buffer
114 + */
115 + public static FpmHeader decode(byte[] buffer, int start, int length) throws
116 + DeserializationException {
117 + checkInput(buffer, start, length, FPM_HEADER_LENGTH);
118 +
119 + ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
120 +
121 + short version = bb.get();
122 + if (version != FPM_VERSION_1) {
123 + throw new DeserializationException(VERSION_NOT_SUPPORTED + version);
124 + }
125 +
126 + short type = bb.get();
127 + if (type != FPM_TYPE_NETLINK) {
128 + throw new DeserializationException(TYPE_NOT_SUPPORTED + type);
129 + }
130 +
131 + int messageLength = bb.getShort();
132 +
133 + Netlink netlink = Netlink.decode(buffer, bb.position(), bb.limit() - bb.position());
134 +
135 + return new FpmHeader(version, type, messageLength, netlink);
136 + }
137 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +import com.google.common.base.MoreObjects;
20 +import org.onlab.packet.DeserializationException;
21 +
22 +import java.nio.ByteBuffer;
23 +
24 +import static org.onlab.packet.PacketUtils.checkInput;
25 +
26 +/**
27 + * Netlink header.
28 + * <p>
29 + * Taken from struct nlmsghdr in linux/netlink.h
30 + * </p>
31 + */
32 +public final class Netlink {
33 +
34 + public static final int NETLINK_HEADER_LENGTH = 16;
35 +
36 + private final long length;
37 + private final NetlinkMessageType type;
38 + private final int flags;
39 + private final long sequence;
40 + private final long processPortId;
41 +
42 + private final RtNetlink rtNetlink;
43 +
44 + /**
45 + * Class constructor.
46 + *
47 + * @param length message length
48 + * @param type type
49 + * @param flags flags
50 + * @param sequence sequence number
51 + * @param processPortId port ID
52 + * @param rtNetlink netlink routing message
53 + */
54 + private Netlink(long length, NetlinkMessageType type, int flags, long sequence,
55 + long processPortId, RtNetlink rtNetlink) {
56 + this.length = length;
57 + this.type = type;
58 + this.flags = flags;
59 + this.sequence = sequence;
60 + this.processPortId = processPortId;
61 + this.rtNetlink = rtNetlink;
62 + }
63 +
64 + /**
65 + * Returns the message length.
66 + *
67 + * @return length
68 + */
69 + public long length() {
70 + return length;
71 + }
72 +
73 + /**
74 + * Returns the message type.
75 + *
76 + * @return message type
77 + */
78 + public NetlinkMessageType type() {
79 + return type;
80 + }
81 +
82 + /**
83 + * Returns the flags.
84 + *
85 + * @return flags
86 + */
87 + public int flags() {
88 + return flags;
89 + }
90 +
91 + /**
92 + * Returns the sequence number.
93 + *
94 + * @return sequence number
95 + */
96 + public long sequence() {
97 + return sequence;
98 + }
99 +
100 + /**
101 + * Returns the port ID.
102 + *
103 + * @return port ID
104 + */
105 + public long processPortId() {
106 + return processPortId;
107 + }
108 +
109 + /**
110 + * Returns the netlink routing message.
111 + *
112 + * @return netlink routing message
113 + */
114 + public RtNetlink rtNetlink() {
115 + return rtNetlink;
116 + }
117 +
118 + @Override
119 + public String toString() {
120 + return MoreObjects.toStringHelper(getClass())
121 + .add("length", length)
122 + .add("type", type)
123 + .add("flags", flags)
124 + .add("sequence", sequence)
125 + .add("processPortId", processPortId)
126 + .add("rtNetlink", rtNetlink)
127 + .toString();
128 + }
129 +
130 + /**
131 + * Decodes a netlink header from an input buffer.
132 + *
133 + * @param buffer input buffer
134 + * @param start starting position the netlink header
135 + * @param length length of the message
136 + * @return netlink header
137 + * @throws DeserializationException if a netlink header could not be
138 + * decoded from the input buffer
139 + */
140 + public static Netlink decode(byte[] buffer, int start, int length) throws
141 + DeserializationException {
142 + checkInput(buffer, start, length, NETLINK_HEADER_LENGTH);
143 +
144 + ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
145 +
146 + long messageLength = Integer.reverseBytes(bb.getInt());
147 + int type = Short.reverseBytes(bb.getShort());
148 + int flags = Short.reverseBytes(bb.getShort());
149 + long sequence = Integer.reverseBytes(bb.getInt());
150 + long processPortId = Integer.reverseBytes(bb.getInt());
151 +
152 + NetlinkMessageType messageType = NetlinkMessageType.get(type);
153 + if (messageType == null) {
154 + throw new DeserializationException(
155 + "Unsupported Netlink message type: " + type);
156 + }
157 +
158 + // Netlink messages from Quagga's FPM protocol are always in the
159 + // netlink route family (family 0).
160 + RtNetlink rtNetlink = RtNetlink.decode(buffer, bb.position(),
161 + bb.limit() - bb.position());
162 +
163 + return new Netlink(messageLength,
164 + messageType,
165 + flags,
166 + sequence,
167 + processPortId,
168 + rtNetlink);
169 + }
170 +
171 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +/**
20 + * Netlink message types.
21 + * <p>
22 + * This is a subset of the types used for routing messages (rtnelink).
23 + * Taken from linux/rtnetlink.h
24 + * </p>
25 + */
26 +public enum NetlinkMessageType {
27 + RTM_NEWROUTE(24),
28 + RTM_DELROUTE(25),
29 + RTM_GETROUTE(26);
30 +
31 + private final int type;
32 +
33 + /**
34 + * Enum constructor.
35 + *
36 + * @param type integer type value
37 + */
38 + NetlinkMessageType(int type) {
39 + this.type = type;
40 + }
41 +
42 + /**
43 + * Returns the integer type value for this message type.
44 + *
45 + * @return type value
46 + */
47 + public int type() {
48 + return type;
49 + }
50 +
51 + /**
52 + * Gets the NetlinkMessageType for the given integer type value.
53 + *
54 + * @param type type value
55 + * @return Netlink message type, or null if unsupported type value
56 + */
57 + public static NetlinkMessageType get(int type) {
58 + for (NetlinkMessageType m : NetlinkMessageType.values()) {
59 + if (m.type() == type) {
60 + return m;
61 + }
62 + }
63 + return null;
64 + }
65 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +import com.google.common.collect.ImmutableMap;
20 +import org.onlab.packet.DeserializationException;
21 +
22 +import java.nio.ByteBuffer;
23 +import java.util.Map;
24 +
25 +import static org.onlab.packet.PacketUtils.checkInput;
26 +
27 +/**
28 + * Route attribute header.
29 + */
30 +public abstract class RouteAttribute {
31 +
32 + public static final int ROUTE_ATTRIBUTE_HEADER_LENGTH = 4;
33 +
34 + public static final int RTA_DST = 1;
35 + public static final int RTA_OIF = 4;
36 + public static final int RTA_GATEWAY = 5;
37 + public static final int RTA_PRIORITY = 6;
38 +
39 + private final int length;
40 + private final int type;
41 +
42 + private static final Map<Integer, RouteAttributeDecoder<?>> TYPE_DECODER_MAP
43 + = ImmutableMap.<Integer, RouteAttributeDecoder<?>>builder()
44 + .put(RTA_DST, RouteAttributeDst.decoder())
45 + .put(RTA_OIF, RouteAttributeOif.decoder())
46 + .put(RTA_GATEWAY, RouteAttributeGateway.decoder())
47 + .put(RTA_PRIORITY, RouteAttributePriority.decoder())
48 + .build();
49 +
50 + /**
51 + * Class constructor.
52 + *
53 + * @param length attribute length
54 + * @param type attribute type
55 + */
56 + protected RouteAttribute(int length, int type) {
57 + this.length = length;
58 + this.type = type;
59 + }
60 +
61 + /**
62 + * Returns the attribute length.
63 + *
64 + * @return length
65 + */
66 + public int length() {
67 + return length;
68 + }
69 +
70 + /**
71 + * Returns the attribute type.
72 + *
73 + * @return type
74 + */
75 + public int type() {
76 + return type;
77 + }
78 +
79 + @Override
80 + public abstract String toString();
81 +
82 + /**
83 + * Decodes a route attribute from an input buffer.
84 + *
85 + * @param buffer input buffer
86 + * @param start starting position the route attribute message
87 + * @param length length of the message
88 + * @return route attribute message
89 + * @throws DeserializationException if a route attribute could not be
90 + * decoded from the input buffer
91 + */
92 + public static RouteAttribute decode(byte[] buffer, int start, int length)
93 + throws DeserializationException {
94 + checkInput(buffer, start, length, ROUTE_ATTRIBUTE_HEADER_LENGTH);
95 +
96 + ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
97 +
98 + int tlvLength = Short.reverseBytes(bb.getShort());
99 + int type = Short.reverseBytes(bb.getShort());
100 +
101 + if (bb.remaining() < tlvLength - ROUTE_ATTRIBUTE_HEADER_LENGTH) {
102 + throw new DeserializationException(
103 + "Incorrect buffer size when decoding route attribute");
104 + }
105 +
106 + byte[] value = new byte[tlvLength - ROUTE_ATTRIBUTE_HEADER_LENGTH];
107 + bb.get(value);
108 +
109 + RouteAttributeDecoder<?> decoder = TYPE_DECODER_MAP.get(type);
110 + if (decoder == null) {
111 + throw new DeserializationException(
112 + "No decoder found for route attribute type " + type);
113 + }
114 +
115 + return decoder.decodeAttribute(tlvLength, type, value);
116 + }
117 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +import org.onlab.packet.DeserializationException;
20 +
21 +/**
22 + * Decoder for a route attribute.
23 + */
24 +@FunctionalInterface
25 +public interface RouteAttributeDecoder<A extends RouteAttribute> {
26 +
27 + /**
28 + * Decodes the a route attribute from the input buffer.
29 + *
30 + * @param length length of the attribute
31 + * @param type type of the attribute
32 + * @param value input buffer
33 + * @return route attribute
34 + * @throws DeserializationException if a route attribute could not be
35 + * decoded from the input buffer
36 + */
37 + A decodeAttribute(int length, int type, byte[] value)
38 + throws DeserializationException;
39 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +import com.google.common.base.MoreObjects;
20 +import org.onlab.packet.DeserializationException;
21 +import org.onlab.packet.Ip4Address;
22 +import org.onlab.packet.Ip6Address;
23 +import org.onlab.packet.IpAddress;
24 +
25 +/**
26 + * Destination address route attribute.
27 + */
28 +public final class RouteAttributeDst extends RouteAttribute {
29 +
30 + private final IpAddress dstAddress;
31 +
32 + /**
33 + * Class constructor.
34 + *
35 + * @param length length
36 + * @param type type
37 + * @param dstAddress destination address
38 + */
39 + private RouteAttributeDst(int length, int type, IpAddress dstAddress) {
40 + super(length, type);
41 +
42 + this.dstAddress = dstAddress;
43 + }
44 +
45 + /**
46 + * Returns the destination IP address.
47 + *
48 + * @return destination IP address
49 + */
50 + public IpAddress dstAddress() {
51 + return dstAddress;
52 + }
53 +
54 + @Override
55 + public String toString() {
56 + return MoreObjects.toStringHelper(getClass())
57 + .add("type", type())
58 + .add("length", length())
59 + .add("dstAddress", dstAddress)
60 + .toString();
61 + }
62 +
63 + /**
64 + * Returns a decoder for a destination address route attribute.
65 + *
66 + * @return destination address route attribute decoder
67 + */
68 + public static RouteAttributeDecoder<RouteAttributeDst> decoder() {
69 + return (int length, int type, byte[] value) -> {
70 +
71 + IpAddress dstAddress;
72 + if (value.length == Ip4Address.BYTE_LENGTH) {
73 + dstAddress = IpAddress.valueOf(IpAddress.Version.INET, value);
74 + } else if (value.length == Ip6Address.BYTE_LENGTH) {
75 + dstAddress = IpAddress.valueOf(IpAddress.Version.INET6, value);
76 + } else {
77 + throw new DeserializationException("Invalid address length");
78 + }
79 +
80 + return new RouteAttributeDst(length, type, dstAddress);
81 + };
82 + }
83 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +import com.google.common.base.MoreObjects;
20 +import org.onlab.packet.DeserializationException;
21 +import org.onlab.packet.Ip4Address;
22 +import org.onlab.packet.Ip6Address;
23 +import org.onlab.packet.IpAddress;
24 +
25 +/**
26 + * Gateway route attribute.
27 + */
28 +public final class RouteAttributeGateway extends RouteAttribute {
29 +
30 + public static final int VALUE_LENGTH = 4;
31 +
32 + private final IpAddress gateway;
33 +
34 + /**
35 + * Class constructor.
36 + *
37 + * @param length length
38 + * @param type type
39 + * @param gateway gateway address
40 + */
41 + private RouteAttributeGateway(int length, int type, IpAddress gateway) {
42 + super(length, type);
43 +
44 + this.gateway = gateway;
45 + }
46 +
47 + /**
48 + * Returns the gateway address.
49 + *
50 + * @return gateway address
51 + */
52 + public IpAddress gateway() {
53 + return gateway;
54 + }
55 +
56 + @Override
57 + public String toString() {
58 + return MoreObjects.toStringHelper(getClass())
59 + .add("type", type())
60 + .add("length", length())
61 + .add("gateway", gateway)
62 + .toString();
63 + }
64 +
65 + /**
66 + * Returns a decoder for a gateway route attribute.
67 + *
68 + * @return gateway route attribute decoder
69 + */
70 + public static RouteAttributeDecoder<RouteAttributeGateway> decoder() {
71 + return (int length, int type, byte[] value) -> {
72 +
73 + IpAddress gateway;
74 + if (value.length == Ip4Address.BYTE_LENGTH) {
75 + gateway = IpAddress.valueOf(IpAddress.Version.INET, value);
76 + } else if (value.length == Ip6Address.BYTE_LENGTH) {
77 + gateway = IpAddress.valueOf(IpAddress.Version.INET6, value);
78 + } else {
79 + throw new DeserializationException("Invalid address length");
80 + }
81 +
82 + return new RouteAttributeGateway(length, type, gateway);
83 + };
84 + }
85 +
86 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +import com.google.common.base.MoreObjects;
20 +import org.onlab.packet.DeserializationException;
21 +
22 +import java.nio.ByteBuffer;
23 +
24 +/**
25 + * Output interface route attribute.
26 + */
27 +public final class RouteAttributeOif extends RouteAttribute {
28 +
29 + private static final int VALUE_LENGTH = 4;
30 +
31 + private final long outputInterface;
32 +
33 + /**
34 + * Class constructor.
35 + *
36 + * @param length length
37 + * @param type type
38 + * @param outputInterface output interface
39 + */
40 + private RouteAttributeOif(int length, int type, long outputInterface) {
41 + super(length, type);
42 +
43 + this.outputInterface = outputInterface;
44 + }
45 +
46 + /**
47 + * Returns the output interface.
48 + *
49 + * @return output interface
50 + */
51 + public long outputInterface() {
52 + return outputInterface;
53 + }
54 +
55 + @Override
56 + public String toString() {
57 + return MoreObjects.toStringHelper(getClass())
58 + .add("type", type())
59 + .add("length", length())
60 + .add("outputInterface", outputInterface)
61 + .toString();
62 + }
63 +
64 + /**
65 + * Returns a decoder for a output interface route attribute.
66 + *
67 + * @return output interface route attribute decoder
68 + */
69 + public static RouteAttributeDecoder<RouteAttributeOif> decoder() {
70 + return (int length, int type, byte[] value) -> {
71 + if (value.length != VALUE_LENGTH) {
72 + throw new DeserializationException("Wrong value length");
73 + }
74 +
75 + long outputInterface = Integer.reverseBytes(ByteBuffer.wrap(value).getInt());
76 +
77 + return new RouteAttributeOif(length, type, outputInterface);
78 + };
79 + }
80 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +import com.google.common.base.MoreObjects;
20 +import org.onlab.packet.DeserializationException;
21 +
22 +import java.nio.ByteBuffer;
23 +
24 +/**
25 + * Priority route attribute.
26 + */
27 +public final class RouteAttributePriority extends RouteAttribute {
28 +
29 + private static final int VALUE_LENGTH = 4;
30 +
31 + private final long priority;
32 +
33 + /**
34 + * Class constructor.
35 + *
36 + * @param length length
37 + * @param type type
38 + * @param priority priority
39 + */
40 + private RouteAttributePriority(int length, int type, long priority) {
41 + super(length, type);
42 +
43 + this.priority = priority;
44 + }
45 +
46 + /**
47 + * Returns the priority.
48 + *
49 + * @return priority
50 + */
51 + public long priority() {
52 + return priority;
53 + }
54 +
55 + @Override
56 + public String toString() {
57 + return MoreObjects.toStringHelper(getClass())
58 + .add("type", type())
59 + .add("length", length())
60 + .add("priority", priority)
61 + .toString();
62 + }
63 +
64 + /**
65 + * Returns a decoder for a priority route attribute.
66 + *
67 + * @return priority route attribute decoder
68 + */
69 + public static RouteAttributeDecoder<RouteAttributePriority> decoder() {
70 + return (int length, int type, byte[] value) -> {
71 + if (value.length != VALUE_LENGTH) {
72 + throw new DeserializationException("Wrong value length");
73 + }
74 +
75 + long priority = Integer.reverseBytes(ByteBuffer.wrap(value).getInt());
76 +
77 + return new RouteAttributePriority(length, type, priority);
78 + };
79 + }
80 +
81 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.routing.fpm.protocol;
18 +
19 +import com.google.common.base.MoreObjects;
20 +import com.google.common.collect.ImmutableList;
21 +import org.onlab.packet.DeserializationException;
22 +
23 +import java.nio.ByteBuffer;
24 +import java.util.ArrayList;
25 +import java.util.List;
26 +
27 +import static org.onlab.packet.PacketUtils.checkInput;
28 +
29 +/**
30 + * Netlink routing message (rtnetlink).
31 + * <p>
32 + * Taken from struct rtmsg in linux/rtnetlink.h
33 + * </p>
34 + */
35 +public final class RtNetlink {
36 +
37 + private static final int RT_NETLINK_LENGTH = 12;
38 +
39 + private static final int MASK = 0xff;
40 +
41 + private final short addressFamily;
42 + private final int dstLength;
43 + private final int srcLength;
44 + private final short tos;
45 + private final short table;
46 + private final short protocol;
47 + private final short scope;
48 + private final short type;
49 + private final long flags;
50 +
51 + private final List<RouteAttribute> attributes;
52 +
53 + /**
54 + * Class constructor.
55 + *
56 + * @param addressFamily address family
57 + * @param dstLength destination address length
58 + * @param srcLength source address length
59 + * @param tos type of service
60 + * @param table routing table
61 + * @param protocol protocol
62 + * @param scope scope
63 + * @param type type
64 + * @param flags flags
65 + * @param attributes list of attributes
66 + */
67 + private RtNetlink(short addressFamily,
68 + int dstLength,
69 + int srcLength,
70 + short tos,
71 + short table,
72 + short protocol,
73 + short scope,
74 + short type,
75 + long flags,
76 + List<RouteAttribute> attributes) {
77 +
78 + this.addressFamily = addressFamily;
79 + this.dstLength = dstLength;
80 + this.srcLength = srcLength;
81 + this.tos = tos;
82 + this.table = table;
83 + this.protocol = protocol;
84 + this.scope = scope;
85 + this.type = type;
86 + this.flags = flags;
87 +
88 + this.attributes = ImmutableList.copyOf(attributes);
89 +
90 + }
91 +
92 + /**
93 + * Returns the address family of the route.
94 + *
95 + * @return address family
96 + */
97 + public short addressFamily() {
98 + return addressFamily;
99 + }
100 +
101 + /**
102 + * Returns the destination address length.
103 + *
104 + * @return destination address length
105 + */
106 + public int dstLength() {
107 + return dstLength;
108 + }
109 +
110 + /**
111 + * Returns the source address length.
112 + *
113 + * @return source address length
114 + */
115 + public int srcLength() {
116 + return srcLength;
117 + }
118 +
119 + /**
120 + * Returns the type of service.
121 + *
122 + * @return type of service
123 + */
124 + public short tos() {
125 + return tos;
126 + }
127 +
128 + /**
129 + * Returns the routing table.
130 + *
131 + * @return routing table
132 + */
133 + public short table() {
134 + return table;
135 + }
136 +
137 + /**
138 + * Returns the protocol.
139 + *
140 + * @return protocol
141 + */
142 + public short protocol() {
143 + return protocol;
144 + }
145 +
146 + /**
147 + * Returns the route scope.
148 + *
149 + * @return scope
150 + */
151 + public short scope() {
152 + return scope;
153 + }
154 +
155 + /**
156 + * Returns the route type.
157 + *
158 + * @return route type
159 + */
160 + public short type() {
161 + return type;
162 + }
163 +
164 + /**
165 + * Returns the route flags.
166 + *
167 + * @return route flags
168 + */
169 + public long flags() {
170 + return flags;
171 + }
172 +
173 + /**
174 + * Returns the list of route attributes.
175 + *
176 + * @return route attributes
177 + */
178 + public List<RouteAttribute> attributes() {
179 + return attributes;
180 + }
181 +
182 + @Override
183 + public String toString() {
184 + return MoreObjects.toStringHelper(getClass())
185 + .add("addressFamily", addressFamily)
186 + .add("dstLength", dstLength)
187 + .add("srcLength", srcLength)
188 + .add("tos", tos)
189 + .add("table", table)
190 + .add("protocol", protocol)
191 + .add("scope", scope)
192 + .add("type", type)
193 + .add("flags", flags)
194 + .add("attributes", attributes)
195 + .toString();
196 + }
197 +
198 + /**
199 + * Decodes an rtnetlink message from an input buffer.
200 + *
201 + * @param buffer input buffer
202 + * @param start starting position the rtnetlink message
203 + * @param length length of the message
204 + * @return rtnetlink message
205 + * @throws DeserializationException if an rtnetlink message could not be
206 + * decoded from the input buffer
207 + */
208 + public static RtNetlink decode(byte[] buffer, int start, int length)
209 + throws DeserializationException {
210 + checkInput(buffer, start, length, RT_NETLINK_LENGTH);
211 +
212 + ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
213 +
214 + short addressFamily = (short) (bb.get() & MASK);
215 + int dstLength = bb.get() & MASK;
216 + int srcLength = bb.get() & MASK;
217 + short tos = (short) (bb.get() & MASK);
218 + short table = (short) (bb.get() & MASK);
219 + short protocol = (short) (bb.get() & MASK);
220 + short scope = (short) (bb.get() & MASK);
221 + short type = (short) (bb.get() & MASK);
222 + long flags = Integer.reverseBytes(bb.getInt());
223 + List<RouteAttribute> attributes = new ArrayList<>();
224 +
225 + while (bb.hasRemaining()) {
226 + RouteAttribute attribute = RouteAttribute.decode(buffer, bb.position(),
227 + bb.limit() - bb.position());
228 + attributes.add(attribute);
229 + bb.position(bb.position() + attribute.length());
230 + }
231 +
232 + return new RtNetlink(
233 + addressFamily,
234 + dstLength,
235 + srcLength,
236 + tos,
237 + table,
238 + protocol,
239 + scope,
240 + type,
241 + flags,
242 + attributes);
243 + }
244 +
245 +}
1 +/*
2 + * Copyright 2016 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 +
17 +/**
18 + * FPM protocol implementation.
19 + */
20 +package org.onosproject.routing.fpm.protocol;
...@@ -39,7 +39,7 @@ import org.onosproject.net.Host; ...@@ -39,7 +39,7 @@ import org.onosproject.net.Host;
39 import org.onosproject.net.host.HostEvent; 39 import org.onosproject.net.host.HostEvent;
40 import org.onosproject.net.host.HostListener; 40 import org.onosproject.net.host.HostListener;
41 import org.onosproject.net.host.HostService; 41 import org.onosproject.net.host.HostService;
42 -import org.onosproject.routing.BgpService; 42 +import org.onosproject.routing.RouteSourceService;
43 import org.onosproject.routing.FibEntry; 43 import org.onosproject.routing.FibEntry;
44 import org.onosproject.routing.FibListener; 44 import org.onosproject.routing.FibListener;
45 import org.onosproject.routing.FibUpdate; 45 import org.onosproject.routing.FibUpdate;
...@@ -103,7 +103,7 @@ public class Router implements RoutingService { ...@@ -103,7 +103,7 @@ public class Router implements RoutingService {
103 protected HostService hostService; 103 protected HostService hostService;
104 104
105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
106 - protected BgpService bgpService; 106 + protected RouteSourceService routeSourceService;
107 107
108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
109 protected RoutingConfigurationService routingConfigurationService; 109 protected RoutingConfigurationService routingConfigurationService;
...@@ -142,14 +142,14 @@ public class Router implements RoutingService { ...@@ -142,14 +142,14 @@ public class Router implements RoutingService {
142 public void start() { 142 public void start() {
143 this.hostService.addListener(hostListener); 143 this.hostService.addListener(hostListener);
144 144
145 - bgpService.start(new InternalRouteListener()); 145 + routeSourceService.start(new InternalRouteListener());
146 146
147 bgpUpdatesExecutor.execute(this::doUpdatesThread); 147 bgpUpdatesExecutor.execute(this::doUpdatesThread);
148 } 148 }
149 149
150 @Override 150 @Override
151 public void stop() { 151 public void stop() {
152 - bgpService.stop(); 152 + routeSourceService.stop();
153 153
154 this.hostService.removeListener(hostListener); 154 this.hostService.removeListener(hostListener);
155 155
......
...@@ -40,7 +40,7 @@ import org.onosproject.net.host.HostService; ...@@ -40,7 +40,7 @@ import org.onosproject.net.host.HostService;
40 import org.onosproject.net.provider.ProviderId; 40 import org.onosproject.net.provider.ProviderId;
41 import org.onosproject.routing.config.RoutingConfigurationService; 41 import org.onosproject.routing.config.RoutingConfigurationService;
42 import org.onosproject.routing.impl.Router.InternalHostListener; 42 import org.onosproject.routing.impl.Router.InternalHostListener;
43 -import org.onosproject.routing.BgpService; 43 +import org.onosproject.routing.RouteSourceService;
44 import org.onosproject.routing.FibEntry; 44 import org.onosproject.routing.FibEntry;
45 import org.onosproject.routing.FibListener; 45 import org.onosproject.routing.FibListener;
46 import org.onosproject.routing.FibUpdate; 46 import org.onosproject.routing.FibUpdate;
...@@ -83,10 +83,10 @@ public class RouterAsyncArpTest { ...@@ -83,10 +83,10 @@ public class RouterAsyncArpTest {
83 routingConfigurationService = 83 routingConfigurationService =
84 createMock(RoutingConfigurationService.class); 84 createMock(RoutingConfigurationService.class);
85 85
86 - BgpService bgpService = createMock(BgpService.class); 86 + RouteSourceService routeSourceService = createMock(RouteSourceService.class);
87 - bgpService.start(anyObject(RouteListener.class)); 87 + routeSourceService.start(anyObject(RouteListener.class));
88 - bgpService.stop(); 88 + routeSourceService.stop();
89 - replay(bgpService); 89 + replay(routeSourceService);
90 90
91 fibListener = createMock(FibListener.class); 91 fibListener = createMock(FibListener.class);
92 92
...@@ -94,7 +94,7 @@ public class RouterAsyncArpTest { ...@@ -94,7 +94,7 @@ public class RouterAsyncArpTest {
94 router.coreService = createNiceMock(CoreService.class); 94 router.coreService = createNiceMock(CoreService.class);
95 router.hostService = hostService; 95 router.hostService = hostService;
96 router.routingConfigurationService = routingConfigurationService; 96 router.routingConfigurationService = routingConfigurationService;
97 - router.bgpService = bgpService; 97 + router.routeSourceService = routeSourceService;
98 router.activate(); 98 router.activate();
99 99
100 router.addFibListener(fibListener); 100 router.addFibListener(fibListener);
......
...@@ -39,7 +39,7 @@ import org.onosproject.net.PortNumber; ...@@ -39,7 +39,7 @@ import org.onosproject.net.PortNumber;
39 import org.onosproject.net.host.HostListener; 39 import org.onosproject.net.host.HostListener;
40 import org.onosproject.net.host.HostService; 40 import org.onosproject.net.host.HostService;
41 import org.onosproject.net.provider.ProviderId; 41 import org.onosproject.net.provider.ProviderId;
42 -import org.onosproject.routing.BgpService; 42 +import org.onosproject.routing.RouteSourceService;
43 import org.onosproject.routing.FibEntry; 43 import org.onosproject.routing.FibEntry;
44 import org.onosproject.routing.FibListener; 44 import org.onosproject.routing.FibListener;
45 import org.onosproject.routing.FibUpdate; 45 import org.onosproject.routing.FibUpdate;
...@@ -98,10 +98,10 @@ public class RouterTest { ...@@ -98,10 +98,10 @@ public class RouterTest {
98 routingConfigurationService = 98 routingConfigurationService =
99 createMock(RoutingConfigurationService.class); 99 createMock(RoutingConfigurationService.class);
100 100
101 - BgpService bgpService = createMock(BgpService.class); 101 + RouteSourceService routeSourceService = createMock(RouteSourceService.class);
102 - bgpService.start(anyObject(RouteListener.class)); 102 + routeSourceService.start(anyObject(RouteListener.class));
103 - bgpService.stop(); 103 + routeSourceService.stop();
104 - replay(bgpService); 104 + replay(routeSourceService);
105 105
106 fibListener = createMock(FibListener.class); 106 fibListener = createMock(FibListener.class);
107 107
...@@ -109,7 +109,7 @@ public class RouterTest { ...@@ -109,7 +109,7 @@ public class RouterTest {
109 router.coreService = createNiceMock(CoreService.class); 109 router.coreService = createNiceMock(CoreService.class);
110 router.hostService = hostService; 110 router.hostService = hostService;
111 router.routingConfigurationService = routingConfigurationService; 111 router.routingConfigurationService = routingConfigurationService;
112 - router.bgpService = bgpService; 112 + router.routeSourceService = routeSourceService;
113 router.activate(); 113 router.activate();
114 114
115 router.addFibListener(fibListener); 115 router.addFibListener(fibListener);
......
...@@ -384,8 +384,11 @@ public class SoftRouterPipeline extends AbstractHandlerBehaviour implements Pipe ...@@ -384,8 +384,11 @@ public class SoftRouterPipeline extends AbstractHandlerBehaviour implements Pipe
384 .fromApp(fwd.appId()) 384 .fromApp(fwd.appId())
385 .withPriority(fwd.priority()) 385 .withPriority(fwd.priority())
386 .forDevice(deviceId) 386 .forDevice(deviceId)
387 - .withSelector(filteredSelector) 387 + .withSelector(filteredSelector);
388 - .withTreatment(tt); 388 +
389 + if (tt != null) {
390 + ruleBuilder.withTreatment(tt);
391 + }
389 392
390 if (fwd.permanent()) { 393 if (fwd.permanent()) {
391 ruleBuilder.makePermanent(); 394 ruleBuilder.makePermanent();
......