Jonathan Hart
Committed by Gerrit Code Review

Abstraction to help applications write logic to handle ARP + NDP packets.

The idea is to allow applications to contribute NeighbourMessageHandlers to
handle ARP/NDP packets coming from a particular ConnectPoint, Interface or with
a particular traffic selector. Applications can contribute different handlers
for different ports, because they know how those ports will be used. Also,
multiple applications can contribute handlers for different ports/interfaces
without having to have one ARP handler for the entire network. The framework
provides actions that the handler can choose to take - flood, proxy, reply, drop.
The handler is free to implement some other action if none of these fit what it
needs to do. The framework also handles many of the common tasks for ARP handlers,
like parsing packets, abstracting the differences between ARP and NDP, implementing
actions like replying to a request. This allows handlers to be very simple and
easy to understand and implement.

Change-Id: I313c723e9ebc3d0816eb79870ee0536780e7a640
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 +
17 +package org.onosproject.incubator.net.neighbour;
18 +
19 +import org.onosproject.net.Host;
20 +import org.onosproject.net.host.HostService;
21 +
22 +import java.util.Set;
23 +
24 +import static org.onosproject.net.HostId.hostId;
25 +
26 +/**
27 + * Default neighbour message handler which implements basic proxying on a flat
28 + * L2 network (i.e. ProxyArp behaviour).
29 + */
30 +public class DefaultNeighbourMessageHandler implements NeighbourMessageHandler {
31 + @Override
32 + public void handleMessage(NeighbourMessageContext context, HostService hostService) {
33 + // See if we have the target host in the host store
34 + Set<Host> hosts = hostService.getHostsByIp(context.target());
35 +
36 + Host dst = null;
37 + Host src = hostService.getHost(hostId(context.srcMac(), context.vlan()));
38 +
39 + for (Host host : hosts) {
40 + if (host.vlan().equals(context.vlan())) {
41 + dst = host;
42 + break;
43 + }
44 + }
45 +
46 + if (src != null && dst != null) {
47 + // We know the target host so we can respond
48 + context.reply(dst.mac());
49 + return;
50 + }
51 +
52 + // The request couldn't be resolved.
53 + // Flood the request on all ports except the incoming port.
54 + context.flood();
55 + }
56 +}
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 +
17 +package org.onosproject.incubator.net.neighbour;
18 +
19 +import com.google.common.annotations.Beta;
20 +import org.onlab.packet.MacAddress;
21 +import org.onosproject.incubator.net.intf.Interface;
22 +import org.onosproject.net.ConnectPoint;
23 +
24 +/**
25 + * Performs actions on a neighbour message contexts.
26 + */
27 +@Beta
28 +public interface NeighbourMessageActions {
29 +
30 + /**
31 + * Replies to an incoming request with the given MAC address.
32 + *
33 + * @param context incoming message context
34 + * @param targetMac target MAC address.
35 + */
36 + void reply(NeighbourMessageContext context, MacAddress targetMac);
37 +
38 + /**
39 + * Proxies the incoming message to the given connect point.
40 + *
41 + * @param context incoming message context
42 + * @param outPort port to send the message out
43 + */
44 + void proxy(NeighbourMessageContext context, ConnectPoint outPort);
45 +
46 + /**
47 + * Proxies the incoming message to a given interface.
48 + *
49 + * @param context incoming message context
50 + * @param outIntf interface to send the message out. The message will be
51 + * modified to fit the parameters of the outgoing interface.
52 + */
53 + void proxy(NeighbourMessageContext context, Interface outIntf);
54 +
55 + /**
56 + * Floods the incoming message to all edge ports except the in port.
57 + *
58 + * @param context incoming message context
59 + */
60 + void flood(NeighbourMessageContext context);
61 +
62 + /**
63 + * Drops the incoming message.
64 + *
65 + * @param context incoming message context
66 + */
67 + void drop(NeighbourMessageContext context);
68 +}
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 +
17 +package org.onosproject.incubator.net.neighbour;
18 +
19 +import com.google.common.annotations.Beta;
20 +import org.onlab.packet.Ethernet;
21 +import org.onlab.packet.IpAddress;
22 +import org.onlab.packet.MacAddress;
23 +import org.onlab.packet.VlanId;
24 +import org.onosproject.incubator.net.intf.Interface;
25 +import org.onosproject.net.ConnectPoint;
26 +
27 +import static com.google.common.base.Preconditions.checkState;
28 +
29 +/**
30 + * Context of an incoming neighbor message (e.g. ARP, NDP).
31 + *
32 + * <p>This includes information about the message accessible through a
33 + * protocol-agnostic interface, as well as mechanisms to perform an action in
34 + * response to the incoming message.</p>
35 + */
36 +@Beta
37 +public class NeighbourMessageContext {
38 +
39 + private final NeighbourProtocol protocol;
40 + private final NeighbourMessageType type;
41 +
42 + private final IpAddress target;
43 + private final IpAddress sender;
44 +
45 + private final Ethernet eth;
46 + private final ConnectPoint inPort;
47 +
48 + private final NeighbourMessageActions actions;
49 +
50 + /**
51 + * Creates a new neighbour message context.
52 + *
53 + * @param actions actions
54 + * @param eth ethernet frame
55 + * @param inPort incoming port
56 + * @param protocol message protocol
57 + * @param type message type
58 + * @param target target IP address
59 + * @param sender sender IP address
60 + */
61 + public NeighbourMessageContext(NeighbourMessageActions actions,
62 + Ethernet eth, ConnectPoint inPort,
63 + NeighbourProtocol protocol, NeighbourMessageType type,
64 + IpAddress target, IpAddress sender) {
65 + this.actions = actions;
66 + this.eth = eth;
67 + this.inPort = inPort;
68 + this.protocol = protocol;
69 + this.type = type;
70 + this.target = target;
71 + this.sender = sender;
72 + }
73 +
74 + /**
75 + * Gets the port where the packet came in to the network.
76 + *
77 + * @return connect point
78 + */
79 + public ConnectPoint inPort() {
80 + return inPort;
81 + }
82 +
83 + /**
84 + * Gets the full parsed representation of the packet.
85 + *
86 + * @return ethernet header
87 + */
88 + public Ethernet packet() {
89 + return eth;
90 + }
91 +
92 + /**
93 + * Gets the protocol of the packet.
94 + *
95 + * @return protocol
96 + */
97 + public NeighbourProtocol protocol() {
98 + return protocol;
99 + }
100 +
101 + /**
102 + * Gets the message type of the packet.
103 + *
104 + * @return message type
105 + */
106 + public NeighbourMessageType type() {
107 + return type;
108 + }
109 +
110 + /**
111 + * Gets the vlan of the packet, if any.
112 + *
113 + * @return vlan
114 + */
115 + public VlanId vlan() {
116 + return VlanId.vlanId(eth.getVlanID());
117 + }
118 +
119 + /**
120 + * Gets the source MAC address of the message.
121 + *
122 + * @return source MAC address
123 + */
124 + public MacAddress srcMac() {
125 + return MacAddress.valueOf(eth.getSourceMACAddress());
126 + }
127 +
128 + /**
129 + * Gets the target IP address of the message.
130 + *
131 + * @return target IP address
132 + */
133 + public IpAddress target() {
134 + return target;
135 + }
136 +
137 + /**
138 + * Gets the source IP address of the message.
139 + *
140 + * @return source IP address
141 + */
142 + public IpAddress sender() {
143 + return sender;
144 + }
145 +
146 + /**
147 + * Proxies the message to a given output port.
148 + *
149 + * @param outPort output port
150 + */
151 + public void proxy(ConnectPoint outPort) {
152 + actions.proxy(this, outPort);
153 + }
154 +
155 + /**
156 + * Proxies the message to a given interface.
157 + *
158 + * @param outIntf output interface
159 + */
160 + public void proxy(Interface outIntf) {
161 + actions.proxy(this, outIntf);
162 + }
163 +
164 + /**
165 + * Replies to the request message with a given MAC address.
166 + *
167 + * @param targetMac target MAC address
168 + */
169 + public void reply(MacAddress targetMac) {
170 + checkState(type == NeighbourMessageType.REQUEST, "can only reply to requests");
171 +
172 + actions.reply(this, targetMac);
173 + }
174 +
175 + /**
176 + * Floods the incoming message out all ports except the input port.
177 + */
178 + public void flood() {
179 + actions.flood(this);
180 + }
181 +
182 + /**
183 + * Drops the incoming message.
184 + */
185 + public void drop() {
186 + actions.drop(this);
187 + }
188 +
189 +}
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 +
17 +package org.onosproject.incubator.net.neighbour;
18 +
19 +import com.google.common.annotations.Beta;
20 +import org.onosproject.net.host.HostService;
21 +
22 +/**
23 + * Handler for an incoming neighbour message.
24 + *
25 + * <p>An application may implement this interface in order to provide their own
26 + * logic for handling particular neighbour messages.</p>
27 + */
28 +@Beta
29 +public interface NeighbourMessageHandler {
30 +
31 + /**
32 + * Handles a neighbour message.
33 + *
34 + * @param context neighbour message context
35 + * @param hostService host service
36 + */
37 + void handleMessage(NeighbourMessageContext context, HostService hostService);
38 +}
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 +
17 +package org.onosproject.incubator.net.neighbour;
18 +
19 +import com.google.common.annotations.Beta;
20 +
21 +/**
22 + * Neighbour message type.
23 + */
24 +@Beta
25 +public enum NeighbourMessageType {
26 + /**
27 + * Request message.
28 + */
29 + REQUEST,
30 +
31 + /**
32 + * Reply message.
33 + */
34 + REPLY
35 +}
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 +
17 +package org.onosproject.incubator.net.neighbour;
18 +
19 +import com.google.common.annotations.Beta;
20 +
21 +/**
22 + * Enumerates protocols used for neighbour discover/address resolution.
23 + */
24 +@Beta
25 +public enum NeighbourProtocol {
26 +
27 + /**
28 + * Address Resolution Protocol (IPv4).
29 + */
30 + ARP,
31 +
32 + /**
33 + * Neighbor Discovery Protocol (IPv6).
34 + */
35 + NDP
36 +}
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 +
17 +package org.onosproject.incubator.net.neighbour;
18 +
19 +import com.google.common.annotations.Beta;
20 +import org.onosproject.incubator.net.intf.Interface;
21 +import org.onosproject.net.ConnectPoint;
22 +
23 +/**
24 + * Provides a means of registering logic for handling neighbour messages.
25 + */
26 +@Beta
27 +public interface NeighbourResolutionService {
28 +
29 + /**
30 + * Registers a neighbour message handler for all neighbour messages
31 + * incoming on the given connect point.
32 + *
33 + * @param connectPoint connect point
34 + * @param handler neighbour message handler
35 + */
36 + void registerNeighbourHandler(ConnectPoint connectPoint, NeighbourMessageHandler handler);
37 +
38 + /**
39 + * Registers a neighbour message handler for all neighbour messages incoming
40 + * on the given interface. Neighbour packets must match the fields of the
41 + * interface in order to be handled by this message handler.
42 + *
43 + * @param intf interface
44 + * @param handler neighbour message handler
45 + */
46 + void registerNeighbourHandler(Interface intf, NeighbourMessageHandler handler);
47 +
48 +}
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 +
17 +/**
18 + * Neighbour message (ARP, NDP) handling.
19 + */
20 +package org.onosproject.incubator.net.neighbour;