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 | +} |
apps/routing/src/main/java/org/onosproject/routing/fpm/protocol/RouteAttributeDecoder.java
0 → 100644
| 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 | +} |
apps/routing/src/main/java/org/onosproject/routing/fpm/protocol/RouteAttributeGateway.java
0 → 100644
| 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 | +} |
apps/routing/src/main/java/org/onosproject/routing/fpm/protocol/RouteAttributePriority.java
0 → 100644
| 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(); | ... | ... |
-
Please register or login to post a comment