Charles Chan
Committed by Gerrit Code Review

CORD-349 Support VLAN cross-connect traffic

Change related to this topic:
- Support VLAN cross-connect traffic
    Utilize ports subjectClass to achieve. For non-xConnect port, set interface VLAN to -1
- Remove VLAN checking since we have multiple VLANs per port
- Hash the L2 interface group key generation to include VLAN as well
- Update the network-cfg.json sample

Other refactoring changes:
- Read next objective stores from srManager directly
- Use constant for flow priority
- CORD-267 Javadoc fix

Change-Id: I4ca8c2d9c8b3633a4a0101c5070d19343f7e5b90
Showing 31 changed files with 675 additions and 234 deletions
...@@ -41,6 +41,10 @@ import java.util.Set; ...@@ -41,6 +41,10 @@ import java.util.Set;
41 41
42 import static com.google.common.base.Preconditions.checkNotNull; 42 import static com.google.common.base.Preconditions.checkNotNull;
43 43
44 +/**
45 + * Handler of ARP packets that responses or forwards ARP packets that
46 + * are sent to the controller.
47 + */
44 public class ArpHandler { 48 public class ArpHandler {
45 49
46 private static Logger log = LoggerFactory.getLogger(ArpHandler.class); 50 private static Logger log = LoggerFactory.getLogger(ArpHandler.class);
......
...@@ -37,6 +37,10 @@ import java.util.concurrent.locks.ReentrantLock; ...@@ -37,6 +37,10 @@ import java.util.concurrent.locks.ReentrantLock;
37 37
38 import static com.google.common.base.Preconditions.checkNotNull; 38 import static com.google.common.base.Preconditions.checkNotNull;
39 39
40 +/**
41 + * Default routing handler that is responsible for route computing and
42 + * routing rule population.
43 + */
40 public class DefaultRoutingHandler { 44 public class DefaultRoutingHandler {
41 45
42 private static Logger log = LoggerFactory 46 private static Logger log = LoggerFactory
...@@ -512,6 +516,7 @@ public class DefaultRoutingHandler { ...@@ -512,6 +516,7 @@ public class DefaultRoutingHandler {
512 */ 516 */
513 public void populatePortAddressingRules(DeviceId deviceId) { 517 public void populatePortAddressingRules(DeviceId deviceId) {
514 rulePopulator.populateRouterMacVlanFilters(deviceId); 518 rulePopulator.populateRouterMacVlanFilters(deviceId);
519 + rulePopulator.populateXConnectVlanFilters(deviceId);
515 rulePopulator.populateRouterIpPunts(deviceId); 520 rulePopulator.populateRouterIpPunts(deviceId);
516 } 521 }
517 522
......
...@@ -20,7 +20,7 @@ import java.util.List; ...@@ -20,7 +20,7 @@ import java.util.List;
20 import static com.google.common.base.Preconditions.checkNotNull; 20 import static com.google.common.base.Preconditions.checkNotNull;
21 21
22 /** 22 /**
23 - * Tunnel class. 23 + * Default Tunnel class.
24 */ 24 */
25 public class DefaultTunnel implements Tunnel { 25 public class DefaultTunnel implements Tunnel {
26 26
......
...@@ -38,6 +38,10 @@ import java.util.Set; ...@@ -38,6 +38,10 @@ import java.util.Set;
38 38
39 import static com.google.common.base.Preconditions.checkNotNull; 39 import static com.google.common.base.Preconditions.checkNotNull;
40 40
41 +/**
42 + * Handler of ICMP packets that responses or forwards ICMP packets that
43 + * are sent to the controller.
44 + */
41 public class IcmpHandler { 45 public class IcmpHandler {
42 46
43 private static Logger log = LoggerFactory.getLogger(IcmpHandler.class); 47 private static Logger log = LoggerFactory.getLogger(IcmpHandler.class);
......
...@@ -37,6 +37,10 @@ import java.util.concurrent.ConcurrentLinkedQueue; ...@@ -37,6 +37,10 @@ import java.util.concurrent.ConcurrentLinkedQueue;
37 37
38 import static com.google.common.base.Preconditions.checkNotNull; 38 import static com.google.common.base.Preconditions.checkNotNull;
39 39
40 +/**
41 + * Handler of IP packets that forwards IP packets that are sent to the controller,
42 + * except the ICMP packets which are processed by @link{IcmpHandler}.
43 + */
40 public class IpHandler { 44 public class IpHandler {
41 45
42 private static Logger log = LoggerFactory.getLogger(IpHandler.class); 46 private static Logger log = LoggerFactory.getLogger(IpHandler.class);
......
...@@ -24,16 +24,24 @@ public interface Policy { ...@@ -24,16 +24,24 @@ public interface Policy {
24 * Enums for policy type. 24 * Enums for policy type.
25 */ 25 */
26 enum Type { 26 enum Type {
27 - // Tunnel flow policy type 27 + /**
28 + * Tunnel flow policy type.
29 + */
28 TUNNEL_FLOW, 30 TUNNEL_FLOW,
29 31
30 - // Load balancing policy type 32 + /**
33 + * Load balancing policy type.
34 + */
31 LOADBALANCE, 35 LOADBALANCE,
32 36
33 - // policy to avoid specific routers or links 37 + /**
38 + * policy to avoid specific routers or links.
39 + */
34 AVOID, 40 AVOID,
35 41
36 - // Access Control policy type 42 + /**
43 + * Access Control policy type.
44 + */
37 DENY 45 DENY
38 } 46 }
39 47
......
...@@ -48,18 +48,43 @@ public class PolicyHandler { ...@@ -48,18 +48,43 @@ public class PolicyHandler {
48 private FlowObjectiveService flowObjectiveService; 48 private FlowObjectiveService flowObjectiveService;
49 private TunnelHandler tunnelHandler; 49 private TunnelHandler tunnelHandler;
50 private final EventuallyConsistentMap<String, Policy> policyStore; 50 private final EventuallyConsistentMap<String, Policy> policyStore;
51 - 51 + /**
52 + * Result of policy creation.
53 + */
52 public enum Result { 54 public enum Result {
55 + /**
56 + * Success.
57 + */
53 SUCCESS, 58 SUCCESS,
59 +
60 + /**
61 + * The same policy exists already.
62 + */
54 POLICY_EXISTS, 63 POLICY_EXISTS,
64 +
65 + /**
66 + * The policy ID exists already.
67 + */
55 ID_EXISTS, 68 ID_EXISTS,
69 +
70 + /**
71 + * Cannot find associated tunnel.
72 + */
56 TUNNEL_NOT_FOUND, 73 TUNNEL_NOT_FOUND,
74 +
75 + /**
76 + * Policy was not found.
77 + */
57 POLICY_NOT_FOUND, 78 POLICY_NOT_FOUND,
79 +
80 + /**
81 + * Policy type {} is not supported yet.
82 + */
58 UNSUPPORTED_TYPE 83 UNSUPPORTED_TYPE
59 } 84 }
60 85
61 /** 86 /**
62 - * Creates a reference. 87 + * Constructs policy handler.
63 * 88 *
64 * @param appId segment routing application ID 89 * @param appId segment routing application ID
65 * @param deviceConfiguration DeviceConfiguration reference 90 * @param deviceConfiguration DeviceConfiguration reference
......
...@@ -23,6 +23,7 @@ import org.onlab.packet.IpPrefix; ...@@ -23,6 +23,7 @@ import org.onlab.packet.IpPrefix;
23 import org.onlab.packet.MacAddress; 23 import org.onlab.packet.MacAddress;
24 import org.onlab.packet.MplsLabel; 24 import org.onlab.packet.MplsLabel;
25 import org.onlab.packet.VlanId; 25 import org.onlab.packet.VlanId;
26 +import org.onosproject.net.ConnectPoint;
26 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; 27 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
27 import org.onosproject.segmentrouting.config.DeviceConfiguration; 28 import org.onosproject.segmentrouting.config.DeviceConfiguration;
28 import org.onosproject.segmentrouting.grouphandler.NeighborSet; 29 import org.onosproject.segmentrouting.grouphandler.NeighborSet;
...@@ -49,11 +50,15 @@ import org.slf4j.LoggerFactory; ...@@ -49,11 +50,15 @@ import org.slf4j.LoggerFactory;
49 import java.util.ArrayList; 50 import java.util.ArrayList;
50 import java.util.HashSet; 51 import java.util.HashSet;
51 import java.util.List; 52 import java.util.List;
53 +import java.util.Map;
52 import java.util.Set; 54 import java.util.Set;
53 import java.util.concurrent.atomic.AtomicLong; 55 import java.util.concurrent.atomic.AtomicLong;
54 56
55 import static com.google.common.base.Preconditions.checkNotNull; 57 import static com.google.common.base.Preconditions.checkNotNull;
56 58
59 +/**
60 + * Populator of segment routing flow rules.
61 + */
57 public class RoutingRulePopulator { 62 public class RoutingRulePopulator {
58 private static final Logger log = LoggerFactory 63 private static final Logger log = LoggerFactory
59 .getLogger(RoutingRulePopulator.class); 64 .getLogger(RoutingRulePopulator.class);
...@@ -63,6 +68,10 @@ public class RoutingRulePopulator { ...@@ -63,6 +68,10 @@ public class RoutingRulePopulator {
63 private DeviceConfiguration config; 68 private DeviceConfiguration config;
64 69
65 private static final int HIGHEST_PRIORITY = 0xffff; 70 private static final int HIGHEST_PRIORITY = 0xffff;
71 + //
72 + private static final int XCONNECT_PRIORITY = 1000;
73 + private static final int DEFAULT_PRIORITY = 100;
74 + private static final int FLOOD_PRIORITY = 5;
66 private static final long OFPP_MAX = 0xffffff00L; 75 private static final long OFPP_MAX = 0xffffff00L;
67 76
68 77
...@@ -120,6 +129,14 @@ public class RoutingRulePopulator { ...@@ -120,6 +129,14 @@ public class RoutingRulePopulator {
120 rulePopulationCounter.incrementAndGet(); 129 rulePopulationCounter.incrementAndGet();
121 } 130 }
122 131
132 + /**
133 + * Removes IP rules for host when the host is gone.
134 + *
135 + * @param deviceId device ID of the device that host attaches to
136 + * @param hostIp IP address of the host
137 + * @param hostMac MAC address of the host
138 + * @param outPort port that host attaches to
139 + */
123 public void revokeIpRuleForHost(DeviceId deviceId, Ip4Address hostIp, 140 public void revokeIpRuleForHost(DeviceId deviceId, Ip4Address hostIp,
124 MacAddress hostMac, PortNumber outPort) { 141 MacAddress hostMac, PortNumber outPort) {
125 log.debug("Revoke IP table entry for host {} at {}:{}", 142 log.debug("Revoke IP table entry for host {} at {}:{}",
...@@ -175,7 +192,7 @@ public class RoutingRulePopulator { ...@@ -175,7 +192,7 @@ public class RoutingRulePopulator {
175 .withSelector(selector) 192 .withSelector(selector)
176 .nextStep(portNextObjId) 193 .nextStep(portNextObjId)
177 .fromApp(srManager.appId).makePermanent() 194 .fromApp(srManager.appId).makePermanent()
178 - .withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC); 195 + .withPriority(DEFAULT_PRIORITY).withFlag(ForwardingObjective.Flag.SPECIFIC);
179 } 196 }
180 197
181 /** 198 /**
...@@ -369,7 +386,7 @@ public class RoutingRulePopulator { ...@@ -369,7 +386,7 @@ public class RoutingRulePopulator {
369 for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) { 386 for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) {
370 ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId) 387 ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId)
371 .makePermanent()).withSelector(selector) 388 .makePermanent()).withSelector(selector)
372 - .withPriority(100)) 389 + .withPriority(DEFAULT_PRIORITY))
373 .withFlag(ForwardingObjective.Flag.SPECIFIC); 390 .withFlag(ForwardingObjective.Flag.SPECIFIC);
374 srManager.flowObjectiveService. 391 srManager.flowObjectiveService.
375 forward(deviceId, 392 forward(deviceId,
...@@ -464,7 +481,8 @@ public class RoutingRulePopulator { ...@@ -464,7 +481,8 @@ public class RoutingRulePopulator {
464 FilteringObjective.Builder fob = DefaultFilteringObjective.builder(); 481 FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
465 fob.withKey(Criteria.matchInPort(port.number())) 482 fob.withKey(Criteria.matchInPort(port.number()))
466 .addCondition(Criteria.matchEthDst(deviceMac)) 483 .addCondition(Criteria.matchEthDst(deviceMac))
467 - .addCondition(Criteria.matchVlanId(VlanId.NONE)); 484 + .addCondition(Criteria.matchVlanId(VlanId.NONE))
485 + .withPriority(DEFAULT_PRIORITY);
468 // vlan assignment is valid only if this instance is master 486 // vlan assignment is valid only if this instance is master
469 if (srManager.mastershipService.isLocalMaster(deviceId)) { 487 if (srManager.mastershipService.isLocalMaster(deviceId)) {
470 TrafficTreatment tt = DefaultTrafficTreatment.builder() 488 TrafficTreatment tt = DefaultTrafficTreatment.builder()
...@@ -558,7 +576,7 @@ public class RoutingRulePopulator { ...@@ -558,7 +576,7 @@ public class RoutingRulePopulator {
558 fob.withFlag(Flag.SPECIFIC) 576 fob.withFlag(Flag.SPECIFIC)
559 .withSelector(sbuilder.build()) 577 .withSelector(sbuilder.build())
560 .nextStep(nextId) 578 .nextStep(nextId)
561 - .withPriority(5) 579 + .withPriority(FLOOD_PRIORITY)
562 .fromApp(srManager.appId) 580 .fromApp(srManager.appId)
563 .makePermanent(); 581 .makePermanent();
564 582
...@@ -572,6 +590,86 @@ public class RoutingRulePopulator { ...@@ -572,6 +590,86 @@ public class RoutingRulePopulator {
572 }); 590 });
573 } 591 }
574 592
593 + /**
594 + * Creates a filtering objective to permit VLAN cross-connect traffic.
595 + *
596 + * @param deviceId the DPID of the switch
597 + */
598 + public void populateXConnectVlanFilters(DeviceId deviceId) {
599 + Map<VlanId, List<ConnectPoint>> xConnectsForDevice =
600 + config.getXConnects();
601 + xConnectsForDevice.forEach((vlanId, connectPoints) -> {
602 + // Only proceed the xConnect for given device
603 + for (ConnectPoint connectPoint : connectPoints) {
604 + if (!connectPoint.deviceId().equals(deviceId)) {
605 + return;
606 + }
607 + }
608 +
609 + connectPoints.forEach(connectPoint -> {
610 + FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
611 + fob.withKey(Criteria.matchInPort(connectPoint.port()))
612 + .addCondition(Criteria.matchVlanId(vlanId))
613 + .addCondition(Criteria.matchEthDst(MacAddress.NONE))
614 + .withPriority(XCONNECT_PRIORITY);
615 +
616 + fob.permit().fromApp(srManager.appId);
617 + srManager.flowObjectiveService
618 + .filter(deviceId, fob.add(new SRObjectiveContext(deviceId,
619 + SRObjectiveContext.ObjectiveType.FILTER)));
620 + });
621 + });
622 + }
623 +
624 + /**
625 + * Populates a forwarding objective that points the VLAN cross-connect
626 + * packets to a broadcast group.
627 + *
628 + * @param deviceId switch ID to set the rules
629 + */
630 + public void populateXConnectBroadcastRule(DeviceId deviceId) {
631 + Map<VlanId, List<ConnectPoint>> xConnects =
632 + config.getXConnects();
633 + xConnects.forEach((vlanId, connectPoints) -> {
634 + // Only proceed the xConnect for given device
635 + for (ConnectPoint connectPoint : connectPoints) {
636 + if (!connectPoint.deviceId().equals(deviceId)) {
637 + return;
638 + }
639 + }
640 +
641 + int nextId = srManager.getXConnectNextObjectiveId(deviceId, vlanId);
642 + if (nextId < 0) {
643 + log.error("Cannot install cross-connect broadcast rule in dev:{} " +
644 + "due to missing nextId:{}", deviceId, nextId);
645 + return;
646 + }
647 +
648 + /*
649 + * Driver should treat objectives with MacAddress.NONE and !VlanId.NONE
650 + * as the VLAN cross-connect broadcast rules
651 + */
652 + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
653 + sbuilder.matchVlanId(vlanId);
654 + sbuilder.matchEthDst(MacAddress.NONE);
655 +
656 + ForwardingObjective.Builder fob = DefaultForwardingObjective.builder();
657 + fob.withFlag(Flag.SPECIFIC)
658 + .withSelector(sbuilder.build())
659 + .nextStep(nextId)
660 + .withPriority(DEFAULT_PRIORITY)
661 + .fromApp(srManager.appId)
662 + .makePermanent();
663 +
664 + srManager.flowObjectiveService.forward(
665 + deviceId,
666 + fob.add(new SRObjectiveContext(
667 + deviceId,
668 + SRObjectiveContext.ObjectiveType.FORWARDING)
669 + )
670 + );
671 + });
672 + }
575 673
576 private static class SRObjectiveContext implements ObjectiveContext { 674 private static class SRObjectiveContext implements ObjectiveContext {
577 enum ObjectiveType { 675 enum ObjectiveType {
......
...@@ -69,7 +69,6 @@ import org.onosproject.net.device.DeviceListener; ...@@ -69,7 +69,6 @@ import org.onosproject.net.device.DeviceListener;
69 import org.onosproject.net.device.DeviceService; 69 import org.onosproject.net.device.DeviceService;
70 import org.onosproject.net.flowobjective.FlowObjectiveService; 70 import org.onosproject.net.flowobjective.FlowObjectiveService;
71 import org.onosproject.net.host.HostService; 71 import org.onosproject.net.host.HostService;
72 -import org.onosproject.net.intent.IntentService;
73 import org.onosproject.net.link.LinkEvent; 72 import org.onosproject.net.link.LinkEvent;
74 import org.onosproject.net.link.LinkListener; 73 import org.onosproject.net.link.LinkListener;
75 import org.onosproject.net.link.LinkService; 74 import org.onosproject.net.link.LinkService;
...@@ -77,8 +76,8 @@ import org.onosproject.net.packet.InboundPacket; ...@@ -77,8 +76,8 @@ import org.onosproject.net.packet.InboundPacket;
77 import org.onosproject.net.packet.PacketContext; 76 import org.onosproject.net.packet.PacketContext;
78 import org.onosproject.net.packet.PacketProcessor; 77 import org.onosproject.net.packet.PacketProcessor;
79 import org.onosproject.net.packet.PacketService; 78 import org.onosproject.net.packet.PacketService;
80 -import org.onosproject.net.topology.TopologyService;
81 import org.onosproject.segmentrouting.grouphandler.SubnetNextObjectiveStoreKey; 79 import org.onosproject.segmentrouting.grouphandler.SubnetNextObjectiveStoreKey;
80 +import org.onosproject.segmentrouting.grouphandler.XConnectNextObjectiveStoreKey;
82 import org.onosproject.store.service.EventuallyConsistentMap; 81 import org.onosproject.store.service.EventuallyConsistentMap;
83 import org.onosproject.store.service.EventuallyConsistentMapBuilder; 82 import org.onosproject.store.service.EventuallyConsistentMapBuilder;
84 import org.onosproject.store.service.StorageService; 83 import org.onosproject.store.service.StorageService;
...@@ -102,6 +101,9 @@ import java.util.concurrent.TimeUnit; ...@@ -102,6 +101,9 @@ import java.util.concurrent.TimeUnit;
102 101
103 @Service 102 @Service
104 @Component(immediate = true) 103 @Component(immediate = true)
104 +/**
105 + * Segment routing manager.
106 + */
105 public class SegmentRoutingManager implements SegmentRoutingService { 107 public class SegmentRoutingManager implements SegmentRoutingService {
106 108
107 private static Logger log = LoggerFactory 109 private static Logger log = LoggerFactory
...@@ -111,15 +113,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -111,15 +113,9 @@ public class SegmentRoutingManager implements SegmentRoutingService {
111 protected CoreService coreService; 113 protected CoreService coreService;
112 114
113 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 115 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
114 - protected TopologyService topologyService;
115 -
116 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
117 protected PacketService packetService; 116 protected PacketService packetService;
118 117
119 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 118 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
120 - protected IntentService intentService;
121 -
122 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
123 protected HostService hostService; 119 protected HostService hostService;
124 120
125 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 121 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
...@@ -157,20 +153,31 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -157,20 +153,31 @@ public class SegmentRoutingManager implements SegmentRoutingService {
157 @SuppressWarnings("rawtypes") 153 @SuppressWarnings("rawtypes")
158 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); 154 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
159 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = 155 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap =
160 - new ConcurrentHashMap<DeviceId, DefaultGroupHandler>(); 156 + new ConcurrentHashMap<>();
161 - // Per device next objective ID store with (device id + neighbor set) as key 157 + /**
162 - private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer> 158 + * Per device next objective ID store with (device id + neighbor set) as key.
159 + */
160 + public EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer>
163 nsNextObjStore = null; 161 nsNextObjStore = null;
164 - // Per device next objective ID store with (device id + subnet) as key 162 + /**
165 - private EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer> 163 + * Per device next objective ID store with (device id + subnet) as key.
164 + */
165 + public EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer>
166 subnetNextObjStore = null; 166 subnetNextObjStore = null;
167 - // Per device next objective ID store with (device id + port) as key 167 + /**
168 - private EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer> 168 + * Per device next objective ID store with (device id + port) as key.
169 + */
170 + public EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer>
169 portNextObjStore = null; 171 portNextObjStore = null;
172 + /**
173 + * Per cross-connect objective ID store with VLAN ID as key.
174 + */
175 + public EventuallyConsistentMap<XConnectNextObjectiveStoreKey, Integer>
176 + xConnectNextObjStore = null;
170 // Per device, per-subnet assigned-vlans store, with (device id + subnet 177 // Per device, per-subnet assigned-vlans store, with (device id + subnet
171 // IPv4 prefix) as key 178 // IPv4 prefix) as key
172 private EventuallyConsistentMap<SubnetAssignedVidStoreKey, VlanId> 179 private EventuallyConsistentMap<SubnetAssignedVidStoreKey, VlanId>
173 - subnetVidStore = null; 180 + subnetVidStore = null;
174 private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; 181 private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
175 private EventuallyConsistentMap<String, Policy> policyStore = null; 182 private EventuallyConsistentMap<String, Policy> policyStore = null;
176 183
...@@ -204,7 +211,13 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -204,7 +211,13 @@ public class SegmentRoutingManager implements SegmentRoutingService {
204 211
205 private KryoNamespace.Builder kryoBuilder = null; 212 private KryoNamespace.Builder kryoBuilder = null;
206 213
214 + /**
215 + * The starting value of per-subnet VLAN ID assignment.
216 + */
207 private static final short ASSIGNED_VLAN_START = 4093; 217 private static final short ASSIGNED_VLAN_START = 4093;
218 + /**
219 + * The default VLAN ID assigned to the interfaces without subnet config.
220 + */
208 public static final short ASSIGNED_VLAN_NO_SUBNET = 4094; 221 public static final short ASSIGNED_VLAN_NO_SUBNET = 4094;
209 222
210 @Activate 223 @Activate
...@@ -262,6 +275,15 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -262,6 +275,15 @@ public class SegmentRoutingManager implements SegmentRoutingService {
262 .withTimestampProvider((k, v) -> new WallClockTimestamp()) 275 .withTimestampProvider((k, v) -> new WallClockTimestamp())
263 .build(); 276 .build();
264 277
278 + log.debug("Creating EC map xconnectnextobjectivestore");
279 + EventuallyConsistentMapBuilder<XConnectNextObjectiveStoreKey, Integer>
280 + xConnectNextObjStoreBuilder = storageService.eventuallyConsistentMapBuilder();
281 + xConnectNextObjStore = xConnectNextObjStoreBuilder
282 + .withName("xconnectnextobjectivestore")
283 + .withSerializer(kryoBuilder)
284 + .withTimestampProvider((k, v) -> new WallClockTimestamp())
285 + .build();
286 +
265 EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder = 287 EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
266 storageService.eventuallyConsistentMapBuilder(); 288 storageService.eventuallyConsistentMapBuilder();
267 tunnelStore = tunnelMapBuilder 289 tunnelStore = tunnelMapBuilder
...@@ -394,9 +416,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -394,9 +416,6 @@ public class SegmentRoutingManager implements SegmentRoutingService {
394 * Vlan id 4094 expected to be used for all ports that are not assigned subnets. 416 * Vlan id 4094 expected to be used for all ports that are not assigned subnets.
395 * Vlan id 4095 is reserved and unused. Only a single vlan id is assigned 417 * Vlan id 4095 is reserved and unused. Only a single vlan id is assigned
396 * per subnet. 418 * per subnet.
397 - * XXX This method should avoid any vlans configured on the ports, but
398 - * currently the app works only on untagged packets and as a result
399 - * ignores any vlan configuration.
400 * 419 *
401 * @param deviceId switch dpid 420 * @param deviceId switch dpid
402 * @param subnet IPv4 prefix for which assigned vlan is desired 421 * @param subnet IPv4 prefix for which assigned vlan is desired
...@@ -404,6 +423,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -404,6 +423,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
404 * null if no vlan assignment was found and this instance is not 423 * null if no vlan assignment was found and this instance is not
405 * the master for the device. 424 * the master for the device.
406 */ 425 */
426 + // TODO: We should avoid assigning VLAN IDs that are used by VLAN cross-connection.
407 public VlanId getSubnetAssignedVlanId(DeviceId deviceId, Ip4Prefix subnet) { 427 public VlanId getSubnetAssignedVlanId(DeviceId deviceId, Ip4Prefix subnet) {
408 VlanId assignedVid = subnetVidStore.get(new SubnetAssignedVidStoreKey( 428 VlanId assignedVid = subnetVidStore.get(new SubnetAssignedVidStoreKey(
409 deviceId, subnet)); 429 deviceId, subnet));
...@@ -508,7 +528,26 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -508,7 +528,26 @@ public class SegmentRoutingManager implements SegmentRoutingService {
508 if (ghdlr != null) { 528 if (ghdlr != null) {
509 return ghdlr.getPortNextObjectiveId(portNum, treatment, meta); 529 return ghdlr.getPortNextObjectiveId(portNum, treatment, meta);
510 } else { 530 } else {
511 - log.warn("getPortNextObjectiveId query - groupHandler for device {}" 531 + log.warn("getPortNextObjectiveId query - groupHandler for device {}"
532 + + " not found", deviceId);
533 + return -1;
534 + }
535 + }
536 +
537 + /**
538 + * Returns the next objective ID of type broadcast associated with the VLAN
539 + * cross-connection.
540 + *
541 + * @param deviceId Device ID for the cross-connection
542 + * @param vlanId VLAN ID for the cross-connection
543 + * @return next objective ID or -1 if it was not found
544 + */
545 + public int getXConnectNextObjectiveId(DeviceId deviceId, VlanId vlanId) {
546 + DefaultGroupHandler ghdlr = groupHandlerMap.get(deviceId);
547 + if (ghdlr != null) {
548 + return ghdlr.getXConnectNextObjectiveId(vlanId);
549 + } else {
550 + log.warn("getPortNextObjectiveId query - groupHandler for device {}"
512 + " not found", deviceId); 551 + " not found", deviceId);
513 return -1; 552 return -1;
514 } 553 }
...@@ -707,9 +746,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -707,9 +746,6 @@ public class SegmentRoutingManager implements SegmentRoutingService {
707 deviceConfiguration, 746 deviceConfiguration,
708 linkService, 747 linkService,
709 flowObjectiveService, 748 flowObjectiveService,
710 - nsNextObjStore,
711 - subnetNextObjStore,
712 - portNextObjStore,
713 this); 749 this);
714 } catch (DeviceConfigNotFoundException e) { 750 } catch (DeviceConfigNotFoundException e) {
715 log.warn(e.getMessage() + " Aborting processDeviceAdded."); 751 log.warn(e.getMessage() + " Aborting processDeviceAdded.");
...@@ -727,6 +763,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -727,6 +763,8 @@ public class SegmentRoutingManager implements SegmentRoutingService {
727 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); 763 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
728 groupHandler.createGroupsFromSubnetConfig(); 764 groupHandler.createGroupsFromSubnetConfig();
729 routingRulePopulator.populateSubnetBroadcastRule(device.id()); 765 routingRulePopulator.populateSubnetBroadcastRule(device.id());
766 + groupHandler.createGroupsForXConnect(device.id());
767 + routingRulePopulator.populateXConnectBroadcastRule(device.id());
730 } 768 }
731 } 769 }
732 770
...@@ -742,10 +780,18 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -742,10 +780,18 @@ public class SegmentRoutingManager implements SegmentRoutingService {
742 private class InternalConfigListener implements NetworkConfigListener { 780 private class InternalConfigListener implements NetworkConfigListener {
743 SegmentRoutingManager segmentRoutingManager; 781 SegmentRoutingManager segmentRoutingManager;
744 782
783 + /**
784 + * Constructs the internal network config listener.
785 + *
786 + * @param srMgr segment routing manager
787 + */
745 public InternalConfigListener(SegmentRoutingManager srMgr) { 788 public InternalConfigListener(SegmentRoutingManager srMgr) {
746 this.segmentRoutingManager = srMgr; 789 this.segmentRoutingManager = srMgr;
747 } 790 }
748 791
792 + /**
793 + * Reads network config and initializes related data structure accordingly.
794 + */
749 public void configureNetwork() { 795 public void configureNetwork() {
750 deviceConfiguration = new DeviceConfiguration(segmentRoutingManager.cfgService); 796 deviceConfiguration = new DeviceConfiguration(segmentRoutingManager.cfgService);
751 797
...@@ -777,9 +823,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -777,9 +823,6 @@ public class SegmentRoutingManager implements SegmentRoutingService {
777 deviceConfiguration, 823 deviceConfiguration,
778 linkService, 824 linkService,
779 flowObjectiveService, 825 flowObjectiveService,
780 - nsNextObjStore,
781 - subnetNextObjStore,
782 - portNextObjStore,
783 segmentRoutingManager); 826 segmentRoutingManager);
784 } catch (DeviceConfigNotFoundException e) { 827 } catch (DeviceConfigNotFoundException e) {
785 log.warn(e.getMessage() + " Aborting configureNetwork."); 828 log.warn(e.getMessage() + " Aborting configureNetwork.");
...@@ -798,6 +841,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -798,6 +841,8 @@ public class SegmentRoutingManager implements SegmentRoutingService {
798 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); 841 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
799 groupHandler.createGroupsFromSubnetConfig(); 842 groupHandler.createGroupsFromSubnetConfig();
800 routingRulePopulator.populateSubnetBroadcastRule(device.id()); 843 routingRulePopulator.populateSubnetBroadcastRule(device.id());
844 + groupHandler.createGroupsForXConnect(device.id());
845 + routingRulePopulator.populateXConnectBroadcastRule(device.id());
801 } 846 }
802 } 847 }
803 848
......
...@@ -6,13 +6,18 @@ import org.onlab.packet.Ip4Prefix; ...@@ -6,13 +6,18 @@ import org.onlab.packet.Ip4Prefix;
6 import org.onosproject.net.DeviceId; 6 import org.onosproject.net.DeviceId;
7 7
8 /** 8 /**
9 - * Class definition for key used to map per device subnets to assigned Vlan ids. 9 + * Key of assigned VLAN ID store.
10 - *
11 */ 10 */
12 public class SubnetAssignedVidStoreKey { 11 public class SubnetAssignedVidStoreKey {
13 private final DeviceId deviceId; 12 private final DeviceId deviceId;
14 private final Ip4Prefix subnet; 13 private final Ip4Prefix subnet;
15 14
15 + /**
16 + * Constructs the key of per subnet VLAN ID store.
17 + *
18 + * @param deviceId device ID of the VLAN cross-connection
19 + * @param subnet subnet information
20 + */
16 public SubnetAssignedVidStoreKey(DeviceId deviceId, Ip4Prefix subnet) { 21 public SubnetAssignedVidStoreKey(DeviceId deviceId, Ip4Prefix subnet) {
17 this.deviceId = deviceId; 22 this.deviceId = deviceId;
18 this.subnet = subnet; 23 this.subnet = subnet;
......
...@@ -43,16 +43,54 @@ public class TunnelHandler { ...@@ -43,16 +43,54 @@ public class TunnelHandler {
43 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap; 43 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap;
44 private LinkService linkService; 44 private LinkService linkService;
45 45
46 + /**
47 + * Result of tunnel creation or removal.
48 + */
46 public enum Result { 49 public enum Result {
50 + /**
51 + * Success.
52 + */
47 SUCCESS, 53 SUCCESS,
54 +
55 + /**
56 + * More than one router needs to specified to created a tunnel.
57 + */
48 WRONG_PATH, 58 WRONG_PATH,
59 +
60 + /**
61 + * The same tunnel exists already.
62 + */
49 TUNNEL_EXISTS, 63 TUNNEL_EXISTS,
64 +
65 + /**
66 + * The same tunnel ID exists already.
67 + */
50 ID_EXISTS, 68 ID_EXISTS,
69 +
70 + /**
71 + * Tunnel not found.
72 + */
51 TUNNEL_NOT_FOUND, 73 TUNNEL_NOT_FOUND,
74 +
75 + /**
76 + * Cannot remove the tunnel used by a policy.
77 + */
52 TUNNEL_IN_USE, 78 TUNNEL_IN_USE,
79 +
80 + /**
81 + * Failed to create/remove groups for the tunnel.
82 + */
53 INTERNAL_ERROR 83 INTERNAL_ERROR
54 } 84 }
55 85
86 + /**
87 + * Constructs tunnel handler.
88 + *
89 + * @param linkService link service
90 + * @param deviceConfiguration device configuration
91 + * @param groupHandlerMap group handler map
92 + * @param tunnelStore tunnel store
93 + */
56 public TunnelHandler(LinkService linkService, 94 public TunnelHandler(LinkService linkService,
57 DeviceConfiguration deviceConfiguration, 95 DeviceConfiguration deviceConfiguration,
58 Map<DeviceId, DefaultGroupHandler> groupHandlerMap, 96 Map<DeviceId, DefaultGroupHandler> groupHandlerMap,
......
...@@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableSet; ...@@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableSet;
19 import org.onlab.packet.Ip4Address; 19 import org.onlab.packet.Ip4Address;
20 import org.onlab.packet.Ip4Prefix; 20 import org.onlab.packet.Ip4Prefix;
21 import org.onlab.packet.MacAddress; 21 import org.onlab.packet.MacAddress;
22 +import org.onlab.packet.VlanId;
22 import org.onosproject.incubator.net.config.basics.ConfigException; 23 import org.onosproject.incubator.net.config.basics.ConfigException;
23 import org.onosproject.incubator.net.config.basics.InterfaceConfig; 24 import org.onosproject.incubator.net.config.basics.InterfaceConfig;
24 import org.onosproject.incubator.net.intf.Interface; 25 import org.onosproject.incubator.net.intf.Interface;
...@@ -33,6 +34,7 @@ import org.slf4j.LoggerFactory; ...@@ -33,6 +34,7 @@ import org.slf4j.LoggerFactory;
33 import java.util.ArrayList; 34 import java.util.ArrayList;
34 import java.util.HashMap; 35 import java.util.HashMap;
35 import java.util.HashSet; 36 import java.util.HashSet;
37 +import java.util.LinkedList;
36 import java.util.List; 38 import java.util.List;
37 import java.util.Map; 39 import java.util.Map;
38 import java.util.Set; 40 import java.util.Set;
...@@ -48,8 +50,8 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -48,8 +50,8 @@ public class DeviceConfiguration implements DeviceProperties {
48 private static final Logger log = LoggerFactory 50 private static final Logger log = LoggerFactory
49 .getLogger(DeviceConfiguration.class); 51 .getLogger(DeviceConfiguration.class);
50 private final List<Integer> allSegmentIds = new ArrayList<>(); 52 private final List<Integer> allSegmentIds = new ArrayList<>();
51 - private final ConcurrentHashMap<DeviceId, SegmentRouterInfo> deviceConfigMap 53 + private final Map<DeviceId, SegmentRouterInfo> deviceConfigMap = new ConcurrentHashMap<>();
52 - = new ConcurrentHashMap<>(); 54 + private final Map<VlanId, List<ConnectPoint>> xConnects = new ConcurrentHashMap<>();
53 55
54 private class SegmentRouterInfo { 56 private class SegmentRouterInfo {
55 int nodeSid; 57 int nodeSid;
...@@ -62,14 +64,14 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -62,14 +64,14 @@ public class DeviceConfiguration implements DeviceProperties {
62 Map<Integer, Set<Integer>> adjacencySids; 64 Map<Integer, Set<Integer>> adjacencySids;
63 65
64 public SegmentRouterInfo() { 66 public SegmentRouterInfo() {
65 - this.gatewayIps = new HashMap<>(); 67 + gatewayIps = new HashMap<>();
66 - this.subnets = new HashMap<>(); 68 + subnets = new HashMap<>();
67 } 69 }
68 } 70 }
69 71
70 /** 72 /**
71 - * Constructor. Reads all the configuration for all devices of type 73 + * Constructs device configuration for all Segment Router devices,
72 - * Segment Router and organizes into various maps for easier access. 74 + * organizing the data into various maps for easier access.
73 * 75 *
74 * @param cfgService config service 76 * @param cfgService config service
75 */ 77 */
...@@ -88,8 +90,8 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -88,8 +90,8 @@ public class DeviceConfiguration implements DeviceProperties {
88 info.isEdge = config.isEdgeRouter(); 90 info.isEdge = config.isEdgeRouter();
89 info.adjacencySids = config.adjacencySids(); 91 info.adjacencySids = config.adjacencySids();
90 92
91 - this.deviceConfigMap.put(info.deviceId, info); 93 + deviceConfigMap.put(info.deviceId, info);
92 - this.allSegmentIds.add(info.nodeSid); 94 + allSegmentIds.add(info.nodeSid);
93 }); 95 });
94 96
95 // Read gatewayIps and subnets from port subject. 97 // Read gatewayIps and subnets from port subject.
...@@ -106,17 +108,42 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -106,17 +108,42 @@ public class DeviceConfiguration implements DeviceProperties {
106 return; 108 return;
107 } 109 }
108 networkInterfaces.forEach(networkInterface -> { 110 networkInterfaces.forEach(networkInterface -> {
109 - DeviceId dpid = networkInterface.connectPoint().deviceId(); 111 + VlanId vlanId = networkInterface.vlan();
110 - PortNumber port = networkInterface.connectPoint().port(); 112 + ConnectPoint connectPoint = networkInterface.connectPoint();
111 - SegmentRouterInfo info = this.deviceConfigMap.get(dpid); 113 + DeviceId dpid = connectPoint.deviceId();
114 + PortNumber port = connectPoint.port();
115 + SegmentRouterInfo info = deviceConfigMap.get(dpid);
112 116
113 // skip if there is no corresponding device for this ConenctPoint 117 // skip if there is no corresponding device for this ConenctPoint
114 if (info != null) { 118 if (info != null) {
119 + // Extract subnet information
115 Set<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddresses(); 120 Set<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddresses();
116 interfaceAddresses.forEach(interfaceAddress -> { 121 interfaceAddresses.forEach(interfaceAddress -> {
117 info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address()); 122 info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address());
118 info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix()); 123 info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix());
119 }); 124 });
125 +
126 + // Extract VLAN cross-connect information
127 + // Do not setup cross-connect if VLAN is NONE
128 + if (vlanId.equals(VlanId.NONE)) {
129 + return;
130 + }
131 + List<ConnectPoint> connectPoints = xConnects.get(vlanId);
132 + if (connectPoints != null) {
133 + if (connectPoints.size() != 1) {
134 + log.warn("Cross-connect should only have two endpoints. Aborting.");
135 + return;
136 + }
137 + if (!connectPoints.get(0).deviceId().equals(connectPoint.deviceId())) {
138 + log.warn("Cross-connect endpoints must be on the same switch. Aborting.");
139 + return;
140 + }
141 + connectPoints.add(connectPoint);
142 + } else {
143 + connectPoints = new LinkedList<>();
144 + connectPoints.add(connectPoint);
145 + xConnects.put(vlanId, connectPoints);
146 + }
120 } 147 }
121 }); 148 });
122 149
...@@ -235,6 +262,11 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -235,6 +262,11 @@ public class DeviceConfiguration implements DeviceProperties {
235 return subnetPortMap; 262 return subnetPortMap;
236 } 263 }
237 264
265 + @Override
266 + public Map<VlanId, List<ConnectPoint>> getXConnects() {
267 + return xConnects;
268 + }
269 +
238 /** 270 /**
239 * Returns the device identifier or data plane identifier (dpid) 271 * Returns the device identifier or data plane identifier (dpid)
240 * of a segment router given its segment id. 272 * of a segment router given its segment id.
......
...@@ -21,6 +21,8 @@ import java.util.Map; ...@@ -21,6 +21,8 @@ import java.util.Map;
21 import org.onlab.packet.Ip4Address; 21 import org.onlab.packet.Ip4Address;
22 import org.onlab.packet.Ip4Prefix; 22 import org.onlab.packet.Ip4Prefix;
23 import org.onlab.packet.MacAddress; 23 import org.onlab.packet.MacAddress;
24 +import org.onlab.packet.VlanId;
25 +import org.onosproject.net.ConnectPoint;
24 import org.onosproject.net.DeviceId; 26 import org.onosproject.net.DeviceId;
25 import org.onosproject.net.PortNumber; 27 import org.onosproject.net.PortNumber;
26 28
...@@ -93,4 +95,11 @@ public interface DeviceProperties { ...@@ -93,4 +95,11 @@ public interface DeviceProperties {
93 * @return a map that contains all subnet-to-ports mapping of given device 95 * @return a map that contains all subnet-to-ports mapping of given device
94 */ 96 */
95 Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId); 97 Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId);
98 +
99 + /**
100 + * Returns the VLAN cross-connect configuration.
101 + *
102 + * @return A map of that maps VLAN ID to a list of cross-connect endpoints
103 + */
104 + Map<VlanId, List<ConnectPoint>> getXConnects();
96 } 105 }
......
...@@ -35,24 +35,24 @@ import java.util.Set; ...@@ -35,24 +35,24 @@ import java.util.Set;
35 * Configuration object for Segment Routing Application. 35 * Configuration object for Segment Routing Application.
36 */ 36 */
37 public class SegmentRoutingConfig extends Config<DeviceId> { 37 public class SegmentRoutingConfig extends Config<DeviceId> {
38 - public static final String NAME = "name"; 38 + private static final String NAME = "name";
39 - public static final String IP = "routerIp"; 39 + private static final String IP = "routerIp";
40 - public static final String MAC = "routerMac"; 40 + private static final String MAC = "routerMac";
41 - public static final String SID = "nodeSid"; 41 + private static final String SID = "nodeSid";
42 - public static final String EDGE = "isEdgeRouter"; 42 + private static final String EDGE = "isEdgeRouter";
43 - public static final String ADJSIDS = "adjacencySids"; 43 + private static final String ADJSIDS = "adjacencySids";
44 - public static final String ADJSID = "adjSid"; 44 + private static final String ADJSID = "adjSid";
45 - public static final String PORTS = "ports"; 45 + private static final String PORTS = "ports";
46 46
47 @Override 47 @Override
48 public boolean isValid() { 48 public boolean isValid() {
49 return hasOnlyFields(NAME, IP, MAC, SID, EDGE, ADJSIDS, ADJSID, PORTS) && 49 return hasOnlyFields(NAME, IP, MAC, SID, EDGE, ADJSIDS, ADJSID, PORTS) &&
50 - this.name() != null && 50 + name() != null &&
51 - this.routerIp() != null && 51 + routerIp() != null &&
52 - this.routerMac() != null && 52 + routerMac() != null &&
53 - this.nodeSid() != -1 && 53 + nodeSid() != -1 &&
54 - this.isEdgeRouter() != null && 54 + isEdgeRouter() != null &&
55 - this.adjacencySids() != null; 55 + adjacencySids() != null;
56 } 56 }
57 57
58 /** 58 /**
......
...@@ -26,7 +26,6 @@ import org.onosproject.net.flowobjective.FlowObjectiveService; ...@@ -26,7 +26,6 @@ import org.onosproject.net.flowobjective.FlowObjectiveService;
26 import org.onosproject.net.link.LinkService; 26 import org.onosproject.net.link.LinkService;
27 import org.onosproject.segmentrouting.SegmentRoutingManager; 27 import org.onosproject.segmentrouting.SegmentRoutingManager;
28 import org.onosproject.segmentrouting.config.DeviceProperties; 28 import org.onosproject.segmentrouting.config.DeviceProperties;
29 -import org.onosproject.store.service.EventuallyConsistentMap;
30 29
31 /** 30 /**
32 * Default ECMP group handler creation module for an edge device. 31 * Default ECMP group handler creation module for an edge device.
...@@ -47,22 +46,13 @@ import org.onosproject.store.service.EventuallyConsistentMap; ...@@ -47,22 +46,13 @@ import org.onosproject.store.service.EventuallyConsistentMap;
47 * 8) what about ecmp no label case 46 * 8) what about ecmp no label case
48 */ 47 */
49 public class DefaultEdgeGroupHandler extends DefaultGroupHandler { 48 public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
50 - // TODO Access stores through srManager
51 protected DefaultEdgeGroupHandler(DeviceId deviceId, 49 protected DefaultEdgeGroupHandler(DeviceId deviceId,
52 ApplicationId appId, 50 ApplicationId appId,
53 DeviceProperties config, 51 DeviceProperties config,
54 LinkService linkService, 52 LinkService linkService,
55 FlowObjectiveService flowObjService, 53 FlowObjectiveService flowObjService,
56 - EventuallyConsistentMap<
57 - NeighborSetNextObjectiveStoreKey,
58 - Integer> nsNextObjStore,
59 - EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
60 - Integer> subnetNextObjStore,
61 - EventuallyConsistentMap<PortNextObjectiveStoreKey,
62 - Integer> portNextObjStore,
63 SegmentRoutingManager srManager) { 54 SegmentRoutingManager srManager) {
64 - super(deviceId, appId, config, linkService, flowObjService, 55 + super(deviceId, appId, config, linkService, flowObjService, srManager);
65 - nsNextObjStore, subnetNextObjStore, portNextObjStore, srManager);
66 } 56 }
67 57
68 @Override 58 @Override
......
...@@ -26,7 +26,6 @@ import org.onosproject.net.link.LinkService; ...@@ -26,7 +26,6 @@ import org.onosproject.net.link.LinkService;
26 import org.onosproject.segmentrouting.SegmentRoutingManager; 26 import org.onosproject.segmentrouting.SegmentRoutingManager;
27 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; 27 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
28 import org.onosproject.segmentrouting.config.DeviceProperties; 28 import org.onosproject.segmentrouting.config.DeviceProperties;
29 -import org.onosproject.store.service.EventuallyConsistentMap;
30 29
31 /** 30 /**
32 * Default ECMP group handler creation module for a transit device. 31 * Default ECMP group handler creation module for a transit device.
...@@ -41,22 +40,13 @@ import org.onosproject.store.service.EventuallyConsistentMap; ...@@ -41,22 +40,13 @@ import org.onosproject.store.service.EventuallyConsistentMap;
41 * 2) all ports to D3 + with no label push, 40 * 2) all ports to D3 + with no label push,
42 */ 41 */
43 public class DefaultTransitGroupHandler extends DefaultGroupHandler { 42 public class DefaultTransitGroupHandler extends DefaultGroupHandler {
44 - // TODO Access stores through srManager
45 protected DefaultTransitGroupHandler(DeviceId deviceId, 43 protected DefaultTransitGroupHandler(DeviceId deviceId,
46 ApplicationId appId, 44 ApplicationId appId,
47 DeviceProperties config, 45 DeviceProperties config,
48 LinkService linkService, 46 LinkService linkService,
49 FlowObjectiveService flowObjService, 47 FlowObjectiveService flowObjService,
50 - EventuallyConsistentMap<
51 - NeighborSetNextObjectiveStoreKey,
52 - Integer> nsNextObjStore,
53 - EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
54 - Integer> subnetNextObjStore,
55 - EventuallyConsistentMap<PortNextObjectiveStoreKey,
56 - Integer> portNextObjStore,
57 SegmentRoutingManager srManager) { 48 SegmentRoutingManager srManager) {
58 - super(deviceId, appId, config, linkService, flowObjService, 49 + super(deviceId, appId, config, linkService, flowObjService, srManager);
59 - nsNextObjStore, subnetNextObjStore, portNextObjStore, srManager);
60 } 50 }
61 51
62 @Override 52 @Override
......
...@@ -21,22 +21,38 @@ import java.util.Objects; ...@@ -21,22 +21,38 @@ import java.util.Objects;
21 import org.onosproject.net.DeviceId; 21 import org.onosproject.net.DeviceId;
22 22
23 /** 23 /**
24 - * Class definition of Key for Neighborset to NextObjective store. 24 + * Key of Neighborset next objective store.
25 */ 25 */
26 public class NeighborSetNextObjectiveStoreKey { 26 public class NeighborSetNextObjectiveStoreKey {
27 private final DeviceId deviceId; 27 private final DeviceId deviceId;
28 private final NeighborSet ns; 28 private final NeighborSet ns;
29 29
30 + /**
31 + * Constructs the key of neighbor set next objective store.
32 + *
33 + * @param deviceId device ID
34 + * @param ns neighbor set
35 + */
30 public NeighborSetNextObjectiveStoreKey(DeviceId deviceId, 36 public NeighborSetNextObjectiveStoreKey(DeviceId deviceId,
31 NeighborSet ns) { 37 NeighborSet ns) {
32 this.deviceId = deviceId; 38 this.deviceId = deviceId;
33 this.ns = ns; 39 this.ns = ns;
34 } 40 }
35 41
42 + /**
43 + * Returns the device ID in the key.
44 + *
45 + * @return device ID
46 + */
36 public DeviceId deviceId() { 47 public DeviceId deviceId() {
37 return this.deviceId; 48 return this.deviceId;
38 } 49 }
39 50
51 + /**
52 + * Returns the neighbor set in the key.
53 + *
54 + * @return neighbor set
55 + */
40 public NeighborSet neighborSet() { 56 public NeighborSet neighborSet() {
41 return this.ns; 57 return this.ns;
42 } 58 }
......
...@@ -31,7 +31,6 @@ import org.onosproject.segmentrouting.SegmentRoutingManager; ...@@ -31,7 +31,6 @@ import org.onosproject.segmentrouting.SegmentRoutingManager;
31 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; 31 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
32 import org.onosproject.segmentrouting.config.DeviceProperties; 32 import org.onosproject.segmentrouting.config.DeviceProperties;
33 import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; 33 import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType;
34 -import org.onosproject.store.service.EventuallyConsistentMap;
35 import org.onosproject.net.DeviceId; 34 import org.onosproject.net.DeviceId;
36 import org.onosproject.net.PortNumber; 35 import org.onosproject.net.PortNumber;
37 import org.onosproject.net.flow.DefaultTrafficTreatment; 36 import org.onosproject.net.flow.DefaultTrafficTreatment;
...@@ -51,33 +50,31 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -51,33 +50,31 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
51 private HashMap<PolicyGroupIdentifier, PolicyGroupIdentifier> dependentGroups = new HashMap<>(); 50 private HashMap<PolicyGroupIdentifier, PolicyGroupIdentifier> dependentGroups = new HashMap<>();
52 51
53 /** 52 /**
54 - * Policy group handler constructor. 53 + * Constructs policy group handler.
55 * 54 *
56 * @param deviceId device identifier 55 * @param deviceId device identifier
57 * @param appId application identifier 56 * @param appId application identifier
58 * @param config interface to retrieve the device properties 57 * @param config interface to retrieve the device properties
59 * @param linkService link service object 58 * @param linkService link service object
60 * @param flowObjService flow objective service object 59 * @param flowObjService flow objective service object
61 - * @param nsNextObjStore NeighborSet next objective store map 60 + * @param srManager segment routing manager
62 - * @param subnetNextObjStore subnet next objective store map
63 */ 61 */
64 - // TODO Access stores through srManager
65 public PolicyGroupHandler(DeviceId deviceId, 62 public PolicyGroupHandler(DeviceId deviceId,
66 ApplicationId appId, 63 ApplicationId appId,
67 DeviceProperties config, 64 DeviceProperties config,
68 LinkService linkService, 65 LinkService linkService,
69 FlowObjectiveService flowObjService, 66 FlowObjectiveService flowObjService,
70 - EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
71 - Integer> nsNextObjStore,
72 - EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
73 - Integer> subnetNextObjStore,
74 - EventuallyConsistentMap<PortNextObjectiveStoreKey,
75 - Integer> portNextObjStore,
76 SegmentRoutingManager srManager) { 67 SegmentRoutingManager srManager) {
77 - super(deviceId, appId, config, linkService, flowObjService, 68 + super(deviceId, appId, config, linkService, flowObjService, srManager);
78 - nsNextObjStore, subnetNextObjStore, portNextObjStore, srManager);
79 } 69 }
80 70
71 + /**
72 + * Creates policy group chain.
73 + *
74 + * @param id unique identifier associated with the policy group
75 + * @param params a list of policy group params
76 + * @return policy group identifier
77 + */
81 public PolicyGroupIdentifier createPolicyGroupChain(String id, 78 public PolicyGroupIdentifier createPolicyGroupChain(String id,
82 List<PolicyGroupParams> params) { 79 List<PolicyGroupParams> params) {
83 List<GroupBucketIdentifier> bucketIds = new ArrayList<>(); 80 List<GroupBucketIdentifier> bucketIds = new ArrayList<>();
...@@ -222,69 +219,18 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -222,69 +219,18 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
222 } 219 }
223 220
224 //TODO: Use nextObjective APIs to handle the group chains 221 //TODO: Use nextObjective APIs to handle the group chains
225 - /*@Override 222 + /*
226 - protected void handleGroupEvent(GroupEvent event) { 223 + @Override
227 - if (event.type() == GroupEvent.Type.GROUP_ADDED) { 224 + protected void handleGroupEvent(GroupEvent event) {}
228 - if (dependentGroups.get(event.subject().appCookie()) != null) { 225 + */
229 - PolicyGroupIdentifier dependentGroupKey = dependentGroups.get(event.subject().appCookie());
230 - dependentGroups.remove(event.subject().appCookie());
231 - boolean fullyResolved = true;
232 - for (GroupBucketIdentifier bucketId:
233 - dependentGroupKey.bucketIds()) {
234 - if (bucketId.type() != BucketOutputType.GROUP) {
235 - continue;
236 - }
237 - if (dependentGroups.containsKey(bucketId.outGroup())) {
238 - fullyResolved = false;
239 - break;
240 - }
241 - }
242 -
243 - if (fullyResolved) {
244 - List<GroupBucket> outBuckets = new ArrayList<GroupBucket>();
245 - for (GroupBucketIdentifier bucketId:
246 - dependentGroupKey.bucketIds()) {
247 - TrafficTreatment.Builder tBuilder =
248 - DefaultTrafficTreatment.builder();
249 - if (bucketId.label() != NeighborSet.NO_EDGE_LABEL) {
250 - tBuilder.pushMpls()
251 - .setMpls(MplsLabel.
252 - mplsLabel(bucketId.label()));
253 - }
254 - //TODO: BoS
255 - if (bucketId.type() == BucketOutputType.PORT) {
256 - DeviceId neighbor = portDeviceMap.
257 - get(bucketId.outPort());
258 - tBuilder.setOutput(bucketId.outPort())
259 - .setEthDst(deviceConfig.
260 - getDeviceMac(neighbor))
261 - .setEthSrc(nodeMacAddr);
262 - } else {
263 - if (groupService.
264 - getGroup(deviceId,
265 - getGroupKey(bucketId.
266 - outGroup())) == null) {
267 - throw new IllegalStateException();
268 - }
269 - GroupId indirectGroupId = groupService.
270 - getGroup(deviceId,
271 - getGroupKey(bucketId.
272 - outGroup())).id();
273 - tBuilder.group(indirectGroupId);
274 - }
275 - outBuckets.add(DefaultGroupBucket.
276 - createSelectGroupBucket(tBuilder.build()));
277 - }
278 - GroupDescription desc = new
279 - DefaultGroupDescription(deviceId,
280 - GroupDescription.Type.SELECT,
281 - new GroupBuckets(outBuckets));
282 - groupService.addGroup(desc);
283 - }
284 - }
285 - }
286 - }*/
287 226
227 + /**
228 + * Generates policy group key.
229 + *
230 + * @param id unique identifier associated with the policy group
231 + * @param params a list of policy group params
232 + * @return policy group identifier
233 + */
288 public PolicyGroupIdentifier generatePolicyGroupKey(String id, 234 public PolicyGroupIdentifier generatePolicyGroupKey(String id,
289 List<PolicyGroupParams> params) { 235 List<PolicyGroupParams> params) {
290 List<GroupBucketIdentifier> bucketIds = new ArrayList<>(); 236 List<GroupBucketIdentifier> bucketIds = new ArrayList<>();
...@@ -354,6 +300,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -354,6 +300,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
354 return innermostGroupkey; 300 return innermostGroupkey;
355 } 301 }
356 302
303 + /**
304 + * Removes policy group chain.
305 + *
306 + * @param key policy group identifier
307 + */
357 public void removeGroupChain(PolicyGroupIdentifier key) { 308 public void removeGroupChain(PolicyGroupIdentifier key) {
358 checkArgument(key != null); 309 checkArgument(key != null);
359 List<PolicyGroupIdentifier> groupsToBeDeleted = new ArrayList<>(); 310 List<PolicyGroupIdentifier> groupsToBeDeleted = new ArrayList<>();
......
...@@ -28,7 +28,7 @@ public class PolicyGroupIdentifier { ...@@ -28,7 +28,7 @@ public class PolicyGroupIdentifier {
28 private List<GroupBucketIdentifier> bucketIds; 28 private List<GroupBucketIdentifier> bucketIds;
29 29
30 /** 30 /**
31 - * Constructor. 31 + * Constructs policy group identifier.
32 * 32 *
33 * @param id unique identifier associated with the policy group 33 * @param id unique identifier associated with the policy group
34 * @param input policy group params associated with this group 34 * @param input policy group params associated with this group
......
...@@ -7,15 +7,23 @@ import org.onosproject.net.flow.TrafficTreatment; ...@@ -7,15 +7,23 @@ import org.onosproject.net.flow.TrafficTreatment;
7 import java.util.Objects; 7 import java.util.Objects;
8 8
9 /** 9 /**
10 - * Class definition of Key for Device/Port to NextObjective store. Since there 10 + * Key of Device/Port to NextObjective store.
11 - * can be multiple next objectives to the same physical port, we differentiate 11 + *
12 - * between them by including the treatment in the key. 12 + * Since there can be multiple next objectives to the same physical port,
13 + * we differentiate between them by including the treatment in the key.
13 */ 14 */
14 public class PortNextObjectiveStoreKey { 15 public class PortNextObjectiveStoreKey {
15 private final DeviceId deviceId; 16 private final DeviceId deviceId;
16 private final PortNumber portNum; 17 private final PortNumber portNum;
17 private final TrafficTreatment treatment; 18 private final TrafficTreatment treatment;
18 19
20 + /**
21 + * Constructs the key of port next objective store.
22 + *
23 + * @param deviceId device ID
24 + * @param portNum port number
25 + * @param treatment treatment that will be applied to the interface
26 + */
19 public PortNextObjectiveStoreKey(DeviceId deviceId, PortNumber portNum, 27 public PortNextObjectiveStoreKey(DeviceId deviceId, PortNumber portNum,
20 TrafficTreatment treatment) { 28 TrafficTreatment treatment) {
21 this.deviceId = deviceId; 29 this.deviceId = deviceId;
......
...@@ -22,12 +22,18 @@ import org.onosproject.net.DeviceId; ...@@ -22,12 +22,18 @@ import org.onosproject.net.DeviceId;
22 import java.util.Objects; 22 import java.util.Objects;
23 23
24 /** 24 /**
25 - * Class definition of Key for Subnet to NextObjective store. 25 + * Key of Subnet to NextObjective store.
26 */ 26 */
27 public class SubnetNextObjectiveStoreKey { 27 public class SubnetNextObjectiveStoreKey {
28 private final DeviceId deviceId; 28 private final DeviceId deviceId;
29 private final IpPrefix prefix; 29 private final IpPrefix prefix;
30 30
31 + /**
32 + * Constructs the key of subnet next objective store.
33 + *
34 + * @param deviceId device ID
35 + * @param prefix subnet information
36 + */
31 public SubnetNextObjectiveStoreKey(DeviceId deviceId, 37 public SubnetNextObjectiveStoreKey(DeviceId deviceId,
32 IpPrefix prefix) { 38 IpPrefix prefix) {
33 this.deviceId = deviceId; 39 this.deviceId = deviceId;
......
1 +/*
2 + * Copyright 2015 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.segmentrouting.grouphandler;
18 +
19 +import org.onlab.packet.VlanId;
20 +import org.onosproject.net.DeviceId;
21 +
22 +import java.util.Objects;
23 +
24 +/**
25 + * Key of VLAN cross-connect next objective store.
26 + */
27 +public class XConnectNextObjectiveStoreKey {
28 + private final DeviceId deviceId;
29 + private final VlanId vlanId;
30 +
31 + /**
32 + * Constructs the key of cross-connect next objective store.
33 + *
34 + * @param deviceId device ID of the VLAN cross-connection
35 + * @param vlanId VLAN ID of the VLAN cross-connection
36 + */
37 + public XConnectNextObjectiveStoreKey(DeviceId deviceId, VlanId vlanId) {
38 + this.deviceId = deviceId;
39 + this.vlanId = vlanId;
40 + }
41 +
42 + /**
43 + * Returns the device ID of this key.
44 + *
45 + * @return device ID
46 + */
47 + public DeviceId deviceId() {
48 + return this.deviceId;
49 + }
50 +
51 + /**
52 + * Returns the VLAN ID of this key.
53 + *
54 + * @return VLAN ID
55 + */
56 + public VlanId vlanId() {
57 + return this.vlanId;
58 + }
59 +
60 + @Override
61 + public boolean equals(Object o) {
62 + if (this == o) {
63 + return true;
64 + }
65 + if (!(o instanceof XConnectNextObjectiveStoreKey)) {
66 + return false;
67 + }
68 + XConnectNextObjectiveStoreKey that =
69 + (XConnectNextObjectiveStoreKey) o;
70 + return (Objects.equals(this.deviceId, that.deviceId) &&
71 + Objects.equals(this.vlanId, that.vlanId));
72 + }
73 +
74 + // The list of neighbor ids and label are used for comparison.
75 + @Override
76 + public int hashCode() {
77 + return Objects.hash(deviceId, vlanId);
78 + }
79 +
80 + @Override
81 + public String toString() {
82 + return "Device: " + deviceId + " VlanId: " + vlanId;
83 + }
84 +}
...@@ -21,6 +21,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode; ...@@ -21,6 +21,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
21 import org.onosproject.segmentrouting.Policy; 21 import org.onosproject.segmentrouting.Policy;
22 import org.onosproject.segmentrouting.TunnelPolicy; 22 import org.onosproject.segmentrouting.TunnelPolicy;
23 23
24 +/**
25 + * Codec of Policy class.
26 + */
24 public final class PolicyCodec extends JsonCodec<Policy> { 27 public final class PolicyCodec extends JsonCodec<Policy> {
25 28
26 // JSON field names 29 // JSON field names
......
...@@ -26,6 +26,9 @@ import org.onosproject.segmentrouting.Tunnel; ...@@ -26,6 +26,9 @@ import org.onosproject.segmentrouting.Tunnel;
26 import java.util.ArrayList; 26 import java.util.ArrayList;
27 import java.util.List; 27 import java.util.List;
28 28
29 +/**
30 + * Codec of Tunnel class.
31 + */
29 public final class TunnelCodec extends JsonCodec<Tunnel> { 32 public final class TunnelCodec extends JsonCodec<Tunnel> {
30 33
31 // JSON field names 34 // JSON field names
......
...@@ -305,29 +305,35 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline ...@@ -305,29 +305,35 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
305 } 305 }
306 306
307 VlanId assignedVlan = null; 307 VlanId assignedVlan = null;
308 - if (vidCriterion != null && vidCriterion.vlanId() == VlanId.NONE) { 308 + // For VLAN cross-connect packets, use the configured VLAN
309 - // untagged packets are assigned vlans in OF-DPA 309 + if (vidCriterion != null) {
310 - if (filt.meta() == null) { 310 + if (vidCriterion.vlanId() != VlanId.NONE) {
311 - log.error("Missing metadata in filtering objective required " 311 + assignedVlan = vidCriterion.vlanId();
312 - + "for vlan assignment in dev {}", deviceId); 312 +
313 - fail(filt, ObjectiveError.BADPARAMS); 313 + // For untagged packets, assign a VLAN ID
314 - return; 314 + } else {
315 - } 315 + if (filt.meta() == null) {
316 - for (Instruction i : filt.meta().allInstructions()) { 316 + log.error("Missing metadata in filtering objective required " +
317 - if (i instanceof ModVlanIdInstruction) { 317 + "for vlan assignment in dev {}", deviceId);
318 - assignedVlan = ((ModVlanIdInstruction) i).vlanId(); 318 + fail(filt, ObjectiveError.BADPARAMS);
319 + return;
320 + }
321 + for (Instruction i : filt.meta().allInstructions()) {
322 + if (i instanceof ModVlanIdInstruction) {
323 + assignedVlan = ((ModVlanIdInstruction) i).vlanId();
324 + }
325 + }
326 + if (assignedVlan == null) {
327 + log.error("Driver requires an assigned vlan-id to tag incoming "
328 + + "untagged packets. Not processing vlan filters on "
329 + + "device {}", deviceId);
330 + fail(filt, ObjectiveError.BADPARAMS);
331 + return;
319 } 332 }
320 - }
321 - if (assignedVlan == null) {
322 - log.error("Driver requires an assigned vlan-id to tag incoming "
323 - + "untagged packets. Not processing vlan filters on "
324 - + "device {}", deviceId);
325 - fail(filt, ObjectiveError.BADPARAMS);
326 - return;
327 } 333 }
328 } 334 }
329 335
330 - if (ethCriterion == null) { 336 + if (ethCriterion == null || ethCriterion.mac().equals(MacAddress.NONE)) {
331 log.debug("filtering objective missing dstMac, cannot program TMAC table"); 337 log.debug("filtering objective missing dstMac, cannot program TMAC table");
332 } else { 338 } else {
333 for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion, 339 for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion,
...@@ -340,8 +346,8 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline ...@@ -340,8 +346,8 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
340 } 346 }
341 347
342 if (ethCriterion == null || vidCriterion == null) { 348 if (ethCriterion == null || vidCriterion == null) {
343 - log.debug("filtering objective missing dstMac or vlan, cannot program" 349 + log.debug("filtering objective missing dstMac or VLAN, "
344 - + "Vlan Table"); 350 + + "cannot program VLAN Table");
345 } else { 351 } else {
346 for (FlowRule vlanRule : processVlanIdFilter(portCriterion, vidCriterion, 352 for (FlowRule vlanRule : processVlanIdFilter(portCriterion, vidCriterion,
347 assignedVlan, 353 assignedVlan,
......
...@@ -837,7 +837,6 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -837,7 +837,6 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
837 if (vlanIdCriterion.vlanId() != VlanId.NONE) { 837 if (vlanIdCriterion.vlanId() != VlanId.NONE) {
838 selector.matchVlanId(vlanIdCriterion.vlanId()); 838 selector.matchVlanId(vlanIdCriterion.vlanId());
839 selector.matchInPort(p.port()); 839 selector.matchInPort(p.port());
840 - treatment.deferred().popVlan();
841 } else { 840 } else {
842 selector.matchInPort(p.port()); 841 selector.matchInPort(p.port());
843 treatment.immediate().pushVlan().setVlanId(assignedVlan); 842 treatment.immediate().pushVlan().setVlanId(assignedVlan);
...@@ -887,25 +886,31 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -887,25 +886,31 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
887 } 886 }
888 887
889 VlanId assignedVlan = null; 888 VlanId assignedVlan = null;
890 - if (vlanIdCriterion != null && vlanIdCriterion.vlanId() == VlanId.NONE) { 889 + if (vlanIdCriterion != null) {
891 - // Assign a VLAN ID to untagged packets 890 + // For VLAN cross-connect packets, use the configured VLAN
892 - if (filt.meta() == null) { 891 + if (vlanIdCriterion.vlanId() != VlanId.NONE) {
893 - log.error("Missing metadata in filtering objective required " 892 + assignedVlan = vlanIdCriterion.vlanId();
894 - + "for vlan assignment in dev {}", deviceId); 893 +
895 - fail(filt, ObjectiveError.BADPARAMS); 894 + // For untagged packets, assign a VLAN ID
896 - return; 895 + } else {
897 - } 896 + if (filt.meta() == null) {
898 - for (Instruction i : filt.meta().allInstructions()) { 897 + log.error("Missing metadata in filtering objective required " +
899 - if (i instanceof ModVlanIdInstruction) { 898 + "for vlan assignment in dev {}", deviceId);
900 - assignedVlan = ((ModVlanIdInstruction) i).vlanId(); 899 + fail(filt, ObjectiveError.BADPARAMS);
900 + return;
901 + }
902 + for (Instruction i : filt.meta().allInstructions()) {
903 + if (i instanceof ModVlanIdInstruction) {
904 + assignedVlan = ((ModVlanIdInstruction) i).vlanId();
905 + }
906 + }
907 + if (assignedVlan == null) {
908 + log.error("Driver requires an assigned vlan-id to tag incoming "
909 + + "untagged packets. Not processing vlan filters on "
910 + + "device {}", deviceId);
911 + fail(filt, ObjectiveError.BADPARAMS);
912 + return;
901 } 913 }
902 - }
903 - if (assignedVlan == null) {
904 - log.error("Driver requires an assigned vlan-id to tag incoming "
905 - + "untagged packets. Not processing vlan filters on "
906 - + "device {}", deviceId);
907 - fail(filt, ObjectiveError.BADPARAMS);
908 - return;
909 } 914 }
910 } 915 }
911 916
...@@ -923,9 +928,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -923,9 +928,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
923 } 928 }
924 } 929 }
925 930
926 - if (ethCriterion == null || vlanIdCriterion == null) { 931 + if (vlanIdCriterion == null) {
927 - log.debug("filtering objective missing dstMac or vlan, cannot program" 932 + log.debug("filtering objective missing VLAN ID criterion, "
928 - + "Vlan Table"); 933 + + "cannot program VLAN Table");
929 } else { 934 } else {
930 for (FlowRule vlanRule : processVlanIdFilter(vlanIdCriterion, 935 for (FlowRule vlanRule : processVlanIdFilter(vlanIdCriterion,
931 filt, 936 filt,
......
1 +{
2 + "ports" : {
3 + "of:0000000000000001/3" : {
4 + "interfaces" : [
5 + {
6 + "ips" : [ "10.0.1.254/24" ],
7 + "vlan" : "-1"
8 + },
9 + {
10 + "vlan" : "100"
11 + }
12 + ]
13 + },
14 + "of:0000000000000001/4" : {
15 + "interfaces" : [
16 + {
17 + "ips" : [ "10.0.1.254/24" ],
18 + "vlan" : "-1"
19 + }
20 + ]
21 + },
22 + "of:0000000000000001/5" : {
23 + "interfaces" : [
24 + {
25 + "vlan" : "100"
26 + }
27 + ]
28 + },
29 + "of:0000000000000002/3" : {
30 + "interfaces" : [
31 + {
32 + "ips" : [ "10.0.2.254/24" ],
33 + "vlan" : "-1"
34 + }
35 + ]
36 + },
37 + "of:0000000000000002/4" : {
38 + "interfaces" : [
39 + {
40 + "ips" : [ "10.0.2.254/24" ],
41 + "vlan" : "-1"
42 + }
43 + ]
44 + }
45 + },
46 + "devices" : {
47 + "of:0000000000000001" : {
48 + "segmentrouting" : {
49 + "name" : "Leaf-R1",
50 + "nodeSid" : 101,
51 + "routerIp" : "10.0.1.254",
52 + "routerMac" : "00:00:00:00:01:80",
53 + "isEdgeRouter" : true,
54 + "adjacencySids" : []
55 + }
56 + },
57 + "of:0000000000000002" : {
58 + "segmentrouting" : {
59 + "name" : "Leaf-R2",
60 + "nodeSid" : 102,
61 + "routerIp" : "10.0.2.254",
62 + "routerMac" : "00:00:00:00:02:80",
63 + "isEdgeRouter" : true,
64 + "adjacencySids" : []
65 + }
66 + },
67 + "of:0000000000000191" : {
68 + "segmentrouting" : {
69 + "name" : "Spine-R1",
70 + "nodeSid" : 103,
71 + "routerIp" : "192.168.0.11",
72 + "routerMac" : "00:00:01:00:11:80",
73 + "isEdgeRouter" : false,
74 + "adjacencySids" : []
75 + }
76 + },
77 + "of:0000000000000192" : {
78 + "segmentrouting" : {
79 + "name" : "Spine-R2",
80 + "nodeSid" : 104,
81 + "routerIp" : "192.168.0.22",
82 + "routerMac" : "00:00:01:00:22:80",
83 + "isEdgeRouter" : false,
84 + "adjacencySids" : []
85 + }
86 + }
87 + },
88 + "hosts" : {
89 + "00:00:00:00:00:01/4093" : {
90 + "basic": {
91 + "ips": ["10.0.1.1"],
92 + "location": "of:0000000000000001/3"
93 + }
94 + },
95 + "00:00:00:00:00:02/4093" : {
96 + "basic": {
97 + "ips": ["10.0.1.2"],
98 + "location": "of:0000000000000001/4"
99 + }
100 + },
101 + "00:00:00:00:00:03/4093" : {
102 + "basic": {
103 + "ips": ["10.0.2.1"],
104 + "location": "of:0000000000000002/3"
105 + }
106 + },
107 + "00:00:00:00:00:04/4093" : {
108 + "basic": {
109 + "ips": ["10.0.2.2"],
110 + "location": "of:0000000000000002/4"
111 + }
112 + }
113 + }
114 +}
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
4 "interfaces" : [ 4 "interfaces" : [
5 { 5 {
6 "ips" : [ "10.0.1.254/24" ], 6 "ips" : [ "10.0.1.254/24" ],
7 - "mac" : "08:9e:01:82:38:68", 7 + "vlan" : "-1"
8 - "vlan" : "100"
9 } 8 }
10 ] 9 ]
11 }, 10 },
...@@ -13,8 +12,7 @@ ...@@ -13,8 +12,7 @@
13 "interfaces" : [ 12 "interfaces" : [
14 { 13 {
15 "ips" : [ "10.0.1.254/24" ], 14 "ips" : [ "10.0.1.254/24" ],
16 - "mac" : "08:9e:01:82:38:68", 15 + "vlan" : "-1"
17 - "vlan" : "100"
18 } 16 }
19 ] 17 ]
20 }, 18 },
...@@ -22,8 +20,7 @@ ...@@ -22,8 +20,7 @@
22 "interfaces" : [ 20 "interfaces" : [
23 { 21 {
24 "ips" : [ "10.0.2.254/24" ], 22 "ips" : [ "10.0.2.254/24" ],
25 - "mac" : "08:9e:01:82:38:68", 23 + "vlan" : "-1"
26 - "vlan" : "100"
27 } 24 }
28 ] 25 ]
29 }, 26 },
...@@ -31,8 +28,7 @@ ...@@ -31,8 +28,7 @@
31 "interfaces" : [ 28 "interfaces" : [
32 { 29 {
33 "ips" : [ "10.0.2.254/24" ], 30 "ips" : [ "10.0.2.254/24" ],
34 - "mac" : "08:9e:01:82:38:68", 31 + "vlan" : "-1"
35 - "vlan" : "100"
36 } 32 }
37 ] 33 ]
38 } 34 }
......
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
4 "interfaces" : [ 4 "interfaces" : [
5 { 5 {
6 "ips" : [ "10.0.1.254/24" ], 6 "ips" : [ "10.0.1.254/24" ],
7 - "mac" : "08:9e:01:82:38:68", 7 + "vlan" : "-1"
8 - "vlan" : "100"
9 } 8 }
10 ] 9 ]
11 }, 10 },
...@@ -13,8 +12,7 @@ ...@@ -13,8 +12,7 @@
13 "interfaces" : [ 12 "interfaces" : [
14 { 13 {
15 "ips" : [ "10.0.1.254/24" ], 14 "ips" : [ "10.0.1.254/24" ],
16 - "mac" : "08:9e:01:82:38:68", 15 + "vlan" : "-1"
17 - "vlan" : "100"
18 } 16 }
19 ] 17 ]
20 }, 18 },
...@@ -22,8 +20,7 @@ ...@@ -22,8 +20,7 @@
22 "interfaces" : [ 20 "interfaces" : [
23 { 21 {
24 "ips" : [ "10.0.2.254/24" ], 22 "ips" : [ "10.0.2.254/24" ],
25 - "mac" : "08:9e:01:82:38:68", 23 + "vlan" : "-1"
26 - "vlan" : "100"
27 } 24 }
28 ] 25 ]
29 }, 26 },
...@@ -31,8 +28,7 @@ ...@@ -31,8 +28,7 @@
31 "interfaces" : [ 28 "interfaces" : [
32 { 29 {
33 "ips" : [ "10.0.2.254/24" ], 30 "ips" : [ "10.0.2.254/24" ],
34 - "mac" : "08:9e:01:82:38:68", 31 + "vlan" : "-1"
35 - "vlan" : "100"
36 } 32 }
37 ] 33 ]
38 }, 34 },
...@@ -40,8 +36,7 @@ ...@@ -40,8 +36,7 @@
40 "interfaces" : [ 36 "interfaces" : [
41 { 37 {
42 "ips" : [ "10.0.3.254/24" ], 38 "ips" : [ "10.0.3.254/24" ],
43 - "mac" : "08:9e:01:82:38:68", 39 + "vlan" : "-1"
44 - "vlan" : "100"
45 } 40 }
46 ] 41 ]
47 }, 42 },
...@@ -49,8 +44,7 @@ ...@@ -49,8 +44,7 @@
49 "interfaces" : [ 44 "interfaces" : [
50 { 45 {
51 "ips" : [ "10.0.3.254/24" ], 46 "ips" : [ "10.0.3.254/24" ],
52 - "mac" : "08:9e:01:82:38:68", 47 + "vlan" : "-1"
53 - "vlan" : "100"
54 } 48 }
55 ] 49 ]
56 }, 50 },
...@@ -58,8 +52,7 @@ ...@@ -58,8 +52,7 @@
58 "interfaces" : [ 52 "interfaces" : [
59 { 53 {
60 "ips" : [ "10.0.4.254/24" ], 54 "ips" : [ "10.0.4.254/24" ],
61 - "mac" : "08:9e:01:82:38:68", 55 + "vlan" : "-1"
62 - "vlan" : "100"
63 } 56 }
64 ] 57 ]
65 }, 58 },
...@@ -67,8 +60,7 @@ ...@@ -67,8 +60,7 @@
67 "interfaces" : [ 60 "interfaces" : [
68 { 61 {
69 "ips" : [ "10.0.4.254/24" ], 62 "ips" : [ "10.0.4.254/24" ],
70 - "mac" : "08:9e:01:82:38:68", 63 + "vlan" : "-1"
71 - "vlan" : "100"
72 } 64 }
73 ] 65 ]
74 } 66 }
......