X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openstack%2Fnet-virt-providers%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fovsdb%2Fopenstack%2Fnetvirt%2Fproviders%2Fopenflow13%2Fservices%2FLoadBalancerService.java;h=4114fa735034ab618590fbadc3019a3b2f73fe18;hb=61c34dff97074213df13a255cb08856a2d7bf261;hp=261a95fba13d728e5c291490c1ac9056c5132266;hpb=f4773d492b2e73d4fd27639e60d69b1a8cf42f83;p=netvirt.git diff --git a/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/LoadBalancerService.java b/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/LoadBalancerService.java index 261a95fba1..4114fa7350 100644 --- a/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/LoadBalancerService.java +++ b/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/LoadBalancerService.java @@ -17,6 +17,7 @@ import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.Node.NodeIDType; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; +import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler; import org.opendaylight.ovsdb.openstack.netvirt.api.Constants; import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration; import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration.LoadBalancerPoolMember; @@ -45,12 +46,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.ovs.nx.action.rev140421.OfjNxHashFields; -import org.opendaylight.yang.gen.v1.urn.opendaylight.ovs.nx.action.rev140421.OfjNxMpAlgorithm; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxHashFields; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxMpAlgorithm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,6 +84,14 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load @Override public Status programLoadBalancerPoolMemberRules(Node node, LoadBalancerConfiguration lbConfig, LoadBalancerPoolMember member, org.opendaylight.ovsdb.openstack.netvirt.api.Action action) { + if (lbConfig == null || member == null) { + logger.error("Null value for LB config {} or Member {}", lbConfig, member); + return new Status(StatusCode.BADREQUEST); + } + if (!lbConfig.isValid()) { + logger.error("LB config is invalid: {}", lbConfig); + return new Status(StatusCode.BADREQUEST); + } if (!node.getType().equals(NodeIDType.OPENFLOW)) { logger.trace("Ignoring non-OpenFlow node {} from flow programming", node); return new Status(StatusCode.BADREQUEST); @@ -94,11 +104,11 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load nodeBuilder.setKey(new NodeKey(nodeBuilder.getId())); //Update the multipath rule - insertLoadBalancerVIPRulesFirstPass(nodeBuilder, lbConfig); + manageLoadBalancerVIPRulesFirstPass(nodeBuilder, lbConfig, true); if (action.equals(org.opendaylight.ovsdb.openstack.netvirt.api.Action.ADD)) { - insertLoadBalancerMemberVIPRulesSecondPass(nodeBuilder, lbConfig.getVip(), member); - insertLoadBalancerMemberReverseRules(nodeBuilder, lbConfig.getVip(), member); + manageLoadBalancerMemberVIPRulesSecondPass(nodeBuilder, lbConfig, member, true); + manageLoadBalancerMemberReverseRules(nodeBuilder, lbConfig, member, true); return new Status(StatusCode.SUCCESS); } /* TODO: Delete single member. @@ -115,6 +125,14 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load */ @Override public Status programLoadBalancerRules(Node node, LoadBalancerConfiguration lbConfig, org.opendaylight.ovsdb.openstack.netvirt.api.Action action) { + if (lbConfig == null) { + logger.error("LB config is invalid: {}", lbConfig); + return new Status(StatusCode.BADREQUEST); + } + if (!lbConfig.isValid()) { + logger.error("LB config is invalid: {}", lbConfig); + return new Status(StatusCode.BADREQUEST); + } if (!node.getType().equals(NodeIDType.OPENFLOW)) { logger.trace("Ignoring non-OpenFlow node {} from flow programming", node); return new Status(StatusCode.BADREQUEST); @@ -126,75 +144,43 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load nodeBuilder.setKey(new NodeKey(nodeBuilder.getId())); if (action.equals(org.opendaylight.ovsdb.openstack.netvirt.api.Action.ADD)) { - insertLoadBalancerVIPRulesFirstPass(nodeBuilder, lbConfig); - insertLoadBalancerVIPRulesSecondPass(nodeBuilder, lbConfig); - insertLoadBalancerReverseRules(nodeBuilder, lbConfig); + manageLoadBalancerVIPRulesFirstPass(nodeBuilder, lbConfig, true); + manageLoadBalancerVIPRulesSecondPass(nodeBuilder, lbConfig, true); + manageLoadBalancerReverseRules(nodeBuilder, lbConfig, true); return new Status(StatusCode.SUCCESS); } else if (action.equals(org.opendaylight.ovsdb.openstack.netvirt.api.Action.DELETE)) { - removeLoadBalancerVIPRules(nodeBuilder, lbConfig); - removeLoadBalancerReverseRules(nodeBuilder, lbConfig); + manageLoadBalancerVIPRulesFirstPass(nodeBuilder, lbConfig, false); + manageLoadBalancerVIPRulesSecondPass(nodeBuilder, lbConfig, false); + manageLoadBalancerReverseRules(nodeBuilder, lbConfig, false); return new Status(StatusCode.SUCCESS); } return new Status(StatusCode.NOTIMPLEMENTED); } - private void insertLoadBalancerVIPRulesFirstPass(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig) { + /** + * Method to insert/remove default rule for traffic destined to the VIP and no + * server selection performed yet + * @param nodeBuilder NodeBuilder + * @param lbConfig LoadBalancerConfiguration + * @param write Boolean to indicate of the flow is to be inserted or removed + */ + private void manageLoadBalancerVIPRulesFirstPass(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig, boolean write) { MatchBuilder matchBuilder = new MatchBuilder(); FlowBuilder flowBuilder = new FlowBuilder(); - // Match VIP, and Reg0==0 - MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(lbConfig.getVip())); - MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(REG_FIELD_A, FIRST_PASS_REGA_MATCH_VALUE)); + // Match Tunnel-ID, VIP, and Reg0==0 + if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) || + lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) + MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(lbConfig.getProviderSegmentationId())); + else if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) + MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(lbConfig.getProviderSegmentationId())), true); + else + return; //Should not get here. TODO: Other types - // Create the OF Actions and Instructions - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - List actionList = Lists.newArrayList(); - - ActionBuilder ab = new ActionBuilder(); - ab.setAction(ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(REG_FIELD_A).build(), - BigInteger.valueOf(SECOND_PASS_REGA_MATCH_VALUE))); - ab.setOrder(0); - ab.setKey(new ActionKey(0)); - actionList.add(ab.build()); - - ab = new ActionBuilder(); - ab.setAction(ActionUtils.nxMultipathAction(OfjNxHashFields.NXHASHFIELDSSYMMETRICL4, - 0, OfjNxMpAlgorithm.NXMPALGMODULON, - lbConfig.getMembers().size()-1, //By Nicira-Ext spec, this field is max_link minus 1 - 0L, new DstNxRegCaseBuilder().setNxReg(REG_FIELD_B).build(), - 0, 31)); - ab.setOrder(1); - ab.setKey(new ActionKey(1)); - actionList.add(ab.build()); - - ab = new ActionBuilder(); - ab.setAction(ActionUtils.nxResubmitAction(null, this.getTable())); - ab.setOrder(2); - ab.setKey(new ActionKey(2)); - actionList.add(ab.build()); - - // Create an Apply Action - ApplyActionsBuilder aab = new ApplyActionsBuilder(); - aab.setAction(actionList); - InstructionBuilder ib = new InstructionBuilder(); - ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); - - // Call the InstructionBuilder Methods Containing Actions - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); + MatchUtils.createDstL3IPv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(lbConfig.getVip())); + MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(REG_FIELD_A, FIRST_PASS_REGA_MATCH_VALUE)); String flowId = "LOADBALANCER_FORWARD_FLOW1_" + lbConfig.getVip(); flowBuilder.setId(new FlowId(flowId)); @@ -207,73 +193,95 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load flowBuilder.setFlowName(flowId); flowBuilder.setHardTimeout(0); flowBuilder.setIdleTimeout(0); - writeFlow(flowBuilder, nodeBuilder); + + if (write) { + // Create the OF Actions and Instructions + InstructionsBuilder isb = new InstructionsBuilder(); + + // Instructions List Stores Individual Instructions + List instructions = Lists.newArrayList(); + + List actionList = Lists.newArrayList(); + + ActionBuilder ab = new ActionBuilder(); + ab.setAction(ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(REG_FIELD_A).build(), + BigInteger.valueOf(SECOND_PASS_REGA_MATCH_VALUE))); + ab.setOrder(0); + ab.setKey(new ActionKey(0)); + actionList.add(ab.build()); + + ab = new ActionBuilder(); + ab.setAction(ActionUtils.nxMultipathAction(OfjNxHashFields.NXHASHFIELDSSYMMETRICL4, + 0, OfjNxMpAlgorithm.NXMPALGMODULON, + lbConfig.getMembers().size()-1, //By Nicira-Ext spec, this field is max_link minus 1 + 0L, new DstNxRegCaseBuilder().setNxReg(REG_FIELD_B).build(), + 0, 31)); + ab.setOrder(1); + ab.setKey(new ActionKey(1)); + actionList.add(ab.build()); + + ab = new ActionBuilder(); + ab.setAction(ActionUtils.nxResubmitAction(null, this.getTable())); + ab.setOrder(2); + ab.setKey(new ActionKey(2)); + actionList.add(ab.build()); + + // Create an Apply Action + ApplyActionsBuilder aab = new ApplyActionsBuilder(); + aab.setAction(actionList); + InstructionBuilder ib = new InstructionBuilder(); + ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); + + // Call the InstructionBuilder Methods Containing Actions + ib.setOrder(0); + ib.setKey(new InstructionKey(0)); + instructions.add(ib.build()); + + // Add InstructionBuilder to the Instruction(s)Builder List + isb.setInstruction(instructions); + + // Add InstructionsBuilder to FlowBuilder + flowBuilder.setInstructions(isb.build()); + + writeFlow(flowBuilder, nodeBuilder); + + } else { + removeFlow(flowBuilder, nodeBuilder); + } } /* * Method to program each rule that matches on Reg0 and Reg1 to insert appropriate header rewriting - * rules for all members. This function calls insertLoadBalancerMemberVIPRulesSecondPass in turn. + * rules for all members. This function calls manageLoadBalancerMemberVIPRulesSecondPass in turn. * @param nodeBuilder Node to insert rule to * @param lbConfig Configuration for this LoadBalancer instance + * @param write Boolean to indicate of the flow is to be inserted or removed */ - private void insertLoadBalancerVIPRulesSecondPass(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig) { + private void manageLoadBalancerVIPRulesSecondPass(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig, boolean write) { for(Map.Entry entry : lbConfig.getMembers().entrySet()){ - insertLoadBalancerMemberVIPRulesSecondPass(nodeBuilder, lbConfig.getVip(), entry.getValue()); + manageLoadBalancerMemberVIPRulesSecondPass(nodeBuilder, lbConfig, entry.getValue(), write); } } - private void insertLoadBalancerMemberVIPRulesSecondPass(NodeBuilder nodeBuilder, String vip, LoadBalancerPoolMember member) { + private void manageLoadBalancerMemberVIPRulesSecondPass(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig, LoadBalancerPoolMember member, boolean write) { + String vip = lbConfig.getVip(); + MatchBuilder matchBuilder = new MatchBuilder(); FlowBuilder flowBuilder = new FlowBuilder(); - // Match VIP, Reg0==1 and Reg1==Index of member - MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(vip)); + // Match Tunnel-ID, VIP, Reg0==1 and Reg1==Index of member + if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) || + lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) + MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(lbConfig.getProviderSegmentationId())); + else if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) + MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(lbConfig.getProviderSegmentationId())), true); + else + return; //Should not get here. TODO: Other types + + MatchUtils.createDstL3IPv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(vip)); MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(REG_FIELD_A, SECOND_PASS_REGA_MATCH_VALUE), new MatchUtils.RegMatch(REG_FIELD_B, (long)member.getIndex())); - // Create the OF Actions and Instructions - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - List actionList = Lists.newArrayList(); - ActionBuilder ab = new ActionBuilder(); - ab.setAction(ActionUtils.setDlDstAction(new MacAddress(member.getMAC()))); - ab.setOrder(0); - ab.setKey(new ActionKey(0)); - actionList.add(ab.build()); - - ab = new ActionBuilder(); - Ipv4Builder ipb = new Ipv4Builder().setIpv4Address(new Ipv4Prefix(member.getIP())); - ab.setAction(ActionUtils.setNwDstAction(ipb.build())); - ab.setOrder(1); - ab.setKey(new ActionKey(1)); - actionList.add(ab.build()); - - // Create an Apply Action - ApplyActionsBuilder aab = new ApplyActionsBuilder(); - aab.setAction(actionList); - - // Call the InstructionBuilder Methods Containing Actions - InstructionBuilder ib = new InstructionBuilder(); - ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Call the InstructionBuilder Methods Containing Actions - ib = this.getMutablePipelineInstructionBuilder(); - ib.setOrder(1); - ib.setKey(new InstructionKey(1)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - String flowId = "LOADBALANCER_FORWARD_FLOW2_" + vip + "_" + member.getIP(); flowBuilder.setId(new FlowId(flowId)); FlowKey key = new FlowKey(new FlowId(flowId)); @@ -285,70 +293,90 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load flowBuilder.setFlowName(flowId); flowBuilder.setHardTimeout(0); flowBuilder.setIdleTimeout(0); - writeFlow(flowBuilder, nodeBuilder); + + if (write) { + // Create the OF Actions and Instructions + InstructionsBuilder isb = new InstructionsBuilder(); + + // Instructions List Stores Individual Instructions + List instructions = Lists.newArrayList(); + + List actionList = Lists.newArrayList(); + ActionBuilder ab = new ActionBuilder(); + ab.setAction(ActionUtils.setDlDstAction(new MacAddress(member.getMAC()))); + ab.setOrder(0); + ab.setKey(new ActionKey(0)); + actionList.add(ab.build()); + + ab = new ActionBuilder(); + Ipv4Builder ipb = new Ipv4Builder().setIpv4Address(MatchUtils.iPv4PrefixFromIPv4Address(member.getIP())); + ab.setAction(ActionUtils.setNwDstAction(ipb.build())); + ab.setOrder(1); + ab.setKey(new ActionKey(1)); + actionList.add(ab.build()); + + // Create an Apply Action + ApplyActionsBuilder aab = new ApplyActionsBuilder(); + aab.setAction(actionList); + + // Call the InstructionBuilder Methods Containing Actions + InstructionBuilder ib = new InstructionBuilder(); + ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); + ib.setOrder(0); + ib.setKey(new InstructionKey(0)); + instructions.add(ib.build()); + + // Call the InstructionBuilder Methods Containing Actions + ib = this.getMutablePipelineInstructionBuilder(); + ib.setOrder(1); + ib.setKey(new InstructionKey(1)); + instructions.add(ib.build()); + + // Add InstructionBuilder to the Instruction(s)Builder List + isb.setInstruction(instructions); + + // Add InstructionsBuilder to FlowBuilder + flowBuilder.setInstructions(isb.build()); + + writeFlow(flowBuilder, nodeBuilder); + + } else { + removeFlow(flowBuilder, nodeBuilder); + } } /** * Method to program all reverse rules that matches member {IP, Protocol, Port} for all members. - * This function calls insertLoadBalancerMemberReverseRules in turn. + * This function calls manageLoadBalancerMemberReverseRules in turn. * @param nodeBuilder Node to insert rule to * @param lbConfig Configuration for this LoadBalancer instance */ - private void insertLoadBalancerReverseRules(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig) { + private void manageLoadBalancerReverseRules(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig, boolean write) { for(Map.Entry entry : lbConfig.getMembers().entrySet()){ - insertLoadBalancerMemberReverseRules(nodeBuilder, lbConfig.getVip(), entry.getValue()); + manageLoadBalancerMemberReverseRules(nodeBuilder, lbConfig, entry.getValue(), write); } } - private void insertLoadBalancerMemberReverseRules(NodeBuilder nodeBuilder, String vip, LoadBalancerPoolMember member) { + private void manageLoadBalancerMemberReverseRules(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig, + LoadBalancerPoolMember member, boolean write) { + + String vip = lbConfig.getVip(); + String vmac = lbConfig.getVmac(); + MatchBuilder matchBuilder = new MatchBuilder(); FlowBuilder flowBuilder = new FlowBuilder(); - // Match MemberIP, and Protocol/Port - MatchUtils.createSrcL3IPv4Match(matchBuilder, new Ipv4Prefix(member.getIP())); - if (member.getProtocol().equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP)) - MatchUtils.createSetSrcTcpMatch(matchBuilder, new PortNumber(LoadBalancerConfiguration.PROTOCOL_HTTP_PORT)); - else if (member.getProtocol().equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS)) - MatchUtils.createSetSrcTcpMatch(matchBuilder, new PortNumber(LoadBalancerConfiguration.PROTOCOL_HTTPS_PORT)); - else //Not possible - return; - - // Create the OF Actions and Instructions - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - List actionList = Lists.newArrayList(); - ActionBuilder ab = new ActionBuilder(); - Ipv4Builder ipb = new Ipv4Builder().setIpv4Address(new Ipv4Prefix(vip)); - ab.setAction(ActionUtils.setNwSrcAction(ipb.build())); - ab.setOrder(0); - ab.setKey(new ActionKey(0)); - actionList.add(ab.build()); - - // Create an Apply Action - ApplyActionsBuilder aab = new ApplyActionsBuilder(); - aab.setAction(actionList); - - // Call the InstructionBuilder Methods Containing Actions - InstructionBuilder ib = new InstructionBuilder(); - ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Call the InstructionBuilder Methods Containing Actions - ib = this.getMutablePipelineInstructionBuilder(); - ib.setOrder(1); - ib.setKey(new InstructionKey(1)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); + // Match Tunnel-ID, MemberIP, and Protocol/Port + if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) || + lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) + MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(lbConfig.getProviderSegmentationId())); + else if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) + MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(lbConfig.getProviderSegmentationId())), true); + else + return; //Should not get here. TODO: Other types + + MatchUtils.createSrcL3IPv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(member.getIP())); + MatchUtils.createSetSrcTcpMatch(matchBuilder, new PortNumber(member.getPort())); String flowId = "LOADBALANCER_REVERSE_FLOW_" + vip + "_" + member.getIP(); flowBuilder.setId(new FlowId(flowId)); @@ -361,78 +389,59 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load flowBuilder.setFlowName(flowId); flowBuilder.setHardTimeout(0); flowBuilder.setIdleTimeout(0); - writeFlow(flowBuilder, nodeBuilder); - } - /** - * Method to remove all rules that are regarding traffic destined to the VIP - * (both first and second pass rules) - * @param nodeBuilder NodeBuilder - * @param lbConfig LoadBalancerConfiguration - */ - private void removeLoadBalancerVIPRules(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig) { - MatchBuilder matchBuilder = new MatchBuilder(); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Match all first pass rules - MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(lbConfig.getVip())); - MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(REG_FIELD_A, FIRST_PASS_REGA_MATCH_VALUE)); - - flowBuilder.setMatch(matchBuilder.build()); - String flowId = "LOADBALANCER_FORWARD_FLOW1_" + lbConfig.getVip(); - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY); - flowBuilder.setBarrier(true); - flowBuilder.setTableId(this.getTable()); - flowBuilder.setKey(key); - removeFlow(flowBuilder, nodeBuilder); - - // Match all second pass rules - for(Map.Entry entry : lbConfig.getMembers().entrySet()){ - LoadBalancerPoolMember member = entry.getValue(); - MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(REG_FIELD_A, SECOND_PASS_REGA_MATCH_VALUE), - new MatchUtils.RegMatch(REG_FIELD_B, (long)member.getIndex())); - MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(lbConfig.getVip())); - - flowBuilder.setMatch(matchBuilder.build()); - flowId = "LOADBALANCER_FORWARD_FLOW2_" + lbConfig.getVip() + "_" + member.getIP(); - flowBuilder.setId(new FlowId(flowId)); - key = new FlowKey(new FlowId(flowId)); - flowBuilder.setKey(key); - removeFlow(flowBuilder, nodeBuilder); - } - } - - /** - * Method to remove all reverse traffic from LB member VMs - * @param nodeBuilder NodeBuilder - * @param lbConfig LoadBalancerConfiguration - */ - private void removeLoadBalancerReverseRules(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig) { - for(Map.Entry entry : lbConfig.getMembers().entrySet()){ - LoadBalancerPoolMember member = entry.getValue(); - - MatchBuilder matchBuilder = new MatchBuilder(); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Match MemberIP, and Protocol/Port - MatchUtils.createSrcL3IPv4Match(matchBuilder, new Ipv4Prefix(member.getIP())); - if (member.getProtocol().equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP)) - MatchUtils.createSetSrcTcpMatch(matchBuilder, new PortNumber(LoadBalancerConfiguration.PROTOCOL_HTTP_PORT)); - else if (member.getProtocol().equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS)) - MatchUtils.createSetSrcTcpMatch(matchBuilder, new PortNumber(LoadBalancerConfiguration.PROTOCOL_HTTPS_PORT)); - else //Not possible - return; - - String flowId = "LOADBALANCER_REVERSE_FLOW_" + lbConfig.getVip() + "_" + member.getIP(); - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setMatch(matchBuilder.build()); - flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY); - flowBuilder.setBarrier(true); - flowBuilder.setTableId(this.getTable()); - flowBuilder.setKey(key); + if (write) { + // Create the OF Actions and Instructions + InstructionsBuilder isb = new InstructionsBuilder(); + + // Instructions List Stores Individual Instructions + List instructions = Lists.newArrayList(); + + List actionList = Lists.newArrayList(); + ActionBuilder ab = new ActionBuilder(); + Ipv4Builder ipb = new Ipv4Builder().setIpv4Address(MatchUtils.iPv4PrefixFromIPv4Address(vip)); + ab.setAction(ActionUtils.setNwSrcAction(ipb.build())); + ab.setOrder(0); + ab.setKey(new ActionKey(0)); + actionList.add(ab.build()); + + /* If a dummy MAC is assigned to the VIP, we use that as the + * source MAC for the reverse traffic. + */ + if (vmac != null) { + ab = new ActionBuilder(); + ab.setAction(ActionUtils.setDlDstAction(new MacAddress(vmac))); + ab.setOrder(1); + ab.setKey(new ActionKey(1)); + actionList.add(ab.build()); + } + + // Create an Apply Action + ApplyActionsBuilder aab = new ApplyActionsBuilder(); + aab.setAction(actionList); + + // Call the InstructionBuilder Methods Containing Actions + InstructionBuilder ib = new InstructionBuilder(); + ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); + ib.setOrder(0); + ib.setKey(new InstructionKey(0)); + instructions.add(ib.build()); + + // Call the InstructionBuilder Methods Containing Actions + ib = this.getMutablePipelineInstructionBuilder(); + ib.setOrder(1); + ib.setKey(new InstructionKey(1)); + instructions.add(ib.build()); + + // Add InstructionBuilder to the Instruction(s)Builder List + isb.setInstruction(instructions); + + // Add InstructionsBuilder to FlowBuilder + flowBuilder.setInstructions(isb.build()); + + writeFlow(flowBuilder, nodeBuilder); + + } else { removeFlow(flowBuilder, nodeBuilder); } }