From: Madhu Venugopal Date: Wed, 24 Sep 2014 20:55:44 +0000 (+0000) Subject: Merge "Bug 1806 - Null destination InetAddress in OF13Provider.handleInterfaceUpdate" X-Git-Tag: release/helium~3 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=09d1d27d6276a7fa542e43f2381e3ef95b610c1c;hp=085a381c399116afc4c68699d7c1564d2cbc5aab;p=ovsdb.git Merge "Bug 1806 - Null destination InetAddress in OF13Provider.handleInterfaceUpdate" --- diff --git a/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/ArpResponderService.java b/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/ArpResponderService.java index fb431ae65..700c579a2 100644 --- a/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/ArpResponderService.java +++ b/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/ArpResponderService.java @@ -24,6 +24,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.OF13Provide import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service; import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils; import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey; @@ -72,6 +73,7 @@ public class ArpResponderService extends AbstractServiceInstance implements ArpP MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)); MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(Constants.ARP_ETHERTYPE)); + MatchUtils.createArpDstIpv4Match(matchBuilder, new Ipv4Prefix(ipAddress.getHostAddress())); // Move Eth Src to Eth Dst ab.setAction(ActionUtils.nxMoveEthSrcToEthDstAction()); 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 261a95fba..a6ebf1b22 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,6 +46,7 @@ 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; @@ -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,76 +144,44 @@ 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 + // 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 + MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(lbConfig.getVip())); MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(REG_FIELD_A, FIRST_PASS_REGA_MATCH_VALUE)); - // 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()); - String flowId = "LOADBALANCER_FORWARD_FLOW1_" + lbConfig.getVip(); flowBuilder.setId(new FlowId(flowId)); FlowKey key = new FlowKey(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 + // 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, new Ipv4Prefix(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(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()); + + 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 + // 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, 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()); + 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(new Ipv4Prefix(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); } } diff --git a/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/RoutingService.java b/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/RoutingService.java index 592518685..677746e45 100644 --- a/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/RoutingService.java +++ b/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/RoutingService.java @@ -53,7 +53,7 @@ public class RoutingService extends AbstractServiceInstance implements RoutingPr } @Override - public Status programRouterInterface(Node node, Long dpid, String segmentationId, String macAddress, + public Status programRouterInterface(Node node, Long dpid, String sourceSegId, String destSegId, String macAddress, InetAddress address, int mask, Action action) { String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid; @@ -70,7 +70,7 @@ public class RoutingService extends AbstractServiceInstance implements RoutingPr List actionList = Lists.newArrayList(); String prefixString = address.getHostAddress() + "/" + mask; - MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)); + MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(sourceSegId)); MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(prefixString)); // Set source Mac address @@ -85,6 +85,12 @@ public class RoutingService extends AbstractServiceInstance implements RoutingPr ab.setKey(new ActionKey(1)); actionList.add(ab.build()); + // Set Destination Tunnel ID + ab.setAction(ActionUtils.setTunnelIdAction(new BigInteger(destSegId))); + ab.setOrder(2); + ab.setKey(new ActionKey(2)); + actionList.add(ab.build()); + // Create Apply Actions Instruction aab.setAction(actionList); ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); @@ -94,8 +100,8 @@ public class RoutingService extends AbstractServiceInstance implements RoutingPr // Goto Next Table ib = getMutablePipelineInstructionBuilder(); - ib.setOrder(1); - ib.setKey(new InstructionKey(1)); + ib.setOrder(2); + ib.setKey(new InstructionKey(2)); instructions.add(ib.build()); FlowBuilder flowBuilder = new FlowBuilder(); diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/Activator.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/Activator.java index 48bc3fd14..3767a5a65 100644 --- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/Activator.java +++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/Activator.java @@ -261,6 +261,8 @@ public class Activator extends ComponentActivatorAbstractBase { c.add(createServiceDependency().setService(INeutronLoadBalancerPoolCRUD.class).setRequired(true)); c.add(createServiceDependency().setService(LoadBalancerProvider.class).setRequired(true)); c.add(createServiceDependency().setService(ISwitchManager.class).setRequired(true)); + c.add(createServiceDependency().setService(INeutronNetworkCRUD.class).setRequired(true)); + c.add(createServiceDependency().setService(INeutronSubnetCRUD.class).setRequired(true)); } if (imp.equals(LBaaSPoolHandler.class)) { @@ -273,9 +275,10 @@ public class Activator extends ComponentActivatorAbstractBase { c.add(createServiceDependency().setService(EventDispatcher.class).setRequired(true)); c.add(createServiceDependency().setService(INeutronPortCRUD.class).setRequired(true)); c.add(createServiceDependency().setService(INeutronLoadBalancerCRUD.class).setRequired(true)); - c.add(createServiceDependency().setService(INeutronLoadBalancerPoolCRUD.class).setRequired(true)); c.add(createServiceDependency().setService(LoadBalancerProvider.class).setRequired(true)); c.add(createServiceDependency().setService(ISwitchManager.class).setRequired(true)); + c.add(createServiceDependency().setService(INeutronNetworkCRUD.class).setRequired(true)); + c.add(createServiceDependency().setService(INeutronSubnetCRUD.class).setRequired(true)); } if (imp.equals(LBaaSPoolMemberHandler.class)) { @@ -291,6 +294,8 @@ public class Activator extends ComponentActivatorAbstractBase { c.add(createServiceDependency().setService(INeutronLoadBalancerPoolCRUD.class).setRequired(true)); c.add(createServiceDependency().setService(LoadBalancerProvider.class).setRequired(true)); c.add(createServiceDependency().setService(ISwitchManager.class).setRequired(true)); + c.add(createServiceDependency().setService(INeutronNetworkCRUD.class).setRequired(true)); + c.add(createServiceDependency().setService(INeutronSubnetCRUD.class).setRequired(true)); } if (imp.equals(PortSecurityHandler.class)) { diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSHandler.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSHandler.java index 10783851d..b958113a6 100644 --- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSHandler.java +++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSHandler.java @@ -13,7 +13,9 @@ package org.opendaylight.ovsdb.openstack.netvirt; import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerAware; import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD; import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer; import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool; import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember; @@ -50,6 +52,8 @@ public class LBaaSHandler extends AbstractHandler private volatile INeutronLoadBalancerCRUD neutronLBCache; private volatile INeutronLoadBalancerPoolCRUD neutronLBPoolCache; private volatile INeutronPortCRUD neutronPortsCache; + private volatile INeutronNetworkCRUD neutronNetworkCache; + private volatile INeutronSubnetCRUD neutronSubnetCache; private volatile LoadBalancerProvider loadBalancerProvider; private volatile ISwitchManager switchManager; @@ -165,7 +169,14 @@ public class LBaaSHandler extends AbstractHandler String loadBalancerName = neutronLB.getLoadBalancerName(); String loadBalancerVip = neutronLB.getLoadBalancerVipAddress(); String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID(); + LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip); + Map.Entry providerInfo = NeutronCacheUtils.getProviderInformation(neutronNetworkCache, neutronSubnetCache, loadBalancerSubnetID); + if (providerInfo != null) { + lbConfig.setProviderNetworkType(providerInfo.getKey()); + lbConfig.setProviderSegmentationId(providerInfo.getValue()); + } + lbConfig.setVmac(NeutronCacheUtils.getMacAddress(neutronPortsCache, loadBalancerVip)); String memberID, memberIP, memberMAC, memberProtocol, memberSubnetID; Integer memberPort; @@ -176,11 +187,9 @@ public class LBaaSHandler extends AbstractHandler memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol(); if (memberProtocol == null) continue; - /* - * Only HTTP and HTTPS are supported as of this version - * TODO: Support all TCP load-balancers - */ - if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) || + + if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_TCP) || + memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) || memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS))) continue; for (NeutronLoadBalancerPoolMember neutronLBPoolMember: members) { diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolHandler.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolHandler.java index f745a4b54..fb86650a5 100755 --- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolHandler.java +++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolHandler.java @@ -12,8 +12,9 @@ package org.opendaylight.ovsdb.openstack.netvirt; import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolAware; -import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD; import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer; import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool; import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember; @@ -30,6 +31,7 @@ import com.google.common.collect.Lists; import java.net.HttpURLConnection; import java.util.List; +import java.util.Map; /** * Handle requests for OpenStack Neutron v2.0 LBaaS API calls for @@ -43,9 +45,10 @@ public class LBaaSPoolHandler extends AbstractHandler private static final Logger logger = LoggerFactory.getLogger(LBaaSPoolHandler.class); // The implementation for each of these services is resolved by the OSGi Service Manager - private volatile INeutronLoadBalancerPoolCRUD neutronLBPoolCache; private volatile INeutronLoadBalancerCRUD neutronLBCache; private volatile INeutronPortCRUD neutronPortsCache; + private volatile INeutronNetworkCRUD neutronNetworkCache; + private volatile INeutronSubnetCRUD neutronSubnetCache; private volatile LoadBalancerProvider loadBalancerProvider; private volatile ISwitchManager switchManager; @@ -54,7 +57,8 @@ public class LBaaSPoolHandler extends AbstractHandler String poolProtocol = neutronLBPool.getLoadBalancerPoolProtocol(); if (poolProtocol == null) return HttpURLConnection.HTTP_BAD_REQUEST; - else if (!(poolProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) || + else if (!(poolProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_TCP) || + poolProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) || poolProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS))) return HttpURLConnection.HTTP_NOT_ACCEPTABLE; else @@ -110,7 +114,8 @@ public class LBaaSPoolHandler extends AbstractHandler String poolProtocol = neutronLBPool.getLoadBalancerPoolProtocol(); if (poolProtocol == null) return HttpURLConnection.HTTP_BAD_REQUEST; - else if (!(poolProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) || + else if (!(poolProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_TCP) || + poolProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) || poolProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS))) return HttpURLConnection.HTTP_NOT_ACCEPTABLE; else @@ -207,7 +212,14 @@ public class LBaaSPoolHandler extends AbstractHandler loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID(); loadBalancerName = neutronLB.getLoadBalancerName(); loadBalancerVip = neutronLB.getLoadBalancerVipAddress(); + LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip); + Map.Entry providerInfo = NeutronCacheUtils.getProviderInformation(neutronNetworkCache, neutronSubnetCache, loadBalancerSubnetID); + if (providerInfo != null) { + lbConfig.setProviderNetworkType(providerInfo.getKey()); + lbConfig.setProviderSegmentationId(providerInfo.getValue()); + } + lbConfig.setVmac(NeutronCacheUtils.getMacAddress(neutronPortsCache, loadBalancerVip)); /* Iterate over all the members in this pool and find those in same * subnet as the VIP. Those will be included in the lbConfigList diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandler.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandler.java index e9c0ed38c..bb3d9a0e4 100755 --- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandler.java +++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandler.java @@ -13,7 +13,9 @@ package org.opendaylight.ovsdb.openstack.netvirt; import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolMemberAware; +import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD; import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer; import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool; import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember; @@ -28,6 +30,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; import java.net.HttpURLConnection; +import java.util.Map; /** * Handle requests for OpenStack Neutron v2.0 LBaaS API calls for @@ -43,6 +46,8 @@ public class LBaaSPoolMemberHandler extends AbstractHandler private volatile INeutronLoadBalancerPoolCRUD neutronLBPoolCache; private volatile INeutronLoadBalancerCRUD neutronLBCache; private volatile INeutronPortCRUD neutronPortsCache; + private volatile INeutronNetworkCRUD neutronNetworkCache; + private volatile INeutronSubnetCRUD neutronSubnetCache; private volatile LoadBalancerProvider loadBalancerProvider; private volatile ISwitchManager switchManager; @@ -198,7 +203,8 @@ public class LBaaSPoolMemberHandler extends AbstractHandler } NeutronLoadBalancerPool neutronLBPool = neutronLBPoolCache.getNeutronLoadBalancerPool(memberPoolID); memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol(); - if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) || + if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_TCP) || + memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) || memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS))) return null; @@ -217,6 +223,12 @@ public class LBaaSPoolMemberHandler extends AbstractHandler * In that case, we create dummy configuration that will not program rules. */ LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip); + Map.Entry providerInfo = NeutronCacheUtils.getProviderInformation(neutronNetworkCache, neutronSubnetCache, memberSubnetID); + if (providerInfo != null) { + lbConfig.setProviderNetworkType(providerInfo.getKey()); + lbConfig.setProviderSegmentationId(providerInfo.getValue()); + } + lbConfig.setVmac(NeutronCacheUtils.getMacAddress(neutronPortsCache, loadBalancerVip)); /* Extract all other active members and include in LB config */ diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NeutronCacheUtils.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NeutronCacheUtils.java index 9f0984a94..bed81ab6d 100755 --- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NeutronCacheUtils.java +++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NeutronCacheUtils.java @@ -10,11 +10,18 @@ package org.opendaylight.ovsdb.openstack.netvirt; +import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD; +import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; import org.opendaylight.controller.networkconfig.neutron.NeutronPort; +import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet; import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs; + +import java.util.AbstractMap; import java.util.Iterator; import java.util.List; +import java.util.Map; public class NeutronCacheUtils { @@ -47,4 +54,36 @@ public class NeutronCacheUtils { } return null; } + + /** + * Look up in the NeutronNetworkCRUD cache and NeutronSubnetCRUD cache for + * extracting the provider segmentation_type and segmentation_id + * @param subnetId Subnet UUID + * @return {Type: ID} pair for that subnet ID + */ + public static Map.Entry getProviderInformation(INeutronNetworkCRUD neutronNetworkCache, + INeutronSubnetCRUD neutronSubnetCache, String subnetID) { + + String networkID = null; + + List allSubnets = neutronSubnetCache.getAllSubnets(); + for (NeutronSubnet subnet: allSubnets) { + if (subnet.getID().equals(subnetID)) { + networkID = subnet.getNetworkUUID(); + break; + } + } + if (networkID == null) + return null; + + List allNetworks = neutronNetworkCache.getAllNetworks(); + for (NeutronNetwork network: allNetworks) { + if (network.getID().equals(networkID)) { + Map.Entry entry = new AbstractMap.SimpleEntry( + network.getProviderNetworkType(), network.getProviderSegmentationID()); + return entry; + } + } + return null; + } } diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/LoadBalancerConfiguration.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/LoadBalancerConfiguration.java index 7965a9e96..e34320ec9 100755 --- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/LoadBalancerConfiguration.java +++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/LoadBalancerConfiguration.java @@ -19,10 +19,9 @@ import java.util.Map; */ public class LoadBalancerConfiguration { + public static final String PROTOCOL_TCP = "TCP"; public static final String PROTOCOL_HTTP = "HTTP"; public static final String PROTOCOL_HTTPS = "HTTPS"; - public static final Integer PROTOCOL_HTTP_PORT = 80; - public static final Integer PROTOCOL_HTTPS_PORT = 443; public class LoadBalancerPoolMember { String ipAddr; @@ -97,6 +96,9 @@ public class LoadBalancerConfiguration { private String name; private String vip; + private String vmac; //Used when a dummy neutron port is created for the VIP + private String providerNetworkType; + private String providerSegmentationId; private Map members; public LoadBalancerConfiguration() { @@ -107,12 +109,21 @@ public class LoadBalancerConfiguration { this.members = Maps.newHashMap(); this.name = name; this.vip = vip; + this.vmac = null; + } + + public LoadBalancerConfiguration(String name, String vip, String vmac) { + this.members = Maps.newHashMap(); + this.name = name; + this.vip = vip; + this.vmac = vmac; } public LoadBalancerConfiguration(LoadBalancerConfiguration lbConfig) { this.members = Maps.newHashMap(lbConfig.getMembers()); this.name = lbConfig.getName(); this.vip = lbConfig.getVip(); + this.vmac = lbConfig.getVmac(); } public Map getMembers() { @@ -144,8 +155,11 @@ public class LoadBalancerConfiguration { public boolean isValid() { if (members.size() == 0) return false; + else if (providerNetworkType == null) + return false; return true; } + public void setVip(String vip) { this.vip = vip; } @@ -154,6 +168,14 @@ public class LoadBalancerConfiguration { return this.vip; } + public void setVmac(String vmac) { + this.vmac = vmac; + } + + public String getVmac() { + return this.vmac; + } + public void setName(String name) { this.name = name; } @@ -162,9 +184,27 @@ public class LoadBalancerConfiguration { return this.name; } + public void setProviderSegmentationId(String providerSegmentationId) { + this.providerSegmentationId = providerSegmentationId; + } + + public String getProviderSegmentationId() { + return this.providerSegmentationId; + } + public void setProviderNetworkType(String providerNetworkType) { + this.providerNetworkType = providerNetworkType; + } + + public String getProviderNetworkType() { + return this.providerNetworkType; + } + @Override public String toString() { - return "LoadBalancerConfiguration [name=" + name + ", vip=" + vip + + return "LoadBalancerConfiguration [name=" + name + + ", vip=" + vip + ", vmac=" + vmac + + ", networkType=" + providerNetworkType + + ", segmentationId=" + providerSegmentationId + ", members=" + members + "]"; } } diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/RoutingProvider.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/RoutingProvider.java index 18b3f3150..0903bbbc4 100644 --- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/RoutingProvider.java +++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/RoutingProvider.java @@ -20,7 +20,7 @@ import java.net.InetAddress; */ public interface RoutingProvider { - Status programRouterInterface(Node node, Long dpid, String segmentationId, String macAddress, + Status programRouterInterface(Node node, Long dpid, String srcSegId, String dstSegId, String macAddress, InetAddress address, int mask, Action action); Status programDefaultRouteEntry(Node node, Long dpid, String segmentationId, String macAddress, diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3Adapter.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3Adapter.java index e596b31a0..cc9aeb44e 100644 --- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3Adapter.java +++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3Adapter.java @@ -358,45 +358,42 @@ public class NeutronL3Adapter { // -- - private void programFlowsForNeutronRouterInterface(final NeutronRouter_Interface neutronRouterInterface, + private void programFlowsForNeutronRouterInterface(final NeutronRouter_Interface destNeutronRouterInterface, Boolean isDelete) { - Preconditions.checkNotNull(neutronRouterInterface); + Preconditions.checkNotNull(destNeutronRouterInterface); - final NeutronPort neutronPort = neutronPortCache.getPort(neutronRouterInterface.getPortUUID()); + final NeutronPort neutronPort = neutronPortCache.getPort(destNeutronRouterInterface.getPortUUID()); final String macAddress = neutronPort != null ? neutronPort.getMacAddress() : null; final List ipList = neutronPort != null ? neutronPort.getFixedIPs() : null; - final NeutronSubnet subnet = neutronSubnetCache.getSubnet(neutronRouterInterface.getSubnetUUID()); + final NeutronSubnet subnet = neutronSubnetCache.getSubnet(destNeutronRouterInterface.getSubnetUUID()); final NeutronNetwork neutronNetwork = subnet != null ? neutronNetworkCache.getNetwork(subnet.getNetworkUUID()) : null; - final String providerSegmentationId = neutronNetwork != null ? - neutronNetwork.getProviderSegmentationID() : null; + final String destinationSegmentationId = neutronNetwork != null ? + neutronNetwork.getProviderSegmentationID() : null; final String gatewayIp = subnet != null ? subnet.getGatewayIP() : null; final Boolean isExternal = neutronNetwork != null ? neutronNetwork.getRouterExternal() : Boolean.TRUE; final String cidr = subnet != null ? subnet.getCidr() : null; final int mask = getMaskLenFromCidr(cidr); logger.trace("programFlowsForNeutronRouterInterface called for interface {} isDelete {}", - neutronRouterInterface, isDelete); + destNeutronRouterInterface, isDelete); - if (providerSegmentationId == null || providerSegmentationId.isEmpty() || + if (destinationSegmentationId == null || destinationSegmentationId.isEmpty() || cidr == null || cidr.isEmpty() || macAddress == null || macAddress.isEmpty() || ipList == null || ipList.isEmpty()) { logger.debug("programFlowsForNeutronRouterInterface is bailing seg:{} cidr:{} mac:{} ip:{}", - providerSegmentationId, cidr, macAddress, ipList); + destinationSegmentationId, cidr, macAddress, ipList); return; // done: go no further w/out all the info needed... } final Action action = isDelete ? Action.DELETE : Action.ADD; - // Keep cache for finding router's mac from network uuid + // Keep cache for finding router's mac from network uuid -- add // - if (isDelete) { - networkIdToRouterMacCache.remove(neutronNetwork.getNetworkUUID()); - subnetIdToRouterInterfaceCache.remove(subnet.getSubnetUUID()); - } else { + if (! isDelete) { networkIdToRouterMacCache.put(neutronNetwork.getNetworkUUID(), macAddress); - subnetIdToRouterInterfaceCache.put(subnet.getSubnetUUID(), neutronRouterInterface); + subnetIdToRouterInterfaceCache.put(subnet.getSubnetUUID(), destNeutronRouterInterface); } List nodes = connectionService.getNodes(); @@ -406,7 +403,7 @@ public class NeutronL3Adapter { for (Node node : nodes) { final Long dpid = getDpid(node); final Action actionForNode = - tenantNetworkManager.isTenantNetworkPresentInNode(node, providerSegmentationId) ? + tenantNetworkManager.isTenantNetworkPresentInNode(node, destinationSegmentationId) ? action : Action.DELETE; for (Neutron_IPs neutronIP : ipList) { @@ -416,8 +413,18 @@ public class NeutronL3Adapter { node.getID(), ipStr); continue; } - programRouterInterfaceStage1(node, dpid, providerSegmentationId, macAddress, ipStr, mask, actionForNode); - programStaticArpStage1(node, dpid, providerSegmentationId, macAddress, ipStr, actionForNode); + + // Iterate through all other interfaces and add/remove reflexive flows to this interface + // + for (NeutronRouter_Interface srcNeutronRouterInterface : subnetIdToRouterInterfaceCache.values()) { + programFlowsForNeutronRouterInterfacePair(node, dpid, + srcNeutronRouterInterface, destNeutronRouterInterface, + neutronNetwork, destinationSegmentationId, + macAddress, ipStr, mask, actionForNode, + true /*isReflexsive*/); + } + + programStaticArpStage1(node, dpid, destinationSegmentationId, macAddress, ipStr, actionForNode); } // Compute action to be programmed. In the case of rewrite exclusions, we must never program rules @@ -425,9 +432,9 @@ public class NeutronL3Adapter { // { final Action actionForRewriteExclusion = isExternal ? Action.DELETE : actionForNode; - programIpRewriteExclusionStage1(node, dpid, providerSegmentationId, true /* isInbound */, + programIpRewriteExclusionStage1(node, dpid, destinationSegmentationId, true /* isInbound */, cidr, actionForRewriteExclusion); - programIpRewriteExclusionStage1(node, dpid, providerSegmentationId, false /* isInbound */, + programIpRewriteExclusionStage1(node, dpid, destinationSegmentationId, false /* isInbound */, cidr, actionForRewriteExclusion); } @@ -437,36 +444,127 @@ public class NeutronL3Adapter { final Action actionForNodeDefaultRoute = isExternal ? actionForNode : Action.DELETE; final String defaultGatewayMacAddress = configurationService.getDefaultGatewayMacAddress(node); - programDefaultRouteStage1(node, dpid, providerSegmentationId, defaultGatewayMacAddress, gatewayIp, + programDefaultRouteStage1(node, dpid, destinationSegmentationId, defaultGatewayMacAddress, gatewayIp, actionForNodeDefaultRoute); } } + + // Keep cache for finding router's mac from network uuid -- remove + // + if (isDelete) { + networkIdToRouterMacCache.remove(neutronNetwork.getNetworkUUID()); + subnetIdToRouterInterfaceCache.remove(subnet.getSubnetUUID()); + } + } + + private void programFlowsForNeutronRouterInterfacePair(final Node node, + final Long dpid, + final NeutronRouter_Interface srcNeutronRouterInterface, + final NeutronRouter_Interface dstNeutronRouterInterface, + final NeutronNetwork dstNeutronNetwork, + final String destinationSegmentationId, + final String dstMacAddress, + final String destIpStr, + final int destMask, + final Action actionForNode, + Boolean isReflexsive) { + Preconditions.checkNotNull(srcNeutronRouterInterface); + Preconditions.checkNotNull(dstNeutronRouterInterface); + + final String sourceSubnetId = srcNeutronRouterInterface.getSubnetUUID(); + if (sourceSubnetId == null) { + logger.error("Could not get provider Subnet ID from router interface {}", + srcNeutronRouterInterface.getID()); + return; + } + + final NeutronSubnet sourceSubnet = neutronSubnetCache.getSubnet(sourceSubnetId); + final String sourceNetworkId = sourceSubnet == null ? null : sourceSubnet.getNetworkUUID(); + if (sourceNetworkId == null) { + logger.error("Could not get provider Network ID from subnet {}", sourceSubnetId); + return; + } + + final NeutronNetwork sourceNetwork = neutronNetworkCache.getNetwork(sourceNetworkId); + if (sourceNetwork == null) { + logger.error("Could not get provider Network for Network ID {}", sourceNetworkId); + return; + } + + if (! sourceNetwork.getTenantID().equals(dstNeutronNetwork.getTenantID())) { + // Isolate subnets from different tenants within the same router + return; + } + final String sourceSegmentationId = sourceNetwork.getProviderSegmentationID(); + if (sourceSegmentationId == null) { + logger.error("Could not get provider Segmentation ID for Subnet {}", sourceSubnetId); + return; + } + if (sourceSegmentationId.equals(destinationSegmentationId)) { + // Skip 'self' + return; + } + + programRouterInterfaceStage1(node, dpid, sourceSegmentationId, destinationSegmentationId, + dstMacAddress, destIpStr, destMask, actionForNode); + + // Flip roles src->dst; dst->src + if (isReflexsive) { + final NeutronPort sourceNeutronPort = neutronPortCache.getPort(srcNeutronRouterInterface.getPortUUID()); + final String macAddress2 = sourceNeutronPort != null ? sourceNeutronPort.getMacAddress() : null; + final List ipList2 = sourceNeutronPort != null ? sourceNeutronPort.getFixedIPs() : null; + final String cidr2 = sourceSubnet.getCidr(); + final int mask2 = getMaskLenFromCidr(cidr2); + + if (cidr2 == null || cidr2.isEmpty() || + macAddress2 == null || macAddress2.isEmpty() || + ipList2 == null || ipList2.isEmpty()) { + logger.trace("programFlowsForNeutronRouterInterfacePair reflexive is bailing seg:{} cidr:{} mac:{} ip:{}", + sourceSegmentationId, cidr2, macAddress2, ipList2); + return; // done: go no further w/out all the info needed... + } + + for (Neutron_IPs neutronIP2 : ipList2) { + final String ipStr2 = neutronIP2.getIpAddress(); + if (ipStr2.isEmpty()) { + continue; + } + programFlowsForNeutronRouterInterfacePair(node, dpid, dstNeutronRouterInterface, + srcNeutronRouterInterface, + sourceNetwork, sourceSegmentationId, + macAddress2, ipStr2, mask2, actionForNode, + false /*isReflexsive*/); + } + } } - private void programRouterInterfaceStage1(Node node, Long dpid, String providerSegmentationId, + private void programRouterInterfaceStage1(Node node, Long dpid, String sourceSegmentationId, + String destinationSegmentationId, String macAddress, String ipStr, int mask, Action actionForNode) { // Based on the local cache, figure out whether programming needs to occur. To do this, we // will look at desired action for node. // - final String cacheKey = node.toString() + ":" + providerSegmentationId + ":" + + final String cacheKey = node.toString() + ":" + sourceSegmentationId + ":" + destinationSegmentationId + ":" + ipStr + "/" + Integer.toString(mask); final Boolean isProgrammed = routerInterfacesCache.contains(cacheKey); if (actionForNode == Action.DELETE && isProgrammed == Boolean.FALSE) { - logger.trace("programRouterInterfaceStage1 for node {} providerId {} mac {} ip {} mask {} action {}" + - " is already done", - node.getNodeIDString(), providerSegmentationId, macAddress, ipStr, mask, actionForNode); + logger.trace("programRouterInterfaceStage1 for node {} sourceSegId {} destSegId {} mac {} ip {} mask {}" + + "action {} is already done", + node.getNodeIDString(), sourceSegmentationId, destinationSegmentationId, + ipStr, mask, actionForNode); return; } if (actionForNode == Action.ADD && isProgrammed == Boolean.TRUE) { - logger.trace("programRouterInterfaceStage1 for node {} providerId {} mac {} ip {} mask {} action {}" + - " is already done", - node.getNodeIDString(), providerSegmentationId, macAddress, ipStr, mask, actionForNode); + logger.trace("programRouterInterfaceStage1 for node {} sourceSegId {} destSegId {} mac {} ip {} mask {}" + + "action {} is already done", + node.getNodeIDString(), sourceSegmentationId, destinationSegmentationId, + ipStr, mask, actionForNode); return; } - Status status = this.programRouterInterfaceStage2(node, dpid, providerSegmentationId, + Status status = this.programRouterInterfaceStage2(node, dpid, sourceSegmentationId, destinationSegmentationId, macAddress, ipStr, mask, actionForNode); if (status.isSuccess()) { // Update cache @@ -480,7 +578,8 @@ public class NeutronL3Adapter { } } - private Status programRouterInterfaceStage2(Node node, Long dpid, String providerSegmentationId, + private Status programRouterInterfaceStage2(Node node, Long dpid, String sourceSegmentationId, + String destinationSegmentationId, String macAddress, String address, int mask, Action actionForNode) { @@ -489,7 +588,7 @@ public class NeutronL3Adapter { InetAddress inetAddress = InetAddress.getByName(address); status = routingProvider == null ? new Status(StatusCode.SUCCESS) : - routingProvider.programRouterInterface(node, dpid, providerSegmentationId, + routingProvider.programRouterInterface(node, dpid, sourceSegmentationId, destinationSegmentationId, macAddress, inetAddress, mask, actionForNode); } catch (UnknownHostException e) { status = new Status(StatusCode.BADREQUEST); diff --git a/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/ActionUtils.java b/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/ActionUtils.java index 51c9b41f6..7e50f6a91 100644 --- a/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/ActionUtils.java +++ b/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/ActionUtils.java @@ -19,6 +19,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder; @@ -28,10 +29,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpShaCaseBuilder; @@ -150,6 +153,20 @@ public final class ActionUtils { .build(); } + public static Action setTunnelIdAction(BigInteger tunnelId) { + + SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); + + // Build the Set Tunnel Field Action + TunnelBuilder tunnel = new TunnelBuilder(); + tunnel.setTunnelId(tunnelId); + setFieldBuilder.setTunnel(tunnel.build()); + + return new SetFieldCaseBuilder() + .setSetField(setFieldBuilder.build()) + .build(); + } + public static Action nxLoadRegAction(DstChoice dstChoice, BigInteger value, int endOffset, diff --git a/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtils.java b/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtils.java index 42e0adcd5..08c5987a0 100644 --- a/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtils.java +++ b/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtils.java @@ -13,6 +13,7 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; @@ -31,6 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TcpFlagMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder; @@ -61,6 +63,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxTunIdKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.tun.id.grouping.NxmNxTunIdBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.arp.tpa.grouping.NxmOfArpTpaBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.ovs.nx.sal.match.rev140714.NxmNxNspKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.ovs.nx.sal.match.rev140714.nxm.nx.nsp.grouping.NxmNxNspBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.ovs.nx.sal.match.rev140714.NxmNxNsiKey; @@ -241,6 +244,19 @@ public class MatchUtils { } + /** + * @param matchBuilder MatchBuilder Object without a match yet + * @param dstip String containing an IPv4 prefix + * @return matchBuilder Map Object with a match + */ + public static MatchBuilder createArpDstIpv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) { + ArpMatchBuilder arpDstMatch = new ArpMatchBuilder(); + arpDstMatch.setArpTargetTransportAddress(dstip); + matchBuilder.setLayer3Match(arpDstMatch.build()); + + return matchBuilder; + } + /** * @param matchBuilder MatchBuilder Object without a match yet * @param srcip String containing an IPv4 prefix