Saurav Das
Committed by Gerrit Code Review

Adding more filtering objectives from the router application and handling them

in the corsa-pipeline driver

Change-Id: I3598b84ce25df97c10b33c6f1fdfc76421499046
...@@ -20,6 +20,7 @@ import com.google.common.collect.HashMultimap; ...@@ -20,6 +20,7 @@ import com.google.common.collect.HashMultimap;
20 import com.google.common.collect.Maps; 20 import com.google.common.collect.Maps;
21 import com.google.common.collect.Multimap; 21 import com.google.common.collect.Multimap;
22 import com.google.common.collect.Multiset; 22 import com.google.common.collect.Multiset;
23 +
23 import org.apache.felix.scr.annotations.Activate; 24 import org.apache.felix.scr.annotations.Activate;
24 import org.apache.felix.scr.annotations.Component; 25 import org.apache.felix.scr.annotations.Component;
25 import org.apache.felix.scr.annotations.Deactivate; 26 import org.apache.felix.scr.annotations.Deactivate;
...@@ -30,14 +31,11 @@ import org.onlab.packet.Ip4Address; ...@@ -30,14 +31,11 @@ import org.onlab.packet.Ip4Address;
30 import org.onlab.packet.Ip6Address; 31 import org.onlab.packet.Ip6Address;
31 import org.onlab.packet.IpAddress; 32 import org.onlab.packet.IpAddress;
32 import org.onlab.packet.IpPrefix; 33 import org.onlab.packet.IpPrefix;
33 -import org.onlab.packet.MacAddress;
34 -import org.onlab.packet.VlanId;
35 import org.onlab.util.KryoNamespace; 34 import org.onlab.util.KryoNamespace;
36 import org.onosproject.config.NetworkConfigService; 35 import org.onosproject.config.NetworkConfigService;
37 import org.onosproject.core.ApplicationId; 36 import org.onosproject.core.ApplicationId;
38 import org.onosproject.core.CoreService; 37 import org.onosproject.core.CoreService;
39 import org.onosproject.net.DeviceId; 38 import org.onosproject.net.DeviceId;
40 -import org.onosproject.net.PortNumber;
41 import org.onosproject.net.flow.DefaultFlowRule; 39 import org.onosproject.net.flow.DefaultFlowRule;
42 import org.onosproject.net.flow.DefaultTrafficSelector; 40 import org.onosproject.net.flow.DefaultTrafficSelector;
43 import org.onosproject.net.flow.DefaultTrafficTreatment; 41 import org.onosproject.net.flow.DefaultTrafficTreatment;
...@@ -60,7 +58,6 @@ import org.onosproject.net.group.GroupDescription; ...@@ -60,7 +58,6 @@ import org.onosproject.net.group.GroupDescription;
60 import org.onosproject.net.group.GroupEvent; 58 import org.onosproject.net.group.GroupEvent;
61 import org.onosproject.net.group.GroupListener; 59 import org.onosproject.net.group.GroupListener;
62 import org.onosproject.net.group.GroupService; 60 import org.onosproject.net.group.GroupService;
63 -import org.onosproject.net.host.InterfaceIpAddress;
64 import org.onosproject.net.packet.PacketService; 61 import org.onosproject.net.packet.PacketService;
65 import org.onosproject.routing.FibEntry; 62 import org.onosproject.routing.FibEntry;
66 import org.onosproject.routing.FibListener; 63 import org.onosproject.routing.FibListener;
...@@ -75,7 +72,6 @@ import org.slf4j.LoggerFactory; ...@@ -75,7 +72,6 @@ import org.slf4j.LoggerFactory;
75 import java.util.Collection; 72 import java.util.Collection;
76 import java.util.Collections; 73 import java.util.Collections;
77 import java.util.HashMap; 74 import java.util.HashMap;
78 -import java.util.HashSet;
79 import java.util.Map; 75 import java.util.Map;
80 import java.util.Set; 76 import java.util.Set;
81 import java.util.stream.Collectors; 77 import java.util.stream.Collectors;
...@@ -146,8 +142,6 @@ public class BgpRouter { ...@@ -146,8 +142,6 @@ public class BgpRouter {
146 142
147 private IcmpHandler icmpHandler; 143 private IcmpHandler icmpHandler;
148 144
149 - private InternalTableHandler provisionStaticTables = new InternalTableHandler();
150 -
151 private KryoNamespace appKryo = new KryoNamespace.Builder() 145 private KryoNamespace appKryo = new KryoNamespace.Builder()
152 .register(IpAddress.Version.class) 146 .register(IpAddress.Version.class)
153 .register(IpAddress.class) 147 .register(IpAddress.class)
...@@ -168,7 +162,7 @@ public class BgpRouter { ...@@ -168,7 +162,7 @@ public class BgpRouter {
168 162
169 groupService.addListener(groupListener); 163 groupService.addListener(groupListener);
170 164
171 - provisionStaticTables.provision(true, configService.getInterfaces()); 165 + processIntfFilters(true, configService.getInterfaces());
172 166
173 connectivityManager = new TunnellingConnectivityManager(appId, 167 connectivityManager = new TunnellingConnectivityManager(appId,
174 configService, 168 configService,
...@@ -192,7 +186,7 @@ public class BgpRouter { ...@@ -192,7 +186,7 @@ public class BgpRouter {
192 routingService.stop(); 186 routingService.stop();
193 connectivityManager.stop(); 187 connectivityManager.stop();
194 icmpHandler.stop(); 188 icmpHandler.stop();
195 - provisionStaticTables.provision(false, configService.getInterfaces()); 189 + processIntfFilters(false, configService.getInterfaces());
196 190
197 groupService.removeListener(groupListener); 191 groupService.removeListener(groupListener);
198 192
...@@ -380,30 +374,20 @@ public class BgpRouter { ...@@ -380,30 +374,20 @@ public class BgpRouter {
380 } 374 }
381 } 375 }
382 376
383 - private class InternalTableHandler { 377 + private void processIntfFilters(boolean install, Set<Interface> intfs) {
384 - 378 + log.info("Processing {} router interfaces", intfs.size());
385 - private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>(); 379 + for (Interface intf : intfs) {
386 - private Set<MacAddress> intfMacs = new HashSet<MacAddress>(); 380 + FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
387 - private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap(); 381 + fob.withKey(Criteria.matchInPort(intf.connectPoint().port()))
388 - 382 + .addCondition(Criteria.matchEthDst(intf.mac()))
389 - public void provision(boolean install, Set<Interface> intfs) { 383 + .addCondition(Criteria.matchVlanId(intf.vlan()));
390 - getInterfaceConfig(intfs); 384 + intf.ipAddresses().stream()
385 + .forEach(ipaddr -> fob.addCondition(
386 + Criteria.matchIPDst(ipaddr.subnetAddress())));
387 + fob.permit().fromApp(appId);
388 + flowObjectiveService.filter(deviceId,
389 + Collections.singletonList(fob.add()));
391 } 390 }
392 -
393 - private void getInterfaceConfig(Set<Interface> intfs) {
394 - log.info("Processing {} router interfaces", intfs.size());
395 - for (Interface intf : intfs) {
396 - FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
397 - flowObjectiveService.filter(deviceId, Collections.singletonList(
398 - fob.addCondition(Criteria.matchEthDst(intf.mac()))
399 - .fromApp(appId).permit().add()));
400 - intfIps.addAll(intf.ipAddresses());
401 - intfMacs.add(intf.mac());
402 - portVlanPair.put(intf.connectPoint().port(), intf.vlan());
403 - }
404 - }
405 -
406 -
407 } 391 }
408 392
409 private class InternalGroupListener implements GroupListener { 393 private class InternalGroupListener implements GroupListener {
......
...@@ -83,53 +83,94 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -83,53 +83,94 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
83 83
84 @Override 84 @Override
85 public Future<Boolean> filter(Collection<FilteringObjective> filteringObjectives) { 85 public Future<Boolean> filter(Collection<FilteringObjective> filteringObjectives) {
86 - Collection<Future<Boolean>> results = 86 + Collection<Future<Boolean>> results = Sets.newHashSet();
87 - Sets.newHashSet();
88 filteringObjectives.stream() 87 filteringObjectives.stream()
89 .filter(obj -> obj.type() == FilteringObjective.Type.PERMIT) 88 .filter(obj -> obj.type() == FilteringObjective.Type.PERMIT)
90 - .forEach(obj -> obj.conditions() 89 + .forEach(filtobj -> results.add(processFilter(filtobj,
91 - .forEach(condition -> 90 + filtobj.op() == Objective.Operation.ADD,
92 - results.add(processCondition(condition, 91 + filtobj.appId()
93 - obj.op() == Objective.Operation.ADD, 92 + )));
94 - obj.appId()))
95 - ));
96 93
97 //TODO: return something more helpful/sensible in the future (no pun intended) 94 //TODO: return something more helpful/sensible in the future (no pun intended)
98 return results.iterator().next(); 95 return results.iterator().next();
99 96
100 } 97 }
101 98
102 - private Future<Boolean> processCondition(Criterion c, boolean install, 99 + private Future<Boolean> processFilter(FilteringObjective filt, boolean install,
103 ApplicationId applicationId) { 100 ApplicationId applicationId) {
104 SettableFuture<Boolean> result = SettableFuture.create(); 101 SettableFuture<Boolean> result = SettableFuture.create();
105 - if (c.type() == Criterion.Type.ETH_DST) { 102 + // This driver only processes filtering criteria defined with switch
106 - Criteria.EthCriterion e = (Criteria.EthCriterion) c; 103 + // ports as the key
107 - log.debug("adding rule for MAC: {}", e.mac()); 104 + Criteria.PortCriterion p = null;
108 - 105 + if (!filt.key().equals(Criteria.dummy()) &&
109 - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); 106 + filt.key().type() == Criterion.Type.IN_PORT) {
110 - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); 107 + p = (Criteria.PortCriterion) filt.key();
111 - selector.matchEthDst(e.mac()); 108 + } else {
112 - treatment.transition(FlowRule.Type.VLAN_MPLS); 109 + log.warn("No key defined in filtering objective from app: {}. Not"
113 - FlowRule rule = new DefaultFlowRule(deviceId, selector.build(), 110 + + "processing filtering objective", applicationId);
114 - treatment.build(), 111 + return null;
115 - CONTROLLER_PRIORITY, applicationId, 0,
116 - true, FlowRule.Type.FIRST);
117 - FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
118 - ops = install ? ops.add(rule) : ops.remove(rule);
119 - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
120 - @Override
121 - public void onSuccess(FlowRuleOperations ops) {
122 - result.set(true);
123 - log.info("Provisioned default table for bgp router");
124 - }
125 -
126 - @Override
127 - public void onError(FlowRuleOperations ops) {
128 - result.set(false);
129 - log.info("Failed to provision default table for bgp router");
130 - }
131 - }));
132 } 112 }
113 + // convert filtering conditions for switch-intfs into flowrules
114 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
115 + for (Criterion c : filt.conditions()) {
116 + if (c.type() == Criterion.Type.ETH_DST) {
117 + Criteria.EthCriterion e = (Criteria.EthCriterion) c;
118 + log.debug("adding rule for MAC: {}", e.mac());
119 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
120 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
121 + selector.matchEthDst(e.mac());
122 + treatment.transition(FlowRule.Type.VLAN_MPLS);
123 + FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
124 + treatment.build(),
125 + CONTROLLER_PRIORITY, applicationId,
126 + 0, true, FlowRule.Type.FIRST);
127 + ops = install ? ops.add(rule) : ops.remove(rule);
128 + } else if (c.type() == Criterion.Type.VLAN_VID) {
129 + Criteria.VlanIdCriterion v = (Criteria.VlanIdCriterion) c;
130 + log.debug("adding rule for VLAN: {}", v.vlanId());
131 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
132 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
133 + selector.matchVlanId(v.vlanId());
134 + selector.matchInPort(p.port());
135 + treatment.transition(FlowRule.Type.ETHER);
136 + treatment.deferred().popVlan();
137 + FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
138 + treatment.build(),
139 + CONTROLLER_PRIORITY, applicationId,
140 + 0, true, FlowRule.Type.VLAN);
141 + ops = install ? ops.add(rule) : ops.remove(rule);
142 + } else if (c.type() == Criterion.Type.IPV4_DST) {
143 + Criteria.IPCriterion ip = (Criteria.IPCriterion) c;
144 + log.debug("adding rule for IP: {}", ip.ip());
145 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
146 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
147 + selector.matchEthType(Ethernet.TYPE_IPV4);
148 + selector.matchIPDst(ip.ip());
149 + treatment.transition(FlowRule.Type.ACL);
150 + FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
151 + treatment.build(), HIGHEST_PRIORITY, appId,
152 + 0, true, FlowRule.Type.IP);
153 + ops = install ? ops.add(rule) : ops.remove(rule);
154 + } else {
155 + log.warn("Driver does not currently process filtering condition"
156 + + " of type: {}", c.type());
157 + }
158 + }
159 + // apply filtering flow rules
160 + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
161 + @Override
162 + public void onSuccess(FlowRuleOperations ops) {
163 + result.set(true);
164 + log.info("Provisioned default table for bgp router");
165 + }
166 +
167 + @Override
168 + public void onError(FlowRuleOperations ops) {
169 + result.set(false);
170 + log.info("Failed to provision default table for bgp router");
171 + }
172 + }));
173 +
133 return result; 174 return result;
134 } 175 }
135 176
......