BGP router now handles the case where groups don't exists right away.
Also reworked some logic to make delete routes work. Change-Id: I1f65279284b85144a847f1295fcbd7695cb59167
Showing
6 changed files
with
182 additions
and
66 deletions
... | @@ -16,6 +16,9 @@ | ... | @@ -16,6 +16,9 @@ |
16 | package org.onosproject.bgprouter; | 16 | package org.onosproject.bgprouter; |
17 | 17 | ||
18 | import com.google.common.collect.ConcurrentHashMultiset; | 18 | import com.google.common.collect.ConcurrentHashMultiset; |
19 | +import com.google.common.collect.HashMultimap; | ||
20 | +import com.google.common.collect.Maps; | ||
21 | +import com.google.common.collect.Multimap; | ||
19 | import com.google.common.collect.Multiset; | 22 | import com.google.common.collect.Multiset; |
20 | import org.apache.felix.scr.annotations.Activate; | 23 | import org.apache.felix.scr.annotations.Activate; |
21 | import org.apache.felix.scr.annotations.Component; | 24 | import org.apache.felix.scr.annotations.Component; |
... | @@ -24,6 +27,8 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -24,6 +27,8 @@ import org.apache.felix.scr.annotations.Reference; |
24 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 27 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
25 | import org.onlab.packet.Ethernet; | 28 | import org.onlab.packet.Ethernet; |
26 | import org.onlab.packet.MacAddress; | 29 | import org.onlab.packet.MacAddress; |
30 | +import org.onlab.packet.IpAddress; | ||
31 | +import org.onlab.packet.IpPrefix; | ||
27 | import org.onosproject.core.ApplicationId; | 32 | import org.onosproject.core.ApplicationId; |
28 | import org.onosproject.core.CoreService; | 33 | import org.onosproject.core.CoreService; |
29 | import org.onosproject.net.DeviceId; | 34 | import org.onosproject.net.DeviceId; |
... | @@ -42,9 +47,12 @@ import org.onosproject.net.group.Group; | ... | @@ -42,9 +47,12 @@ import org.onosproject.net.group.Group; |
42 | import org.onosproject.net.group.GroupBucket; | 47 | import org.onosproject.net.group.GroupBucket; |
43 | import org.onosproject.net.group.GroupBuckets; | 48 | import org.onosproject.net.group.GroupBuckets; |
44 | import org.onosproject.net.group.GroupDescription; | 49 | import org.onosproject.net.group.GroupDescription; |
50 | +import org.onosproject.net.group.GroupEvent; | ||
45 | import org.onosproject.net.group.GroupKey; | 51 | import org.onosproject.net.group.GroupKey; |
52 | +import org.onosproject.net.group.GroupListener; | ||
46 | import org.onosproject.net.group.GroupService; | 53 | import org.onosproject.net.group.GroupService; |
47 | import org.onosproject.net.packet.PacketService; | 54 | import org.onosproject.net.packet.PacketService; |
55 | +import org.onosproject.routing.FibEntry; | ||
48 | import org.onosproject.routing.FibListener; | 56 | import org.onosproject.routing.FibListener; |
49 | import org.onosproject.routing.FibUpdate; | 57 | import org.onosproject.routing.FibUpdate; |
50 | import org.onosproject.routing.RoutingService; | 58 | import org.onosproject.routing.RoutingService; |
... | @@ -55,7 +63,6 @@ import org.slf4j.LoggerFactory; | ... | @@ -55,7 +63,6 @@ import org.slf4j.LoggerFactory; |
55 | 63 | ||
56 | import java.util.Collection; | 64 | import java.util.Collection; |
57 | import java.util.Collections; | 65 | import java.util.Collections; |
58 | -import java.util.HashMap; | ||
59 | import java.util.Map; | 66 | import java.util.Map; |
60 | 67 | ||
61 | /** | 68 | /** |
... | @@ -90,20 +97,32 @@ public class BgpRouter { | ... | @@ -90,20 +97,32 @@ public class BgpRouter { |
90 | 97 | ||
91 | private ApplicationId appId; | 98 | private ApplicationId appId; |
92 | 99 | ||
93 | - private final Multiset<NextHop> nextHops = ConcurrentHashMultiset.create(); | 100 | + // Reference count for how many times a next hop is used by a route |
94 | - private final Map<NextHop, NextHopGroupKey> groups = new HashMap<>(); | 101 | + private final Multiset<IpAddress> nextHopsCount = ConcurrentHashMultiset.create(); |
102 | + | ||
103 | + // Mapping from prefix to its current next hop | ||
104 | + private final Map<IpPrefix, IpAddress> prefixToNextHop = Maps.newHashMap(); | ||
105 | + | ||
106 | + // Mapping from next hop IP to next hop object containing group info | ||
107 | + private final Map<IpAddress, NextHop> nextHops = Maps.newHashMap(); | ||
108 | + | ||
109 | + // Stores FIB updates that are waiting for groups to be set up | ||
110 | + private final Multimap<GroupKey, FibEntry> pendingUpdates = HashMultimap.create(); | ||
95 | 111 | ||
96 | private DeviceId deviceId = DeviceId.deviceId("of:0000000000000001"); // TODO config | 112 | private DeviceId deviceId = DeviceId.deviceId("of:0000000000000001"); // TODO config |
97 | 113 | ||
114 | + private final GroupListener groupListener = new InternalGroupListener(); | ||
115 | + | ||
98 | private TunnellingConnectivityManager connectivityManager; | 116 | private TunnellingConnectivityManager connectivityManager; |
99 | 117 | ||
100 | private InternalTableHandler provisionStaticTables = new InternalTableHandler(); | 118 | private InternalTableHandler provisionStaticTables = new InternalTableHandler(); |
101 | 119 | ||
102 | @Activate | 120 | @Activate |
103 | protected void activate() { | 121 | protected void activate() { |
104 | - log.info("Bgp1Router started"); | ||
105 | appId = coreService.registerApplication(BGP_ROUTER_APP); | 122 | appId = coreService.registerApplication(BGP_ROUTER_APP); |
106 | 123 | ||
124 | + groupService.addListener(groupListener); | ||
125 | + | ||
107 | provisionStaticTables.provision(true); | 126 | provisionStaticTables.provision(true); |
108 | 127 | ||
109 | connectivityManager = new TunnellingConnectivityManager(appId, | 128 | connectivityManager = new TunnellingConnectivityManager(appId, |
... | @@ -123,29 +142,38 @@ public class BgpRouter { | ... | @@ -123,29 +142,38 @@ public class BgpRouter { |
123 | connectivityManager.stop(); | 142 | connectivityManager.stop(); |
124 | provisionStaticTables.provision(false); | 143 | provisionStaticTables.provision(false); |
125 | 144 | ||
145 | + groupService.removeListener(groupListener); | ||
146 | + | ||
126 | log.info("BgpRouter stopped"); | 147 | log.info("BgpRouter stopped"); |
127 | } | 148 | } |
128 | 149 | ||
129 | private void updateFibEntry(Collection<FibUpdate> updates) { | 150 | private void updateFibEntry(Collection<FibUpdate> updates) { |
130 | for (FibUpdate update : updates) { | 151 | for (FibUpdate update : updates) { |
131 | - NextHop nextHop = new NextHop(update.entry().nextHopIp(), | 152 | + FibEntry entry = update.entry(); |
132 | - update.entry().nextHopMac()); | ||
133 | 153 | ||
134 | - addNextHop(nextHop); | 154 | + addNextHop(entry); |
135 | 155 | ||
136 | - TrafficSelector selector = DefaultTrafficSelector.builder() | 156 | + Group group; |
137 | - .matchEthType(Ethernet.TYPE_IPV4) | 157 | + synchronized (pendingUpdates) { |
138 | - .matchIPDst(update.entry().prefix()) | 158 | + NextHop nextHop = nextHops.get(entry.nextHopIp()); |
139 | - .build(); | 159 | + group = groupService.getGroup(deviceId, nextHop.group()); |
140 | 160 | ||
141 | - // TODO ensure group exists | ||
142 | - NextHopGroupKey groupKey = groups.get(nextHop); | ||
143 | - Group group = groupService.getGroup(deviceId, groupKey); | ||
144 | if (group == null) { | 161 | if (group == null) { |
145 | - // TODO handle this | 162 | + log.debug("Adding pending flow {}", update.entry()); |
146 | - log.warn("oops, group {} wasn't there"); | 163 | + pendingUpdates.put(nextHop.group(), update.entry()); |
147 | continue; | 164 | continue; |
148 | } | 165 | } |
166 | + } | ||
167 | + | ||
168 | + installFlow(update.entry(), group); | ||
169 | + } | ||
170 | + } | ||
171 | + | ||
172 | + private void installFlow(FibEntry entry, Group group) { | ||
173 | + TrafficSelector selector = DefaultTrafficSelector.builder() | ||
174 | + .matchEthType(Ethernet.TYPE_IPV4) | ||
175 | + .matchIPDst(entry.prefix()) | ||
176 | + .build(); | ||
149 | 177 | ||
150 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 178 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
151 | .group(group.id()) | 179 | .group(group.id()) |
... | @@ -157,16 +185,15 @@ public class BgpRouter { | ... | @@ -157,16 +185,15 @@ public class BgpRouter { |
157 | 185 | ||
158 | flowService.applyFlowRules(flowRule); | 186 | flowService.applyFlowRules(flowRule); |
159 | } | 187 | } |
160 | - } | ||
161 | 188 | ||
162 | - private void deleteFibEntry(Collection<FibUpdate> withdraws) { | 189 | + private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) { |
163 | for (FibUpdate update : withdraws) { | 190 | for (FibUpdate update : withdraws) { |
164 | - NextHop nextHop = new NextHop(update.entry().nextHopIp(), | 191 | + FibEntry entry = update.entry(); |
165 | - update.entry().nextHopMac()); | ||
166 | 192 | ||
167 | - deleteNextHop(nextHop); | 193 | + deleteNextHop(entry.prefix()); |
168 | 194 | ||
169 | TrafficSelector selector = DefaultTrafficSelector.builder() | 195 | TrafficSelector selector = DefaultTrafficSelector.builder() |
196 | + .matchEthType(Ethernet.TYPE_IPV4) | ||
170 | .matchIPDst(update.entry().prefix()) | 197 | .matchIPDst(update.entry().prefix()) |
171 | .build(); | 198 | .build(); |
172 | 199 | ||
... | @@ -178,18 +205,20 @@ public class BgpRouter { | ... | @@ -178,18 +205,20 @@ public class BgpRouter { |
178 | } | 205 | } |
179 | } | 206 | } |
180 | 207 | ||
181 | - private void addNextHop(NextHop nextHop) { | 208 | + private synchronized void addNextHop(FibEntry entry) { |
182 | - if (nextHops.add(nextHop, 1) == 0) { | 209 | + prefixToNextHop.put(entry.prefix(), entry.nextHopIp()); |
210 | + if (nextHopsCount.count(entry.nextHopIp()) == 0) { | ||
183 | // There was no next hop in the multiset | 211 | // There was no next hop in the multiset |
184 | 212 | ||
185 | - Interface egressIntf = configService.getMatchingInterface(nextHop.ip()); | 213 | + Interface egressIntf = configService.getMatchingInterface(entry.nextHopIp()); |
186 | if (egressIntf == null) { | 214 | if (egressIntf == null) { |
187 | - log.warn("no egress interface found for {}", nextHop); | 215 | + log.warn("no egress interface found for {}", entry); |
188 | return; | 216 | return; |
189 | } | 217 | } |
190 | 218 | ||
191 | - NextHopGroupKey groupKey = new NextHopGroupKey(nextHop.ip()); | 219 | + NextHopGroupKey groupKey = new NextHopGroupKey(entry.nextHopIp()); |
192 | - groups.put(nextHop, groupKey); | 220 | + |
221 | + NextHop nextHop = new NextHop(entry.nextHopIp(), entry.nextHopMac(), groupKey); | ||
193 | 222 | ||
194 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 223 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
195 | .setEthSrc(egressIntf.mac()) | 224 | .setEthSrc(egressIntf.mac()) |
... | @@ -209,17 +238,30 @@ public class BgpRouter { | ... | @@ -209,17 +238,30 @@ public class BgpRouter { |
209 | appId); | 238 | appId); |
210 | 239 | ||
211 | groupService.addGroup(groupDescription); | 240 | groupService.addGroup(groupDescription); |
241 | + | ||
242 | + nextHops.put(nextHop.ip(), nextHop); | ||
243 | + | ||
212 | } | 244 | } |
245 | + | ||
246 | + nextHopsCount.add(entry.nextHopIp()); | ||
247 | + } | ||
248 | + | ||
249 | + private synchronized void deleteNextHop(IpPrefix prefix) { | ||
250 | + IpAddress nextHopIp = prefixToNextHop.remove(prefix); | ||
251 | + NextHop nextHop = nextHops.get(nextHopIp); | ||
252 | + if (nextHop == null) { | ||
253 | + log.warn("No next hop found when removing prefix {}", prefix); | ||
254 | + return; | ||
213 | } | 255 | } |
214 | 256 | ||
215 | - private void deleteNextHop(NextHop nextHop) { | 257 | + if (nextHopsCount.remove(nextHopIp, 1) <= 1) { |
216 | - if (nextHops.remove(nextHop, 1) <= 1) { | ||
217 | // There was one or less next hops, so there are now none | 258 | // There was one or less next hops, so there are now none |
218 | 259 | ||
219 | - log.debug("removing group"); | 260 | + log.debug("removing group for next hop {}", nextHop); |
261 | + | ||
262 | + nextHops.remove(nextHopIp); | ||
220 | 263 | ||
221 | - GroupKey groupKey = groups.remove(nextHop); | 264 | + groupService.removeGroup(deviceId, nextHop.group(), appId); |
222 | - groupService.removeGroup(deviceId, groupKey, appId); | ||
223 | } | 265 | } |
224 | } | 266 | } |
225 | 267 | ||
... | @@ -238,7 +280,6 @@ public class BgpRouter { | ... | @@ -238,7 +280,6 @@ public class BgpRouter { |
238 | private static final int CONTROLLER_PRIORITY = 255; | 280 | private static final int CONTROLLER_PRIORITY = 255; |
239 | private static final int DROP_PRIORITY = 0; | 281 | private static final int DROP_PRIORITY = 0; |
240 | 282 | ||
241 | - | ||
242 | public void provision(boolean install) { | 283 | public void provision(boolean install) { |
243 | 284 | ||
244 | processTableZero(install); | 285 | processTableZero(install); |
... | @@ -262,14 +303,14 @@ public class BgpRouter { | ... | @@ -262,14 +303,14 @@ public class BgpRouter { |
262 | treatment.transition(FlowRule.Type.VLAN_MPLS); | 303 | treatment.transition(FlowRule.Type.VLAN_MPLS); |
263 | 304 | ||
264 | FlowRule rule = new DefaultFlowRule(deviceId, selector.build(), | 305 | FlowRule rule = new DefaultFlowRule(deviceId, selector.build(), |
265 | - treatment.build(), CONTROLLER_PRIORITY, | 306 | + treatment.build(), |
266 | - appId, 0, true); | 307 | + CONTROLLER_PRIORITY, appId, 0, |
308 | + true); | ||
267 | 309 | ||
268 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 310 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
269 | 311 | ||
270 | ops = install ? ops.add(rule) : ops.remove(rule); | 312 | ops = install ? ops.add(rule) : ops.remove(rule); |
271 | 313 | ||
272 | - | ||
273 | //Drop rule | 314 | //Drop rule |
274 | selector = DefaultTrafficSelector.builder(); | 315 | selector = DefaultTrafficSelector.builder(); |
275 | treatment = DefaultTrafficTreatment.builder(); | 316 | treatment = DefaultTrafficTreatment.builder(); |
... | @@ -277,8 +318,8 @@ public class BgpRouter { | ... | @@ -277,8 +318,8 @@ public class BgpRouter { |
277 | treatment.drop(); | 318 | treatment.drop(); |
278 | 319 | ||
279 | rule = new DefaultFlowRule(deviceId, selector.build(), | 320 | rule = new DefaultFlowRule(deviceId, selector.build(), |
280 | - treatment.build(), DROP_PRIORITY, | 321 | + treatment.build(), DROP_PRIORITY, appId, |
281 | - appId, 0, true, FlowRule.Type.VLAN_MPLS); | 322 | + 0, true, FlowRule.Type.VLAN_MPLS); |
282 | 323 | ||
283 | ops = install ? ops.add(rule) : ops.remove(rule); | 324 | ops = install ? ops.add(rule) : ops.remove(rule); |
284 | 325 | ||
... | @@ -298,15 +339,15 @@ public class BgpRouter { | ... | @@ -298,15 +339,15 @@ public class BgpRouter { |
298 | 339 | ||
299 | private void processTableOne(boolean install) { | 340 | private void processTableOne(boolean install) { |
300 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 341 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
301 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 342 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment |
343 | + .builder(); | ||
302 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 344 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
303 | FlowRule rule; | 345 | FlowRule rule; |
304 | 346 | ||
305 | selector.matchEthType(Ethernet.TYPE_IPV4); | 347 | selector.matchEthType(Ethernet.TYPE_IPV4); |
306 | treatment.transition(FlowRule.Type.VLAN); | 348 | treatment.transition(FlowRule.Type.VLAN); |
307 | 349 | ||
308 | - rule = new DefaultFlowRule(deviceId, selector.build(), | 350 | + rule = new DefaultFlowRule(deviceId, selector.build(), treatment.build(), CONTROLLER_PRIORITY, |
309 | - treatment.build(), CONTROLLER_PRIORITY, | ||
310 | appId, 0, true, FlowRule.Type.VLAN_MPLS); | 351 | appId, 0, true, FlowRule.Type.VLAN_MPLS); |
311 | 352 | ||
312 | ops = install ? ops.add(rule) : ops.remove(rule); | 353 | ops = install ? ops.add(rule) : ops.remove(rule); |
... | @@ -342,8 +383,8 @@ public class BgpRouter { | ... | @@ -342,8 +383,8 @@ public class BgpRouter { |
342 | treatment.drop(); | 383 | treatment.drop(); |
343 | 384 | ||
344 | rule = new DefaultFlowRule(deviceId, selector.build(), | 385 | rule = new DefaultFlowRule(deviceId, selector.build(), |
345 | - treatment.build(), DROP_PRIORITY, | 386 | + treatment.build(), DROP_PRIORITY, appId, |
346 | - appId, 0, true, FlowRule.Type.VLAN_MPLS); | 387 | + 0, true, FlowRule.Type.VLAN_MPLS); |
347 | 388 | ||
348 | ops = install ? ops.add(rule) : ops.remove(rule); | 389 | ops = install ? ops.add(rule) : ops.remove(rule); |
349 | 390 | ||
... | @@ -355,7 +396,8 @@ public class BgpRouter { | ... | @@ -355,7 +396,8 @@ public class BgpRouter { |
355 | 396 | ||
356 | @Override | 397 | @Override |
357 | public void onError(FlowRuleOperations ops) { | 398 | public void onError(FlowRuleOperations ops) { |
358 | - log.info("Failed to provision vlan/mpls table for bgp router"); | 399 | + log.info( |
400 | + "Failed to provision vlan/mpls table for bgp router"); | ||
359 | } | 401 | } |
360 | })); | 402 | })); |
361 | 403 | ||
... | @@ -363,7 +405,8 @@ public class BgpRouter { | ... | @@ -363,7 +405,8 @@ public class BgpRouter { |
363 | 405 | ||
364 | private void processTableTwo(boolean install) { | 406 | private void processTableTwo(boolean install) { |
365 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 407 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
366 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 408 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment |
409 | + .builder(); | ||
367 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 410 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
368 | FlowRule rule; | 411 | FlowRule rule; |
369 | 412 | ||
... | @@ -372,8 +415,8 @@ public class BgpRouter { | ... | @@ -372,8 +415,8 @@ public class BgpRouter { |
372 | treatment.drop(); | 415 | treatment.drop(); |
373 | 416 | ||
374 | rule = new DefaultFlowRule(deviceId, selector.build(), | 417 | rule = new DefaultFlowRule(deviceId, selector.build(), |
375 | - treatment.build(), DROP_PRIORITY, | 418 | + treatment.build(), DROP_PRIORITY, appId, |
376 | - appId, 0, true, FlowRule.Type.VLAN); | 419 | + 0, true, FlowRule.Type.VLAN); |
377 | 420 | ||
378 | ops = install ? ops.add(rule) : ops.remove(rule); | 421 | ops = install ? ops.add(rule) : ops.remove(rule); |
379 | 422 | ||
... | @@ -390,11 +433,10 @@ public class BgpRouter { | ... | @@ -390,11 +433,10 @@ public class BgpRouter { |
390 | })); | 433 | })); |
391 | } | 434 | } |
392 | 435 | ||
393 | - | ||
394 | - | ||
395 | private void processTableThree(boolean install) { | 436 | private void processTableThree(boolean install) { |
396 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 437 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
397 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 438 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment |
439 | + .builder(); | ||
398 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 440 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
399 | FlowRule rule; | 441 | FlowRule rule; |
400 | 442 | ||
... | @@ -426,8 +468,8 @@ public class BgpRouter { | ... | @@ -426,8 +468,8 @@ public class BgpRouter { |
426 | treatment.drop(); | 468 | treatment.drop(); |
427 | 469 | ||
428 | rule = new DefaultFlowRule(deviceId, selector.build(), | 470 | rule = new DefaultFlowRule(deviceId, selector.build(), |
429 | - treatment.build(), DROP_PRIORITY, | 471 | + treatment.build(), DROP_PRIORITY, appId, |
430 | - appId, 0, true, FlowRule.Type.VLAN_MPLS); | 472 | + 0, true, FlowRule.Type.VLAN_MPLS); |
431 | 473 | ||
432 | ops = install ? ops.add(rule) : ops.remove(rule); | 474 | ops = install ? ops.add(rule) : ops.remove(rule); |
433 | 475 | ||
... | @@ -443,20 +485,20 @@ public class BgpRouter { | ... | @@ -443,20 +485,20 @@ public class BgpRouter { |
443 | } | 485 | } |
444 | })); | 486 | })); |
445 | 487 | ||
446 | - | ||
447 | } | 488 | } |
448 | 489 | ||
449 | private void processTableFive(boolean install) { | 490 | private void processTableFive(boolean install) { |
450 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 491 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
451 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 492 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment |
493 | + .builder(); | ||
452 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 494 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
453 | FlowRule rule; | 495 | FlowRule rule; |
454 | 496 | ||
455 | treatment.transition(FlowRule.Type.IP); | 497 | treatment.transition(FlowRule.Type.IP); |
456 | 498 | ||
457 | rule = new DefaultFlowRule(deviceId, selector.build(), | 499 | rule = new DefaultFlowRule(deviceId, selector.build(), |
458 | - treatment.build(), DROP_PRIORITY, | 500 | + treatment.build(), DROP_PRIORITY, appId, |
459 | - appId, 0, true, FlowRule.Type.COS); | 501 | + 0, true, FlowRule.Type.COS); |
460 | 502 | ||
461 | ops = install ? ops.add(rule) : ops.remove(rule); | 503 | ops = install ? ops.add(rule) : ops.remove(rule); |
462 | 504 | ||
... | @@ -476,7 +518,8 @@ public class BgpRouter { | ... | @@ -476,7 +518,8 @@ public class BgpRouter { |
476 | 518 | ||
477 | private void processTableSix(boolean install) { | 519 | private void processTableSix(boolean install) { |
478 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 520 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
479 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 521 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment |
522 | + .builder(); | ||
480 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 523 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
481 | FlowRule rule; | 524 | FlowRule rule; |
482 | 525 | ||
... | @@ -485,8 +528,8 @@ public class BgpRouter { | ... | @@ -485,8 +528,8 @@ public class BgpRouter { |
485 | treatment.drop(); | 528 | treatment.drop(); |
486 | 529 | ||
487 | rule = new DefaultFlowRule(deviceId, selector.build(), | 530 | rule = new DefaultFlowRule(deviceId, selector.build(), |
488 | - treatment.build(), DROP_PRIORITY, | 531 | + treatment.build(), DROP_PRIORITY, appId, |
489 | - appId, 0, true, FlowRule.Type.IP); | 532 | + 0, true, FlowRule.Type.IP); |
490 | 533 | ||
491 | ops = install ? ops.add(rule) : ops.remove(rule); | 534 | ops = install ? ops.add(rule) : ops.remove(rule); |
492 | 535 | ||
... | @@ -505,7 +548,8 @@ public class BgpRouter { | ... | @@ -505,7 +548,8 @@ public class BgpRouter { |
505 | 548 | ||
506 | private void processTableNine(boolean install) { | 549 | private void processTableNine(boolean install) { |
507 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 550 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
508 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 551 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment |
552 | + .builder(); | ||
509 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 553 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
510 | FlowRule rule; | 554 | FlowRule rule; |
511 | 555 | ||
... | @@ -529,6 +573,21 @@ public class BgpRouter { | ... | @@ -529,6 +573,21 @@ public class BgpRouter { |
529 | } | 573 | } |
530 | })); | 574 | })); |
531 | } | 575 | } |
576 | + } | ||
577 | + | ||
578 | + private class InternalGroupListener implements GroupListener { | ||
532 | 579 | ||
580 | + @Override | ||
581 | + public void event(GroupEvent event) { | ||
582 | + Group group = event.subject(); | ||
583 | + | ||
584 | + if (event.type() == GroupEvent.Type.GROUP_ADDED || | ||
585 | + event.type() == GroupEvent.Type.GROUP_UPDATED) { | ||
586 | + synchronized (pendingUpdates) { | ||
587 | + pendingUpdates.removeAll(group.appCookie()) | ||
588 | + .forEach((entry) -> installFlow(entry, group)); | ||
589 | + } | ||
590 | + } | ||
591 | + } | ||
533 | } | 592 | } |
534 | } | 593 | } | ... | ... |
... | @@ -18,30 +18,59 @@ package org.onosproject.bgprouter; | ... | @@ -18,30 +18,59 @@ package org.onosproject.bgprouter; |
18 | import com.google.common.base.MoreObjects; | 18 | import com.google.common.base.MoreObjects; |
19 | import org.onlab.packet.IpAddress; | 19 | import org.onlab.packet.IpAddress; |
20 | import org.onlab.packet.MacAddress; | 20 | import org.onlab.packet.MacAddress; |
21 | +import org.onosproject.net.group.GroupKey; | ||
21 | 22 | ||
22 | import java.util.Objects; | 23 | import java.util.Objects; |
23 | 24 | ||
24 | /** | 25 | /** |
25 | - * Created by jono on 2/12/15. | 26 | + * Represents a next hop for routing, whose MAC address has already been resolved. |
26 | */ | 27 | */ |
27 | public class NextHop { | 28 | public class NextHop { |
28 | 29 | ||
29 | private final IpAddress ip; | 30 | private final IpAddress ip; |
30 | private final MacAddress mac; | 31 | private final MacAddress mac; |
32 | + private final GroupKey group; | ||
31 | 33 | ||
32 | - public NextHop(IpAddress ip, MacAddress mac) { | 34 | + /** |
35 | + * Creates a new next hop. | ||
36 | + * | ||
37 | + * @param ip next hop's IP address | ||
38 | + * @param mac next hop's MAC address | ||
39 | + * @param group next hop's group | ||
40 | + */ | ||
41 | + public NextHop(IpAddress ip, MacAddress mac, GroupKey group) { | ||
33 | this.ip = ip; | 42 | this.ip = ip; |
34 | this.mac = mac; | 43 | this.mac = mac; |
44 | + this.group = group; | ||
35 | } | 45 | } |
36 | 46 | ||
47 | + /** | ||
48 | + * Returns the next hop's IP address. | ||
49 | + * | ||
50 | + * @return next hop's IP address | ||
51 | + */ | ||
37 | public IpAddress ip() { | 52 | public IpAddress ip() { |
38 | return ip; | 53 | return ip; |
39 | } | 54 | } |
40 | 55 | ||
56 | + /** | ||
57 | + * Returns the next hop's MAC address. | ||
58 | + * | ||
59 | + * @return next hop's MAC address | ||
60 | + */ | ||
41 | public MacAddress mac() { | 61 | public MacAddress mac() { |
42 | return mac; | 62 | return mac; |
43 | } | 63 | } |
44 | 64 | ||
65 | + /** | ||
66 | + * Returns the next hop group. | ||
67 | + * | ||
68 | + * @return group | ||
69 | + */ | ||
70 | + public GroupKey group() { | ||
71 | + return group; | ||
72 | + } | ||
73 | + | ||
45 | @Override | 74 | @Override |
46 | public boolean equals(Object o) { | 75 | public boolean equals(Object o) { |
47 | if (!(o instanceof NextHop)) { | 76 | if (!(o instanceof NextHop)) { |
... | @@ -51,12 +80,13 @@ public class NextHop { | ... | @@ -51,12 +80,13 @@ public class NextHop { |
51 | NextHop that = (NextHop) o; | 80 | NextHop that = (NextHop) o; |
52 | 81 | ||
53 | return Objects.equals(this.ip, that.ip) && | 82 | return Objects.equals(this.ip, that.ip) && |
54 | - Objects.equals(this.mac, that.mac); | 83 | + Objects.equals(this.mac, that.mac) && |
84 | + Objects.equals(this.group, that.group); | ||
55 | } | 85 | } |
56 | 86 | ||
57 | @Override | 87 | @Override |
58 | public int hashCode() { | 88 | public int hashCode() { |
59 | - return Objects.hash(ip, mac); | 89 | + return Objects.hash(ip, mac, group); |
60 | } | 90 | } |
61 | 91 | ||
62 | @Override | 92 | @Override |
... | @@ -64,6 +94,7 @@ public class NextHop { | ... | @@ -64,6 +94,7 @@ public class NextHop { |
64 | return MoreObjects.toStringHelper(getClass()) | 94 | return MoreObjects.toStringHelper(getClass()) |
65 | .add("ip", ip) | 95 | .add("ip", ip) |
66 | .add("mac", mac) | 96 | .add("mac", mac) |
97 | + .add("group", group) | ||
67 | .toString(); | 98 | .toString(); |
68 | } | 99 | } |
69 | } | 100 | } | ... | ... |
... | @@ -24,16 +24,26 @@ import java.util.Objects; | ... | @@ -24,16 +24,26 @@ import java.util.Objects; |
24 | import static com.google.common.base.Preconditions.checkNotNull; | 24 | import static com.google.common.base.Preconditions.checkNotNull; |
25 | 25 | ||
26 | /** | 26 | /** |
27 | - * Created by jono on 2/16/15. | 27 | + * Identifier for a next hop group. |
28 | */ | 28 | */ |
29 | public class NextHopGroupKey implements GroupKey { | 29 | public class NextHopGroupKey implements GroupKey { |
30 | 30 | ||
31 | private final IpAddress address; | 31 | private final IpAddress address; |
32 | 32 | ||
33 | + /** | ||
34 | + * Creates a new next hop group key. | ||
35 | + * | ||
36 | + * @param address next hop's IP address | ||
37 | + */ | ||
33 | public NextHopGroupKey(IpAddress address) { | 38 | public NextHopGroupKey(IpAddress address) { |
34 | this.address = checkNotNull(address); | 39 | this.address = checkNotNull(address); |
35 | } | 40 | } |
36 | 41 | ||
42 | + /** | ||
43 | + * Returns the next hop's IP address. | ||
44 | + * | ||
45 | + * @return next hop's IP address | ||
46 | + */ | ||
37 | public IpAddress address() { | 47 | public IpAddress address() { |
38 | return address; | 48 | return address; |
39 | } | 49 | } | ... | ... |
... | @@ -288,8 +288,16 @@ public class DistributedStatisticStore implements StatisticStore { | ... | @@ -288,8 +288,16 @@ public class DistributedStatisticStore implements StatisticStore { |
288 | 288 | ||
289 | private ConnectPoint buildConnectPoint(FlowRule rule) { | 289 | private ConnectPoint buildConnectPoint(FlowRule rule) { |
290 | PortNumber port = getOutput(rule); | 290 | PortNumber port = getOutput(rule); |
291 | + | ||
292 | + boolean hasGoto = rule.treatment().instructions() | ||
293 | + .stream() | ||
294 | + .anyMatch(i -> (i instanceof Instructions.GroupInstruction) | ||
295 | + || (i instanceof Instructions.TableTypeTransition)); | ||
296 | + | ||
291 | if (port == null) { | 297 | if (port == null) { |
298 | + if (!hasGoto) { | ||
292 | log.debug("Rule {} has no output.", rule); | 299 | log.debug("Rule {} has no output.", rule); |
300 | + } | ||
293 | return null; | 301 | return null; |
294 | } | 302 | } |
295 | ConnectPoint cp = new ConnectPoint(rule.deviceId(), port); | 303 | ConnectPoint cp = new ConnectPoint(rule.deviceId(), port); | ... | ... |
... | @@ -154,8 +154,16 @@ public class SimpleStatisticStore implements StatisticStore { | ... | @@ -154,8 +154,16 @@ public class SimpleStatisticStore implements StatisticStore { |
154 | 154 | ||
155 | private ConnectPoint buildConnectPoint(FlowRule rule) { | 155 | private ConnectPoint buildConnectPoint(FlowRule rule) { |
156 | PortNumber port = getOutput(rule); | 156 | PortNumber port = getOutput(rule); |
157 | + | ||
158 | + boolean hasGoto = rule.treatment().instructions() | ||
159 | + .stream() | ||
160 | + .anyMatch(i -> (i instanceof Instructions.GroupInstruction) | ||
161 | + || (i instanceof Instructions.TableTypeTransition)); | ||
162 | + | ||
157 | if (port == null) { | 163 | if (port == null) { |
164 | + if (!hasGoto) { | ||
158 | log.debug("Rule {} has no output.", rule); | 165 | log.debug("Rule {} has no output.", rule); |
166 | + } | ||
159 | return null; | 167 | return null; |
160 | } | 168 | } |
161 | ConnectPoint cp = new ConnectPoint(rule.deviceId(), port); | 169 | ConnectPoint cp = new ConnectPoint(rule.deviceId(), port); | ... | ... |
... | @@ -310,7 +310,7 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv | ... | @@ -310,7 +310,7 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv |
310 | break; | 310 | break; |
311 | } | 311 | } |
312 | default: | 312 | default: |
313 | - log.debug("Unhandled message type: {}", msg.getType()); | 313 | + break; |
314 | } | 314 | } |
315 | } | 315 | } |
316 | 316 | ... | ... |
-
Please register or login to post a comment