Committed by
Gerrit Code Review
CORD-455 Implement multicast support in OFDPA driver
Also refactor Ofdpa2GroupHandler Change-Id: Id6a9224cab663f57edb8e85a0e7d81e7da3df132
Showing
4 changed files
with
109 additions
and
24 deletions
... | @@ -26,6 +26,7 @@ import java.util.Set; | ... | @@ -26,6 +26,7 @@ import java.util.Set; |
26 | import java.util.concurrent.ConcurrentHashMap; | 26 | import java.util.concurrent.ConcurrentHashMap; |
27 | 27 | ||
28 | import com.google.common.collect.ImmutableList; | 28 | import com.google.common.collect.ImmutableList; |
29 | +import com.google.common.collect.ImmutableSet; | ||
29 | import org.onlab.packet.Ethernet; | 30 | import org.onlab.packet.Ethernet; |
30 | import org.onlab.packet.MacAddress; | 31 | import org.onlab.packet.MacAddress; |
31 | import org.onlab.packet.IpPrefix; | 32 | import org.onlab.packet.IpPrefix; |
... | @@ -99,7 +100,8 @@ public class CpqdOfdpa2Pipeline extends Ofdpa2Pipeline { | ... | @@ -99,7 +100,8 @@ public class CpqdOfdpa2Pipeline extends Ofdpa2Pipeline { |
99 | // convert filtering conditions for switch-intfs into flowrules | 100 | // convert filtering conditions for switch-intfs into flowrules |
100 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 101 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
101 | for (Criterion criterion : filt.conditions()) { | 102 | for (Criterion criterion : filt.conditions()) { |
102 | - if (criterion.type() == Criterion.Type.ETH_DST) { | 103 | + if (criterion.type() == Criterion.Type.ETH_DST || |
104 | + criterion.type() == Criterion.Type.ETH_DST_MASKED) { | ||
103 | ethCriterion = (EthCriterion) criterion; | 105 | ethCriterion = (EthCriterion) criterion; |
104 | } else if (criterion.type() == Criterion.Type.VLAN_VID) { | 106 | } else if (criterion.type() == Criterion.Type.VLAN_VID) { |
105 | vidCriterion = (VlanIdCriterion) criterion; | 107 | vidCriterion = (VlanIdCriterion) criterion; |
... | @@ -294,6 +296,11 @@ public class CpqdOfdpa2Pipeline extends Ofdpa2Pipeline { | ... | @@ -294,6 +296,11 @@ public class CpqdOfdpa2Pipeline extends Ofdpa2Pipeline { |
294 | return processEthDstOnlyFilter(ethCriterion, applicationId); | 296 | return processEthDstOnlyFilter(ethCriterion, applicationId); |
295 | } | 297 | } |
296 | 298 | ||
299 | + // Multicast MAC | ||
300 | + if (ethCriterion.mask() != null) { | ||
301 | + return processMcastEthDstFilter(ethCriterion, applicationId); | ||
302 | + } | ||
303 | + | ||
297 | //handling untagged packets via assigned VLAN | 304 | //handling untagged packets via assigned VLAN |
298 | if (vidCriterion.vlanId() == VlanId.NONE) { | 305 | if (vidCriterion.vlanId() == VlanId.NONE) { |
299 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | 306 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); |
... | @@ -416,19 +423,37 @@ public class CpqdOfdpa2Pipeline extends Ofdpa2Pipeline { | ... | @@ -416,19 +423,37 @@ public class CpqdOfdpa2Pipeline extends Ofdpa2Pipeline { |
416 | */ | 423 | */ |
417 | if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) { | 424 | if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) { |
418 | IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip(); | 425 | IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip(); |
419 | - if (ipv4Dst.prefixLength() > 0) { | 426 | + if (ipv4Dst.isMulticast()) { |
420 | - filteredSelector.matchEthType(Ethernet.TYPE_IPV4) | 427 | + if (ipv4Dst.prefixLength() != 32) { |
421 | - .matchIPDst(ipv4Dst); | 428 | + log.warn("Multicast specific forwarding objective can only be /32"); |
429 | + fail(fwd, ObjectiveError.BADPARAMS); | ||
430 | + return ImmutableSet.of(); | ||
431 | + } | ||
432 | + VlanId assignedVlan = readVlanFromSelector(fwd.meta()); | ||
433 | + if (assignedVlan == null) { | ||
434 | + log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort."); | ||
435 | + fail(fwd, ObjectiveError.BADPARAMS); | ||
436 | + return ImmutableSet.of(); | ||
437 | + } | ||
438 | + filteredSelector.matchVlanId(assignedVlan); | ||
439 | + filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst); | ||
440 | + forTableId = MULTICAST_ROUTING_TABLE; | ||
441 | + log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}" | ||
442 | + + " in dev:{}", fwd.id(), fwd.nextId(), deviceId); | ||
422 | } else { | 443 | } else { |
423 | - filteredSelector.matchEthType(Ethernet.TYPE_IPV4) | 444 | + if (ipv4Dst.prefixLength() > 0) { |
424 | - .matchIPDst(IpPrefix.valueOf("0.0.0.0/1")); | 445 | + filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst); |
425 | - complementarySelector.matchEthType(Ethernet.TYPE_IPV4) | 446 | + } else { |
426 | - .matchIPDst(IpPrefix.valueOf("128.0.0.0/1")); | 447 | + filteredSelector.matchEthType(Ethernet.TYPE_IPV4) |
427 | - defaultRule = true; | 448 | + .matchIPDst(IpPrefix.valueOf("0.0.0.0/1")); |
449 | + complementarySelector.matchEthType(Ethernet.TYPE_IPV4) | ||
450 | + .matchIPDst(IpPrefix.valueOf("128.0.0.0/1")); | ||
451 | + defaultRule = true; | ||
452 | + } | ||
453 | + forTableId = UNICAST_ROUTING_TABLE; | ||
454 | + log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}" | ||
455 | + + " in dev:{}", fwd.id(), fwd.nextId(), deviceId); | ||
428 | } | 456 | } |
429 | - forTableId = UNICAST_ROUTING_TABLE; | ||
430 | - log.debug("processing IPv4 specific forwarding objective {} -> next:{}" | ||
431 | - + " in dev:{}", fwd.id(), fwd.nextId(), deviceId); | ||
432 | } else { | 457 | } else { |
433 | filteredSelector | 458 | filteredSelector |
434 | .matchEthType(Ethernet.MPLS_UNICAST) | 459 | .matchEthType(Ethernet.MPLS_UNICAST) | ... | ... |
... | @@ -83,6 +83,11 @@ public class CpqdOfdpa2VlanPipeline extends CpqdOfdpa2Pipeline { | ... | @@ -83,6 +83,11 @@ public class CpqdOfdpa2VlanPipeline extends CpqdOfdpa2Pipeline { |
83 | return processEthDstOnlyFilter(ethCriterion, applicationId); | 83 | return processEthDstOnlyFilter(ethCriterion, applicationId); |
84 | } | 84 | } |
85 | 85 | ||
86 | + // Multicast MAC | ||
87 | + if (ethCriterion.mask() != null) { | ||
88 | + return processMcastEthDstFilter(ethCriterion, applicationId); | ||
89 | + } | ||
90 | + | ||
86 | //handling untagged packets via assigned VLAN | 91 | //handling untagged packets via assigned VLAN |
87 | if (vidCriterion.vlanId() == VlanId.NONE) { | 92 | if (vidCriterion.vlanId() == VlanId.NONE) { |
88 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | 93 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -28,6 +28,7 @@ import java.util.Set; | ... | @@ -28,6 +28,7 @@ import java.util.Set; |
28 | import java.util.concurrent.ConcurrentHashMap; | 28 | import java.util.concurrent.ConcurrentHashMap; |
29 | 29 | ||
30 | import com.google.common.collect.ImmutableList; | 30 | import com.google.common.collect.ImmutableList; |
31 | +import com.google.common.collect.ImmutableSet; | ||
31 | import org.onlab.osgi.ServiceDirectory; | 32 | import org.onlab.osgi.ServiceDirectory; |
32 | import org.onlab.packet.Ethernet; | 33 | import org.onlab.packet.Ethernet; |
33 | import org.onlab.packet.IpPrefix; | 34 | import org.onlab.packet.IpPrefix; |
... | @@ -297,7 +298,8 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -297,7 +298,8 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
297 | // convert filtering conditions for switch-intfs into flowrules | 298 | // convert filtering conditions for switch-intfs into flowrules |
298 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 299 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
299 | for (Criterion criterion : filt.conditions()) { | 300 | for (Criterion criterion : filt.conditions()) { |
300 | - if (criterion.type() == Criterion.Type.ETH_DST) { | 301 | + if (criterion.type() == Criterion.Type.ETH_DST || |
302 | + criterion.type() == Criterion.Type.ETH_DST_MASKED) { | ||
301 | ethCriterion = (EthCriterion) criterion; | 303 | ethCriterion = (EthCriterion) criterion; |
302 | } else if (criterion.type() == Criterion.Type.VLAN_VID) { | 304 | } else if (criterion.type() == Criterion.Type.VLAN_VID) { |
303 | vidCriterion = (VlanIdCriterion) criterion; | 305 | vidCriterion = (VlanIdCriterion) criterion; |
... | @@ -559,6 +561,11 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -559,6 +561,11 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
559 | return processEthDstOnlyFilter(ethCriterion, applicationId); | 561 | return processEthDstOnlyFilter(ethCriterion, applicationId); |
560 | } | 562 | } |
561 | 563 | ||
564 | + // Multicast MAC | ||
565 | + if (ethCriterion.mask() != null) { | ||
566 | + return processMcastEthDstFilter(ethCriterion, applicationId); | ||
567 | + } | ||
568 | + | ||
562 | //handling untagged packets via assigned VLAN | 569 | //handling untagged packets via assigned VLAN |
563 | if (vidCriterion.vlanId() == VlanId.NONE) { | 570 | if (vidCriterion.vlanId() == VlanId.NONE) { |
564 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | 571 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); |
... | @@ -635,6 +642,24 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -635,6 +642,24 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
635 | return ImmutableList.<FlowRule>builder().add(rule).build(); | 642 | return ImmutableList.<FlowRule>builder().add(rule).build(); |
636 | } | 643 | } |
637 | 644 | ||
645 | + protected List<FlowRule> processMcastEthDstFilter(EthCriterion ethCriterion, | ||
646 | + ApplicationId applicationId) { | ||
647 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
648 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
649 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
650 | + selector.matchEthDstMasked(ethCriterion.mac(), ethCriterion.mask()); | ||
651 | + treatment.transition(MULTICAST_ROUTING_TABLE); | ||
652 | + FlowRule rule = DefaultFlowRule.builder() | ||
653 | + .forDevice(deviceId) | ||
654 | + .withSelector(selector.build()) | ||
655 | + .withTreatment(treatment.build()) | ||
656 | + .withPriority(DEFAULT_PRIORITY) | ||
657 | + .fromApp(applicationId) | ||
658 | + .makePermanent() | ||
659 | + .forTable(TMAC_TABLE).build(); | ||
660 | + return ImmutableList.<FlowRule>builder().add(rule).build(); | ||
661 | + } | ||
662 | + | ||
638 | private Collection<FlowRule> processForward(ForwardingObjective fwd) { | 663 | private Collection<FlowRule> processForward(ForwardingObjective fwd) { |
639 | switch (fwd.flag()) { | 664 | switch (fwd.flag()) { |
640 | case SPECIFIC: | 665 | case SPECIFIC: |
... | @@ -802,19 +827,38 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -802,19 +827,38 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
802 | */ | 827 | */ |
803 | if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) { | 828 | if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) { |
804 | IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip(); | 829 | IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip(); |
805 | - if (ipv4Dst.prefixLength() > 0) { | 830 | + if (ipv4Dst.isMulticast()) { |
806 | - filteredSelector.matchEthType(Ethernet.TYPE_IPV4) | 831 | + if (ipv4Dst.prefixLength() != 32) { |
807 | - .matchIPDst(ipv4Dst); | 832 | + log.warn("Multicast specific forwarding objective can only be /32"); |
833 | + fail(fwd, ObjectiveError.BADPARAMS); | ||
834 | + return ImmutableSet.of(); | ||
835 | + } | ||
836 | + VlanId assignedVlan = readVlanFromSelector(fwd.meta()); | ||
837 | + if (assignedVlan == null) { | ||
838 | + log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort."); | ||
839 | + fail(fwd, ObjectiveError.BADPARAMS); | ||
840 | + return ImmutableSet.of(); | ||
841 | + } | ||
842 | + OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(assignedVlan); | ||
843 | + filteredSelector.extension(ofdpaMatchVlanVid, deviceId); | ||
844 | + filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst); | ||
845 | + forTableId = MULTICAST_ROUTING_TABLE; | ||
846 | + log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}" | ||
847 | + + " in dev:{}", fwd.id(), fwd.nextId(), deviceId); | ||
808 | } else { | 848 | } else { |
809 | - filteredSelector.matchEthType(Ethernet.TYPE_IPV4) | 849 | + if (ipv4Dst.prefixLength() > 0) { |
810 | - .matchIPDst(IpPrefix.valueOf("0.0.0.0/1")); | 850 | + filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst); |
811 | - complementarySelector.matchEthType(Ethernet.TYPE_IPV4) | 851 | + } else { |
812 | - .matchIPDst(IpPrefix.valueOf("128.0.0.0/1")); | 852 | + filteredSelector.matchEthType(Ethernet.TYPE_IPV4) |
813 | - defaultRule = true; | 853 | + .matchIPDst(IpPrefix.valueOf("0.0.0.0/1")); |
854 | + complementarySelector.matchEthType(Ethernet.TYPE_IPV4) | ||
855 | + .matchIPDst(IpPrefix.valueOf("128.0.0.0/1")); | ||
856 | + defaultRule = true; | ||
857 | + } | ||
858 | + forTableId = UNICAST_ROUTING_TABLE; | ||
859 | + log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}" | ||
860 | + + " in dev:{}", fwd.id(), fwd.nextId(), deviceId); | ||
814 | } | 861 | } |
815 | - forTableId = UNICAST_ROUTING_TABLE; | ||
816 | - log.debug("processing IPv4 specific forwarding objective {} -> next:{}" | ||
817 | - + " in dev:{}", fwd.id(), fwd.nextId(), deviceId); | ||
818 | 862 | ||
819 | if (fwd.treatment() != null) { | 863 | if (fwd.treatment() != null) { |
820 | for (Instruction instr : fwd.treatment().allInstructions()) { | 864 | for (Instruction instr : fwd.treatment().allInstructions()) { |
... | @@ -1057,4 +1101,15 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -1057,4 +1101,15 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
1057 | } | 1101 | } |
1058 | return mappings; | 1102 | return mappings; |
1059 | } | 1103 | } |
1104 | + | ||
1105 | + protected static VlanId readVlanFromSelector(TrafficSelector selector) { | ||
1106 | + Criterion criterion = selector.getCriterion(Criterion.Type.VLAN_VID); | ||
1107 | + return (criterion == null) | ||
1108 | + ? null : ((VlanIdCriterion) criterion).vlanId(); | ||
1109 | + } | ||
1110 | + | ||
1111 | + protected static IpPrefix readIpDstFromSelector(TrafficSelector selector) { | ||
1112 | + Criterion criterion = selector.getCriterion(Criterion.Type.IPV4_DST); | ||
1113 | + return (criterion == null) ? null : ((IPCriterion) criterion).ip(); | ||
1114 | + } | ||
1060 | } | 1115 | } | ... | ... |
-
Please register or login to post a comment