gaurav
Committed by Gerrit Code Review

DHCP Relay Application, addressed the review comments for patch-2.

Change-Id: If447f3786c661c667460f43fc659ea71dd198be7
...@@ -98,6 +98,7 @@ APPS = [ ...@@ -98,6 +98,7 @@ APPS = [
98 98
99 # Apps 99 # Apps
100 '//apps/dhcp:onos-apps-dhcp-oar', 100 '//apps/dhcp:onos-apps-dhcp-oar',
101 + '//apps/dhcprelay:onos-apps-dhcprelay-oar',
101 '//apps/fwd:onos-apps-fwd-oar', 102 '//apps/fwd:onos-apps-fwd-oar',
102 '//apps/acl:onos-apps-acl-oar', 103 '//apps/acl:onos-apps-acl-oar',
103 '//apps/bgprouter:onos-apps-bgprouter-oar', 104 '//apps/bgprouter:onos-apps-bgprouter-oar',
...@@ -147,6 +148,7 @@ APP_JARS = [ ...@@ -147,6 +148,7 @@ APP_JARS = [
147 '//apps/routing-api:onos-apps-routing-api', 148 '//apps/routing-api:onos-apps-routing-api',
148 '//apps/dhcp/api:onos-apps-dhcp-api', 149 '//apps/dhcp/api:onos-apps-dhcp-api',
149 '//apps/dhcp/app:onos-apps-dhcp-app', 150 '//apps/dhcp/app:onos-apps-dhcp-app',
151 + '//apps/dhcprelay:onos-apps-dhcprelay',
150 '//apps/fwd:onos-apps-fwd', 152 '//apps/fwd:onos-apps-fwd',
151 '//apps/iptopology-api:onos-apps-iptopology-api', 153 '//apps/iptopology-api:onos-apps-iptopology-api',
152 '//apps/openstacknode:onos-apps-openstacknode', 154 '//apps/openstacknode:onos-apps-openstacknode',
......
1 +COMPILE_DEPS = [
2 + '//lib:CORE_DEPS',
3 +]
4 +
5 +osgi_jar (
6 + deps = COMPILE_DEPS,
7 +)
8 +
9 +onos_app (
10 + app_name = 'org.onosproject.dhcprelay',
11 + title = 'DHCP Relay Agent App',
12 + category = 'default',
13 + url = 'http://onosproject.org',
14 + description = 'DHCP Relay Agent Application.',
15 +)
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2016 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
18 + <modelVersion>4.0.0</modelVersion>
19 +
20 + <parent>
21 + <groupId>org.onosproject</groupId>
22 + <artifactId>onos-apps</artifactId>
23 + <version>1.7.0-SNAPSHOT</version>
24 + <relativePath>../pom.xml</relativePath>
25 + </parent>
26 +
27 + <artifactId>onos-app-dhcprelay</artifactId>
28 + <packaging>bundle</packaging>
29 +
30 + <description>DHCP Relay Agent</description>
31 + <url>http://onosproject.org</url>
32 +
33 + <properties>
34 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
35 + <onos.version>1.6.0-SNAPSHOT</onos.version>
36 + <onos.app.name>org.onosproject.dhcprelay</onos.app.name>
37 + <onos.app.title>DHCP Relay Agent App</onos.app.title>
38 + <onos.app.origin>ON.Lab</onos.app.origin>
39 + <onos.app.category>default</onos.app.category>
40 + <onos.app.url>http://onosproject.org</onos.app.url>
41 + <onos.app.readme>DHCP Relay Agent Application.</onos.app.readme>
42 + </properties>
43 +
44 + <dependencies>
45 + <dependency>
46 + <groupId>org.onosproject</groupId>
47 + <artifactId>onos-api</artifactId>
48 + <version>${onos.version}</version>
49 + </dependency>
50 +
51 + <dependency>
52 + <groupId>org.onosproject</groupId>
53 + <artifactId>onlab-osgi</artifactId>
54 + <version>${onos.version}</version>
55 + </dependency>
56 +
57 + <dependency>
58 + <groupId>junit</groupId>
59 + <artifactId>junit</artifactId>
60 + <version>4.12</version>
61 + <scope>test</scope>
62 + </dependency>
63 +
64 + <dependency>
65 + <groupId>org.onosproject</groupId>
66 + <artifactId>onlab-junit</artifactId>
67 + <scope>test</scope>
68 + </dependency>
69 +
70 + <dependency>
71 + <groupId>org.onosproject</groupId>
72 + <artifactId>onos-api</artifactId>
73 + <version>${onos.version}</version>
74 + <scope>test</scope>
75 + <classifier>tests</classifier>
76 + </dependency>
77 +
78 + <dependency>
79 + <groupId>org.apache.felix</groupId>
80 + <artifactId>org.apache.felix.scr.annotations</artifactId>
81 + <version>1.9.12</version>
82 + <scope>provided</scope>
83 + </dependency>
84 + </dependencies>
85 +</project>
1 +/*
2 + * Copyright 2016-present 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.dhcprelay;
17 +
18 +import java.util.Set;
19 +
20 +import org.apache.felix.scr.annotations.Activate;
21 +import org.apache.felix.scr.annotations.Component;
22 +import org.apache.felix.scr.annotations.Deactivate;
23 +import org.apache.felix.scr.annotations.Reference;
24 +import org.apache.felix.scr.annotations.ReferenceCardinality;
25 +import org.onlab.packet.DHCP;
26 +import org.onlab.packet.Ethernet;
27 +import org.onlab.packet.IPv4;
28 +import org.onlab.packet.TpPort;
29 +import org.onlab.packet.UDP;
30 +import org.onosproject.core.ApplicationId;
31 +import org.onosproject.core.CoreService;
32 +import org.onosproject.net.ConnectPoint;
33 +import org.onosproject.net.Host;
34 +import org.onosproject.net.HostId;
35 +import org.onosproject.net.config.ConfigFactory;
36 +import org.onosproject.net.config.NetworkConfigEvent;
37 +import org.onosproject.net.config.NetworkConfigListener;
38 +import org.onosproject.net.config.NetworkConfigRegistry;
39 +import org.onosproject.net.flow.DefaultTrafficSelector;
40 +import org.onosproject.net.flow.DefaultTrafficTreatment;
41 +import org.onosproject.net.flow.TrafficSelector;
42 +import org.onosproject.net.flow.TrafficTreatment;
43 +import org.onosproject.net.host.HostService;
44 +import org.onosproject.net.packet.DefaultOutboundPacket;
45 +import org.onosproject.net.packet.OutboundPacket;
46 +import org.onosproject.net.packet.PacketContext;
47 +import org.onosproject.net.packet.PacketPriority;
48 +import org.onosproject.net.packet.PacketProcessor;
49 +import org.onosproject.net.packet.PacketService;
50 +import org.slf4j.Logger;
51 +import org.slf4j.LoggerFactory;
52 +
53 +import com.google.common.collect.ImmutableSet;
54 +import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
55 +/**
56 + * DHCP Relay Agent Application Component.
57 + */
58 +@Component(immediate = true)
59 +public class DhcpRelay {
60 +
61 + public static final String DHCP_RELAY_APP = "org.onosproject.dhcp-relay";
62 + private final Logger log = LoggerFactory.getLogger(getClass());
63 + private final InternalConfigListener cfgListener = new InternalConfigListener();
64 +
65 + private final Set<ConfigFactory> factories = ImmutableSet.of(
66 + new ConfigFactory<ApplicationId, DhcpRelayConfig>(APP_SUBJECT_FACTORY,
67 + DhcpRelayConfig.class,
68 + "dhcprelay") {
69 + @Override
70 + public DhcpRelayConfig createConfig() {
71 + return new DhcpRelayConfig();
72 + }
73 + }
74 + );
75 +
76 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
77 + protected NetworkConfigRegistry cfgService;
78 +
79 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
80 + protected CoreService coreService;
81 +
82 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
83 + protected PacketService packetService;
84 +
85 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
86 + protected HostService hostService;
87 +
88 + private DhcpRelayPacketProcessor dhcpRelayPacketProcessor = new DhcpRelayPacketProcessor();
89 + private ConnectPoint dhcpServerConnectPoint = null;
90 + private ApplicationId appId;
91 +
92 + @Activate
93 + protected void activate() {
94 + //start the dhcp relay agent
95 +
96 + appId = coreService.registerApplication(DHCP_RELAY_APP);
97 +
98 + cfgService.addListener(cfgListener);
99 + factories.forEach(cfgService::registerConfigFactory);
100 + //update the dhcp server configuration.
101 + updateConfig();
102 + //add the packet services.
103 + packetService.addProcessor(dhcpRelayPacketProcessor, PacketProcessor.director(0));
104 + requestPackets();
105 + log.info("DHCP-RELAY Started");
106 + log.info("started the apps dhcp relay");
107 + }
108 +
109 + @Deactivate
110 + protected void deactivate() {
111 + cfgService.removeListener(cfgListener);
112 + factories.forEach(cfgService::unregisterConfigFactory);
113 + packetService.removeProcessor(dhcpRelayPacketProcessor);
114 + cancelPackets();
115 + log.info("DHCP-RELAY Stopped");
116 + }
117 +
118 + private void updateConfig() {
119 + DhcpRelayConfig cfg = cfgService.getConfig(appId, DhcpRelayConfig.class);
120 +
121 + if (cfg == null) {
122 + log.warn("Dhcp Server info not available");
123 + return;
124 + }
125 +
126 + dhcpServerConnectPoint = cfg.getDhcpServerConnectPoint();
127 + log.info("Reconfigured the dhcp server info");
128 + log.info("dhcp server connect points are " + dhcpServerConnectPoint);
129 + }
130 +
131 + /**
132 + * Request packet in via PacketService.
133 + */
134 + private void requestPackets() {
135 +
136 + TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
137 + .matchEthType(Ethernet.TYPE_IPV4)
138 + .matchIPProtocol(IPv4.PROTOCOL_UDP)
139 + .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
140 + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
141 + packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId);
142 +
143 + TrafficSelector.Builder selectorClient = DefaultTrafficSelector.builder()
144 + .matchEthType(Ethernet.TYPE_IPV4)
145 + .matchIPProtocol(IPv4.PROTOCOL_UDP)
146 + .matchUdpDst(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
147 + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_SERVER_PORT));
148 + packetService.requestPackets(selectorClient.build(), PacketPriority.CONTROL, appId);
149 + }
150 +
151 + /**
152 + * Cancel requested packets in via packet service.
153 + */
154 + private void cancelPackets() {
155 + TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
156 + .matchEthType(Ethernet.TYPE_IPV4)
157 + .matchIPProtocol(IPv4.PROTOCOL_UDP)
158 + .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
159 + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
160 + packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId);
161 +
162 + TrafficSelector.Builder selectorClient = DefaultTrafficSelector.builder()
163 + .matchEthType(Ethernet.TYPE_IPV4)
164 + .matchIPProtocol(IPv4.PROTOCOL_UDP)
165 + .matchUdpDst(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
166 + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_SERVER_PORT));
167 + packetService.cancelPackets(selectorClient.build(), PacketPriority.CONTROL, appId);
168 + }
169 +
170 + private class DhcpRelayPacketProcessor implements PacketProcessor {
171 +
172 + @Override
173 + public void process(PacketContext context) {
174 + // process the packet and get the payload
175 + Ethernet packet = context.inPacket().parsed();
176 +
177 + if (packet == null) {
178 + return;
179 + }
180 +
181 + if (packet.getEtherType() == Ethernet.TYPE_IPV4) {
182 + IPv4 ipv4Packet = (IPv4) packet.getPayload();
183 +
184 + if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) {
185 + UDP udpPacket = (UDP) ipv4Packet.getPayload();
186 + DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
187 + if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT &&
188 + udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT) {
189 + //This packet is dhcp client request.
190 + forwardPacket(context, dhcpPayload);
191 + } else {
192 + //This packet is a dhcp reply from DHCP server.
193 + sendReply(context, dhcpPayload);
194 + }
195 + }
196 + }
197 + }
198 +
199 + //forward the packet to ConnectPoint where the DHCP server is attached.
200 + private void forwardPacket(PacketContext context, DHCP dhcpPayload) {
201 + if (dhcpPayload == null) {
202 + log.debug("DHCP packet without payload, do nothing");
203 + return;
204 + }
205 +
206 + //send Packetout to dhcp server connectpoint.
207 + if (dhcpServerConnectPoint != null) {
208 + TrafficTreatment t = DefaultTrafficTreatment.builder()
209 + .setOutput(dhcpServerConnectPoint.port()).build();
210 + OutboundPacket o = new DefaultOutboundPacket(
211 + dhcpServerConnectPoint.deviceId(), t, context.inPacket().unparsed());
212 + packetService.emit(o);
213 + }
214 + }
215 +
216 + /*//process the dhcp packet before sending to server
217 + private void processDhcpPacket(PacketContext context, DHCP dhcpPayload) {
218 + if (dhcpPayload == null) {
219 + return;
220 + }
221 + Ethernet packet = context.inPacket().parsed();
222 + DHCPPacketType incomingPacketType = null;
223 + for (DHCPOption option : dhcpPayload.getOptions()) {
224 + if (option.getCode() == OptionCode_MessageType.getValue()) {
225 + byte[] data = option.getData();
226 + incomingPacketType = DHCPPacketType.getType(data[0]);
227 + }
228 + }
229 + switch (incomingPacketType) {
230 + case DHCPDISCOVER:
231 + break;
232 + default:
233 + break;
234 + }
235 + }*/
236 +
237 + //send the response to the requestor host.
238 + private void sendReply(PacketContext context, DHCP dhcpPayload) {
239 + if (dhcpPayload == null) {
240 + log.debug("DHCP packet without payload, do nothing");
241 + return;
242 + }
243 + //get the host info
244 + Ethernet packet = context.inPacket().parsed();
245 + Host host = hostService.getHost(HostId.hostId(packet.getDestinationMAC()));
246 + ConnectPoint dhcpRequestor = new ConnectPoint(host.location().elementId(),
247 + host.location().port());
248 +
249 + //send Packetout to requestor host.
250 + if (dhcpRequestor != null) {
251 + TrafficTreatment t = DefaultTrafficTreatment.builder()
252 + .setOutput(dhcpRequestor.port()).build();
253 + OutboundPacket o = new DefaultOutboundPacket(
254 + dhcpRequestor.deviceId(), t, context.inPacket().unparsed());
255 + packetService.emit(o);
256 + }
257 + }
258 + }
259 +
260 + /**
261 + * Listener for network config events.
262 + */
263 + private class InternalConfigListener implements NetworkConfigListener {
264 +
265 + @Override
266 + public void event(NetworkConfigEvent event) {
267 +
268 + if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
269 + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
270 + event.configClass().equals(DhcpRelayConfig.class)) {
271 + updateConfig();
272 + log.info("Reconfigured");
273 + }
274 + }
275 + }
276 +}
1 +/*
2 + * Copyright 2016-present 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.dhcprelay;
17 +
18 +import org.onosproject.core.ApplicationId;
19 +import org.onosproject.net.ConnectPoint;
20 +import org.onosproject.net.config.Config;
21 +
22 +import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
23 +/**
24 + * DHCP Relay Config class.
25 + */
26 +public class DhcpRelayConfig extends Config<ApplicationId> {
27 +
28 + private static final String DHCP_CONNECT_POINT = "dhcpserverConnectPoint";
29 +
30 + @Override
31 + public boolean isValid() {
32 +
33 + return hasOnlyFields(DHCP_CONNECT_POINT) &&
34 + isConnectPoint(DHCP_CONNECT_POINT, MANDATORY);
35 + }
36 +
37 + /**
38 + * Returns the dhcp server connect point.
39 + *
40 + * @return dhcp server connect point
41 + */
42 + public ConnectPoint getDhcpServerConnectPoint() {
43 + return ConnectPoint.deviceConnectPoint(object.path(DHCP_CONNECT_POINT).asText());
44 + }
45 +}
1 +/*
2 + * Copyright 2014-present 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 + * DHCP-RELAY application.
19 + */
20 +package org.onosproject.dhcprelay;
1 +{
2 + "apps": {
3 + "org.onosproject.dhcp-relay" : {
4 + "dhcprelay" : {
5 + "dhcpserverConnectPoint": "of:0000000000000002/2"
6 + }
7 + }
8 + }
9 +}
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
53 <module>flowanalyzer</module> 53 <module>flowanalyzer</module>
54 <module>vtn</module> 54 <module>vtn</module>
55 <module>dhcp</module> 55 <module>dhcp</module>
56 + <module>dhcprelay</module>
56 <module>mfwd</module> 57 <module>mfwd</module>
57 <module>pim</module> 58 <module>pim</module>
58 <module>mlb</module> 59 <module>mlb</module>
......