Add explicit configuration for enabling IPv6-related flow installation
(IPv6 Neighbor Discovery related flow mods). The default configuration is false (disabled). This fixes ONOS-1146 The configurable parameters are: tools/package/etc/org.onosproject.provider.host.impl.HostLocationProvider.cfg - Enable host removal on port/device down events. (NOTE: not IPv6 related, added for completeness) hostRemovalEnabled = true - Enable using IPv6 Neighbor Discovery by the Host Location Provider. ipv6NeighborDiscovery = false tools/package/etc/org.onosproject.proxyarp.ProxyArp.cfg - Enable IPv6 Neighbor Discovery. ipv6NeighborDiscovery = false NOTE: The above IPv6-related configuration has drawbacks, partially because of some PacketService-related side effects. Currently, we don't support enabling ipv6NeighborDiscovery in one of the configuration files, and disabling it in another. Enabling ipv6NeighborDiscovery in one configuration file is practically equivalent to enabling it in both places. Change-Id: Ief558697d85c8dcffc8941c575d0bf7d1397d90d
Showing
5 changed files
with
143 additions
and
10 deletions
... | @@ -31,4 +31,11 @@ | ... | @@ -31,4 +31,11 @@ |
31 | 31 | ||
32 | <description>ONOS simple proxy arp module</description> | 32 | <description>ONOS simple proxy arp module</description> |
33 | 33 | ||
34 | + <dependencies> | ||
35 | + <dependency> | ||
36 | + <groupId>org.osgi</groupId> | ||
37 | + <artifactId>org.osgi.compendium</artifactId> | ||
38 | + </dependency> | ||
39 | + </dependencies> | ||
40 | + | ||
34 | </project> | 41 | </project> | ... | ... |
... | @@ -15,9 +15,13 @@ | ... | @@ -15,9 +15,13 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.proxyarp; | 16 | package org.onosproject.proxyarp; |
17 | 17 | ||
18 | +import java.util.Dictionary; | ||
19 | + | ||
18 | import org.apache.felix.scr.annotations.Activate; | 20 | import org.apache.felix.scr.annotations.Activate; |
19 | import org.apache.felix.scr.annotations.Component; | 21 | import org.apache.felix.scr.annotations.Component; |
20 | import org.apache.felix.scr.annotations.Deactivate; | 22 | import org.apache.felix.scr.annotations.Deactivate; |
23 | +import org.apache.felix.scr.annotations.Modified; | ||
24 | +import org.apache.felix.scr.annotations.Property; | ||
21 | import org.apache.felix.scr.annotations.Reference; | 25 | import org.apache.felix.scr.annotations.Reference; |
22 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 26 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
23 | import org.onlab.packet.Ethernet; | 27 | import org.onlab.packet.Ethernet; |
... | @@ -32,8 +36,10 @@ import org.onosproject.net.packet.PacketPriority; | ... | @@ -32,8 +36,10 @@ import org.onosproject.net.packet.PacketPriority; |
32 | import org.onosproject.net.packet.PacketProcessor; | 36 | import org.onosproject.net.packet.PacketProcessor; |
33 | import org.onosproject.net.packet.PacketService; | 37 | import org.onosproject.net.packet.PacketService; |
34 | import org.onosproject.net.proxyarp.ProxyArpService; | 38 | import org.onosproject.net.proxyarp.ProxyArpService; |
39 | +import org.osgi.service.component.ComponentContext; | ||
35 | import org.slf4j.Logger; | 40 | import org.slf4j.Logger; |
36 | 41 | ||
42 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
37 | import static org.slf4j.LoggerFactory.getLogger; | 43 | import static org.slf4j.LoggerFactory.getLogger; |
38 | 44 | ||
39 | /** | 45 | /** |
... | @@ -57,9 +63,15 @@ public class ProxyArp { | ... | @@ -57,9 +63,15 @@ public class ProxyArp { |
57 | 63 | ||
58 | private ApplicationId appId; | 64 | private ApplicationId appId; |
59 | 65 | ||
66 | + @Property(name = "ipv6NeighborDiscovery", boolValue = false, | ||
67 | + label = "Enable IPv6 Neighbor Discovery; default is false") | ||
68 | + private boolean ipv6NeighborDiscovery = false; | ||
69 | + | ||
60 | @Activate | 70 | @Activate |
61 | - public void activate() { | 71 | + public void activate(ComponentContext context) { |
62 | appId = coreService.registerApplication("org.onosproject.proxyarp"); | 72 | appId = coreService.registerApplication("org.onosproject.proxyarp"); |
73 | + readComponentConfiguration(context); | ||
74 | + | ||
63 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1); | 75 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1); |
64 | 76 | ||
65 | TrafficSelector.Builder selectorBuilder = | 77 | TrafficSelector.Builder selectorBuilder = |
... | @@ -68,6 +80,7 @@ public class ProxyArp { | ... | @@ -68,6 +80,7 @@ public class ProxyArp { |
68 | packetService.requestPackets(selectorBuilder.build(), | 80 | packetService.requestPackets(selectorBuilder.build(), |
69 | PacketPriority.CONTROL, appId); | 81 | PacketPriority.CONTROL, appId); |
70 | 82 | ||
83 | + if (ipv6NeighborDiscovery) { | ||
71 | // IPv6 Neighbor Solicitation packet. | 84 | // IPv6 Neighbor Solicitation packet. |
72 | selectorBuilder = DefaultTrafficSelector.builder(); | 85 | selectorBuilder = DefaultTrafficSelector.builder(); |
73 | selectorBuilder.matchEthType(Ethernet.TYPE_IPV6); | 86 | selectorBuilder.matchEthType(Ethernet.TYPE_IPV6); |
... | @@ -83,6 +96,7 @@ public class ProxyArp { | ... | @@ -83,6 +96,7 @@ public class ProxyArp { |
83 | selectorBuilder.matchIcmpv6Type(ICMP6.NEIGHBOR_ADVERTISEMENT); | 96 | selectorBuilder.matchIcmpv6Type(ICMP6.NEIGHBOR_ADVERTISEMENT); |
84 | packetService.requestPackets(selectorBuilder.build(), | 97 | packetService.requestPackets(selectorBuilder.build(), |
85 | PacketPriority.CONTROL, appId); | 98 | PacketPriority.CONTROL, appId); |
99 | + } | ||
86 | 100 | ||
87 | log.info("Started with Application ID {}", appId.id()); | 101 | log.info("Started with Application ID {}", appId.id()); |
88 | } | 102 | } |
... | @@ -94,6 +108,50 @@ public class ProxyArp { | ... | @@ -94,6 +108,50 @@ public class ProxyArp { |
94 | log.info("Stopped"); | 108 | log.info("Stopped"); |
95 | } | 109 | } |
96 | 110 | ||
111 | + @Modified | ||
112 | + public void modified(ComponentContext context) { | ||
113 | + readComponentConfiguration(context); | ||
114 | + } | ||
115 | + | ||
116 | + /** | ||
117 | + * Extracts properties from the component configuration context. | ||
118 | + * | ||
119 | + * @param context the component context | ||
120 | + */ | ||
121 | + private void readComponentConfiguration(ComponentContext context) { | ||
122 | + Dictionary<?, ?> properties = context.getProperties(); | ||
123 | + Boolean flag; | ||
124 | + | ||
125 | + flag = isPropertyEnabled(properties, "ipv6NeighborDiscovery"); | ||
126 | + if (flag == null) { | ||
127 | + log.info("IPv6 Neighbor Discovery is not configured, " + | ||
128 | + "using current value of {}", ipv6NeighborDiscovery); | ||
129 | + } else { | ||
130 | + ipv6NeighborDiscovery = flag; | ||
131 | + log.info("Configured. IPv6 Neighbor Discovery is {}", | ||
132 | + ipv6NeighborDiscovery ? "enabled" : "disabled"); | ||
133 | + } | ||
134 | + } | ||
135 | + | ||
136 | + /** | ||
137 | + * Check property name is defined and set to true. | ||
138 | + * | ||
139 | + * @param properties properties to be looked up | ||
140 | + * @param propertyName the name of the property to look up | ||
141 | + * @return value when the propertyName is defined or return null | ||
142 | + */ | ||
143 | + private static Boolean isPropertyEnabled(Dictionary<?, ?> properties, | ||
144 | + String propertyName) { | ||
145 | + Boolean value = null; | ||
146 | + try { | ||
147 | + String s = (String) properties.get(propertyName); | ||
148 | + value = isNullOrEmpty(s) ? null : s.trim().equals("true"); | ||
149 | + } catch (ClassCastException e) { | ||
150 | + // No propertyName defined. | ||
151 | + value = null; | ||
152 | + } | ||
153 | + return value; | ||
154 | + } | ||
97 | 155 | ||
98 | /** | 156 | /** |
99 | * Packet processor responsible for forwarding packets along their paths. | 157 | * Packet processor responsible for forwarding packets along their paths. | ... | ... |
... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.provider.host.impl; | 16 | package org.onosproject.provider.host.impl; |
17 | 17 | ||
18 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
18 | import static org.slf4j.LoggerFactory.getLogger; | 19 | import static org.slf4j.LoggerFactory.getLogger; |
19 | 20 | ||
20 | import java.util.Dictionary; | 21 | import java.util.Dictionary; |
... | @@ -103,6 +104,10 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -103,6 +104,10 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
103 | label = "Enable host removal on port/device down events") | 104 | label = "Enable host removal on port/device down events") |
104 | private boolean hostRemovalEnabled = true; | 105 | private boolean hostRemovalEnabled = true; |
105 | 106 | ||
107 | + @Property(name = "ipv6NeighborDiscovery", boolValue = false, | ||
108 | + label = "Enable using IPv6 Neighbor Discovery by the " + | ||
109 | + "Host Location Provider; default is false") | ||
110 | + private boolean ipv6NeighborDiscovery = false; | ||
106 | 111 | ||
107 | /** | 112 | /** |
108 | * Creates an OpenFlow host provider. | 113 | * Creates an OpenFlow host provider. |
... | @@ -115,8 +120,8 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -115,8 +120,8 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
115 | public void activate(ComponentContext context) { | 120 | public void activate(ComponentContext context) { |
116 | appId = | 121 | appId = |
117 | coreService.registerApplication("org.onosproject.provider.host"); | 122 | coreService.registerApplication("org.onosproject.provider.host"); |
123 | + readComponentConfiguration(context); | ||
118 | 124 | ||
119 | - modified(context); | ||
120 | providerService = providerRegistry.register(this); | 125 | providerService = providerRegistry.register(this); |
121 | packetService.addProcessor(processor, 1); | 126 | packetService.addProcessor(processor, 1); |
122 | deviceService.addListener(deviceListener); | 127 | deviceService.addListener(deviceListener); |
... | @@ -127,6 +132,7 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -127,6 +132,7 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
127 | packetService.requestPackets(selectorBuilder.build(), | 132 | packetService.requestPackets(selectorBuilder.build(), |
128 | PacketPriority.CONTROL, appId); | 133 | PacketPriority.CONTROL, appId); |
129 | 134 | ||
135 | + if (ipv6NeighborDiscovery) { | ||
130 | // IPv6 Neighbor Solicitation packet. | 136 | // IPv6 Neighbor Solicitation packet. |
131 | selectorBuilder = DefaultTrafficSelector.builder(); | 137 | selectorBuilder = DefaultTrafficSelector.builder(); |
132 | selectorBuilder.matchEthType(Ethernet.TYPE_IPV6); | 138 | selectorBuilder.matchEthType(Ethernet.TYPE_IPV6); |
... | @@ -142,6 +148,7 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -142,6 +148,7 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
142 | selectorBuilder.matchIcmpv6Type(ICMP6.NEIGHBOR_ADVERTISEMENT); | 148 | selectorBuilder.matchIcmpv6Type(ICMP6.NEIGHBOR_ADVERTISEMENT); |
143 | packetService.requestPackets(selectorBuilder.build(), | 149 | packetService.requestPackets(selectorBuilder.build(), |
144 | PacketPriority.CONTROL, appId); | 150 | PacketPriority.CONTROL, appId); |
151 | + } | ||
145 | 152 | ||
146 | log.info("Started with Application ID {}", appId.id()); | 153 | log.info("Started with Application ID {}", appId.id()); |
147 | } | 154 | } |
... | @@ -157,17 +164,57 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -157,17 +164,57 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
157 | 164 | ||
158 | @Modified | 165 | @Modified |
159 | public void modified(ComponentContext context) { | 166 | public void modified(ComponentContext context) { |
160 | - Dictionary properties = context.getProperties(); | 167 | + readComponentConfiguration(context); |
161 | - try { | ||
162 | - String flag = (String) properties.get("hostRemovalEnabled"); | ||
163 | - if (flag != null) { | ||
164 | - hostRemovalEnabled = flag.equals("true"); | ||
165 | } | 168 | } |
169 | + | ||
170 | + /** | ||
171 | + * Extracts properties from the component configuration context. | ||
172 | + * | ||
173 | + * @param context the component context | ||
174 | + */ | ||
175 | + private void readComponentConfiguration(ComponentContext context) { | ||
176 | + Dictionary<?, ?> properties = context.getProperties(); | ||
177 | + Boolean flag; | ||
178 | + | ||
179 | + flag = isPropertyEnabled(properties, "hostRemovalEnabled"); | ||
180 | + if (flag == null) { | ||
181 | + log.info("Host removal on port/device down events is not configured, " + | ||
182 | + "using current value of {}", hostRemovalEnabled); | ||
183 | + } else { | ||
184 | + hostRemovalEnabled = flag; | ||
185 | + log.info("Configured. Host removal on port/device down events is {}", | ||
186 | + hostRemovalEnabled ? "enabled" : "disabled"); | ||
187 | + } | ||
188 | + | ||
189 | + flag = isPropertyEnabled(properties, "ipv6NeighborDiscovery"); | ||
190 | + if (flag == null) { | ||
191 | + log.info("Using IPv6 Neighbor Discovery is not configured, " + | ||
192 | + "using current value of {}", ipv6NeighborDiscovery); | ||
193 | + } else { | ||
194 | + ipv6NeighborDiscovery = flag; | ||
195 | + log.info("Configured. Using IPv6 Neighbor Discovery is {}", | ||
196 | + ipv6NeighborDiscovery ? "enabled" : "disabled"); | ||
197 | + } | ||
198 | + } | ||
199 | + | ||
200 | + /** | ||
201 | + * Check property name is defined and set to true. | ||
202 | + * | ||
203 | + * @param properties properties to be looked up | ||
204 | + * @param propertyName the name of the property to look up | ||
205 | + * @return value when the propertyName is defined or return null | ||
206 | + */ | ||
207 | + private static Boolean isPropertyEnabled(Dictionary<?, ?> properties, | ||
208 | + String propertyName) { | ||
209 | + Boolean value = null; | ||
210 | + try { | ||
211 | + String s = (String) properties.get(propertyName); | ||
212 | + value = isNullOrEmpty(s) ? null : s.trim().equals("true"); | ||
166 | } catch (ClassCastException e) { | 213 | } catch (ClassCastException e) { |
167 | - hostRemovalEnabled = true; | 214 | + // No propertyName defined. |
215 | + value = null; | ||
168 | } | 216 | } |
169 | - log.info("Host removal is {}", | 217 | + return value; |
170 | - hostRemovalEnabled ? "enabled" : "disabled"); | ||
171 | } | 218 | } |
172 | 219 | ||
173 | @Override | 220 | @Override | ... | ... |
1 | +# | ||
2 | +# Sample configuration for Host Location Provider | ||
3 | +# This configuration file would be placed at: $(KARAF_ROOT)/etc. | ||
4 | + | ||
5 | +# | ||
6 | +# Enable host removal on port/device down events. | ||
7 | +# | ||
8 | +# hostRemovalEnabled = true | ||
9 | + | ||
10 | +# | ||
11 | +# Enable using IPv6 Neighbor Discovery by the Host Location Provider. | ||
12 | +# | ||
13 | +# ipv6NeighborDiscovery = false |
-
Please register or login to post a comment