</instructions>
</configuration>
</plugin>
- <plugin>
+ <!--<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
- <!--<configuration>
+ <configuration>
<propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
- </configuration>-->
- </plugin>
+ </configuration>
+ </plugin>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
package org.opendaylight.ovsdb.openstack.netvirt.sfc;
+import java.net.InetAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
public interface ISfcClassifierService {
void programIngressClassifier(long dataPathId, String ruleName, Matches matches,
int tunnelOfPort, int tunnelId, boolean write);
void program_sfEgress(long dataPathId, int dstPort, boolean write);
+
+ void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
+ String ipAddress, String sfDplName, boolean write);
+
+ void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr,
+ String ipAddress, boolean write);
}
return null;
}
+ return getSfIp(serviceFunction);
+ }
+
+ public IpAddress getSfIp(ServiceFunction serviceFunction) {
+ if (serviceFunction == null) {
+ LOG.info("getSfIp: Servicefunction is null");
+ return null;
+ }
+
Ip ipLocator = (Ip) serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType();
return ipLocator.getIp();
}
+
+ public String getSfDplName(ServiceFunction serviceFunction) {
+ String sfDplName = null;
+ if (serviceFunction == null) {
+ LOG.warn("getSfDplName: Servicefunction is null");
+ return null;
+ }
+
+ sfDplName = serviceFunction.getSfDataPlaneLocator().get(0).getName().getValue();
+ return sfDplName;
+ }
}
import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
public void program_sfEgress(long dataPathId, int dstPort, boolean write) {
}
+
+ @Override
+ public void program_sfIngress(long dataPathId, int dstPort, long sfOfPort, String ipAddress, String sfDplName, boolean write) {
+
+ }
+
+ @Override
+ public void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr, String ipAddress, boolean write) {
+
+ }
}
import java.util.List;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.INetvirtSfcOF13Provider;
import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceFunctionAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.path.first.hop.info.RenderedServicePathFirstHop;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.Ace;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
import org.osgi.framework.ServiceReference;
private static final short SFC_TABLE = 150;
private static final int GPE_PORT = 6633;
private static final String NETWORK_TYPE_VXLAN = "vxlan";
-
- public void setSfcClassifierService(ISfcClassifierService sfcClassifierService) {
- this.sfcClassifierService = sfcClassifierService;
- }
-
private MdsalUtils mdsalUtils;
private SfcUtils sfcUtils;
private static final String VXGPE = "vxgpe";
//this.setDependencies(null);
}
+ public void setSfcClassifierService(ISfcClassifierService sfcClassifierService) {
+ this.sfcClassifierService = sfcClassifierService;
+ }
+
@Override
public void addClassifierRules(Bridge bridge, Acl acl) {
RenderedServicePathHop firstHop = pathHopList.get(0);
RenderedServicePathHop lastHop = pathHopList.get(pathHopList.size()-1);
+ ServiceFunction serviceFunction =
+ SfcProviderServiceFunctionAPI.readServiceFunction(
+ SfName.getDefaultInstance(firstHop.getServiceFunctionName().getValue()));
+ if (serviceFunction == null) {
+ LOG.warn("programAclEntry: Could not identify ServiceFunction {} on {}",
+ firstHop.getServiceFunctionName().getValue(), bridgeNode);
+ continue;
+ }
+
nshHeader.setNshNsi(firstHop.getServiceIndex());
// workaround: bypass sff and got directly to sf
//nshHeader.setNshTunIpDst(firstRspHop.getIp().getIpv4Address());
- IpAddress sfIpAddress = sfcUtils.getSfIp(firstHop.getServiceFunctionName().getValue());
+ IpAddress sfIpAddress = sfcUtils.getSfIp(serviceFunction);
+ String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+ //sfcUtils.getSfIp(firstHop.getServiceFunctionName().getValue());
nshHeader.setNshTunIpDst(sfIpAddress.getIpv4Address());
nshHeader.setNshTunUdpPort(firstRspHop.getPort());
LOG.debug("handleIngressClassifier: NSH Header = {}", nshHeader);
sfcClassifierService.program_sfEgress(dataPathId, GPE_PORT, true);
//not needed if ip route and arp can be added to stack
- //sfcClassifierService.program_sfIngress(dataPathId, true);
- //sfcClassifierService.program_sfArp(dataPathId, true);
+ long sfOfPort = getSfPort(bridgeNode, sfDplName);
+
+ String sfMac = getMacFromExternalIds(bridgeNode, sfDplName);
+ String sfIpString = new String(sfIpAddress.getValue());
+ LOG.info("handleIngressClassifier: sfDplName: {}, sfMac: {}, sfOfPort: {}, sfIpAddress: {}",
+ sfDplName, sfMac, sfOfPort, sfIpString);
+ if (sfMac != null) { // install if the sf is on this bridge, expand when using multiple bridges
+ sfcClassifierService.program_sfIngress(dataPathId, GPE_PORT, sfOfPort, sfIpString, sfDplName, true);
+ sfcClassifierService.programStaticArpEntry(dataPathId, 0L, sfMac, sfIpString, true);
+ }
short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1);
- long tunnelOfPort = getTunnelOfPort(bridgeNode, VXGPE);
sfcClassifierService.programEgressClassifier1(dataPathId, vxGpeOfPort, rsp.getPathId(),
- lastServiceindex, (int)tunnelOfPort, 0, (short)0, true);
+ lastServiceindex, (int)sfOfPort, 0, (short)0, true);
sfcClassifierService.programEgressClassifier2(dataPathId, vxGpeOfPort, rsp.getPathId(),
- lastServiceindex, (int) tunnelOfPort, 0, true);
+ lastServiceindex, (int)sfOfPort, 0, true);
sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
}
}
- // loop through sf's:
- // - program arp responder
- // - program sf to sff
- // - program sff to sf
- private void handleSfWorkaround(RenderedServicePath rsp) {
+ private String getSfPortName(SfName sfName) {
+ String sfPortName = null;
+ return sfPortName;
}
private RenderedServicePath getRenderedServicePath (Ace entry) {
return port;
}
+ private long getSfPort(Node bridgeNode, String sfPortName) {
+ long port = 0L;
+ port = getOFPort(bridgeNode, sfPortName);
+ return port;
+ }
+
private long getOFPort(Node bridgeNode, String portName) {
long ofPort = 0L;
OvsdbTerminationPointAugmentation port = southbound.extractTerminationPointAugmentation(bridgeNode, portName);
if (port != null) {
ofPort = southbound.getOFPort(port);
}
- for (int i = 0; i < 5; i++) {
- LOG.info("Looking for ofPort {}, try: {}", portName, i);
- if (ofPort == 0L) {
- TerminationPoint tp = southbound.readTerminationPoint(bridgeNode, null, portName);
- if (tp != null) {
- port = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
- if (port != null) {
- ofPort = southbound.getOFPort(port);
- break;
+ if (ofPort == 0L) {
+ for (int i = 0; i < 5; i++) {
+ LOG.info("Looking for ofPort {}, try: {}", portName, i);
+ if (ofPort == 0L) {
+ TerminationPoint tp = southbound.readTerminationPoint(bridgeNode, null, portName);
+ if (tp != null) {
+ port = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
+ if (port != null) {
+ ofPort = southbound.getOFPort(port);
+ break;
+ }
}
}
- }
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
}
}
return ofPort;
}
+ private String getMacFromOptions(Node bridgeNode, String portName) {
+ String mac = null;
+ OvsdbTerminationPointAugmentation port = southbound.extractTerminationPointAugmentation(bridgeNode, portName);
+ LOG.info("getMac: portName: {}, bridgeNode: {},,, port: {}", portName, bridgeNode, port);
+ if (port != null && port.getOptions() != null) {
+ //mac = southbound.getOptionsValue(port.getOptions(), EXTERNAL_ID_VM_MAC);
+ for (Options option : port.getOptions()) {
+ LOG.info("getMac: option: {}", option);
+ if (option.getOption().equals(Constants.EXTERNAL_ID_VM_MAC)) {
+ mac = option.getValue();
+ break;
+ }
+ }
+ }
+ return mac;
+ }
+
+ private String getMacFromExternalIds(Node bridgeNode, String portName) {
+ String mac = null;
+ OvsdbTerminationPointAugmentation port = southbound.extractTerminationPointAugmentation(bridgeNode, portName);
+ LOG.info("getMac: portName: {}, bridgeNode: {},,, port: {}", portName, bridgeNode, port);
+ if (port != null && port.getInterfaceExternalIds() != null) {
+ mac = southbound.getInterfaceExternalIdsValue(port, Constants.EXTERNAL_ID_VM_MAC);
+ }
+ return mac;
+ }
+
@Override
public void setDependencies(ServiceReference serviceReference) {
nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
- sfcClassifierService = (ISfcClassifierService) ServiceHelper.getGlobalInstance(ISfcClassifierService.class, this);
+ sfcClassifierService =
+ (ISfcClassifierService) ServiceHelper.getGlobalInstance(ISfcClassifierService.class, this);
LOG.info("sfcClassifierService= {}", sfcClassifierService);
}
}
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+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.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
FlowBuilder flowBuilder = new FlowBuilder();
MatchBuilder matchBuilder = buildMatch(matches);
- flowBuilder.setMatch(matchBuilder.build());
+ //flowBuilder.setMatch(matchBuilder.build());
flowBuilder.setMatch(MatchUtils.addNxRegMatch(
matchBuilder,
new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build());
FlowBuilder flowBuilder = new FlowBuilder();
MatchBuilder matchBuilder = new MatchBuilder();
- flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort).build());
- flowBuilder.setMatch(MatchUtils.addNxNspMatch(matchBuilder, nsp).build());
+ MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
+ MatchUtils.addNxNspMatch(matchBuilder, nsp);
flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nsi).build());
String flowId = "sfcEgressClass1_" + vxGpeOfPort;
if (write) {
InstructionsBuilder isb = new InstructionsBuilder();
List<Instruction> instructions = Lists.newArrayList();
- List<Action> actionList = Lists.newArrayList();
+ InstructionBuilder ib = new InstructionBuilder();
+
+ /*List<Action> actionList = Lists.newArrayList();
ActionBuilder ab = new ActionBuilder();
ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
ApplyActionsBuilder aab = new ApplyActionsBuilder();
aab.setAction(actionList);
- InstructionBuilder ib = new InstructionBuilder();
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
- instructions.add(ib.build());
+ ib.setOrder(instructions.size());
+ ib.setKey(new InstructionKey(instructions.size()));
+ instructions.add(ib.build());*/
ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), getTable());
- ib.setOrder(1);
- ib.setKey(new InstructionKey(1));
+ ib.setOrder(instructions.size());
+ ib.setKey(new InstructionKey(instructions.size()));
instructions.add(ib.build());
isb.setInstruction(instructions);
FlowBuilder flowBuilder = new FlowBuilder();
MatchBuilder matchBuilder = new MatchBuilder();
- flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort).build());
- flowBuilder.setMatch(MatchUtils.addNxNspMatch(matchBuilder, nsp).build());
+ MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
+ MatchUtils.addNxNspMatch(matchBuilder, nsp);
flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nsi).build());
String flowId = "sfcEgressClass2_" + vxGpeOfPort;
}
}
+ // packet from sf to sff that need to go out local
@Override
public void program_sfEgress(long dataPathId, int dstPort, boolean write) {
NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
MatchBuilder matchBuilder = new MatchBuilder();
MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
- flowBuilder.setMatch(MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort).build());
+ MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
flowBuilder.setMatch(MatchUtils.addNxRegMatch(
matchBuilder, new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build());
}
}
+ // looped back sff to sf packets
+ @Override
+ public void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
+ String ipAddress, String sfDplName, boolean write) {
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
+ Ipv4Prefix ipCidr = MatchUtils.iPv4PrefixFromIPv4Address(ipAddress);
+ MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(ipCidr));
+ flowBuilder.setMatch(MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort).build());
+
+ String flowId = "sfIngress_" + dstPort + "_" + ipAddress;
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setBarrier(true);
+ flowBuilder.setTableId(TABLE_0);
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+
+ if (write) {
+ InstructionBuilder ib = new InstructionBuilder();
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+ InstructionUtils.createOutputPortInstructions(ib, dataPathId, sfOfPort);
+
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
+ instructions.add(ib.build());
+
+ isb.setInstruction(instructions);
+ flowBuilder.setInstructions(isb.build());
+ writeFlow(flowBuilder, nodeBuilder);
+ } else {
+ removeFlow(flowBuilder, nodeBuilder);
+ }
+ }
+
+ @Override
+ public void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr,
+ String ipAddress, boolean write) {
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ MacAddress macAddress = new MacAddress(macAddressStr);
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(Constants.ARP_ETHERTYPE));
+ MatchUtils.createArpDstIpv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress));
+ flowBuilder.setMatch(matchBuilder.build());
+
+ String flowId = "ArpResponder_" + ipAddress;
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setBarrier(true);
+ flowBuilder.setTableId(TABLE_0);
+ flowBuilder.setKey(key);
+ flowBuilder.setPriority(1024);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+
+ if (write == true) {
+ InstructionBuilder ib = new InstructionBuilder();
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+ ApplyActionsBuilder aab = new ApplyActionsBuilder();
+ ActionBuilder ab = new ActionBuilder();
+ List<Action> actionList = Lists.newArrayList();
+
+ // Move Eth Src to Eth Dst
+ ab.setAction(ActionUtils.nxMoveEthSrcToEthDstAction());
+ ab.setOrder(0);
+ ab.setKey(new ActionKey(0));
+ actionList.add(ab.build());
+
+ // Set Eth Src
+ ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
+ ab.setOrder(1);
+ ab.setKey(new ActionKey(1));
+ actionList.add(ab.build());
+
+ // Set ARP OP
+ ab.setAction(ActionUtils.nxLoadArpOpAction(BigInteger.valueOf(0x02L)));
+ ab.setOrder(2);
+ ab.setKey(new ActionKey(2));
+ actionList.add(ab.build());
+
+ // Move ARP SHA to ARP THA
+ ab.setAction(ActionUtils.nxMoveArpShaToArpThaAction());
+ ab.setOrder(3);
+ ab.setKey(new ActionKey(3));
+ actionList.add(ab.build());
+
+ // Move ARP SPA to ARP TPA
+ ab.setAction(ActionUtils.nxMoveArpSpaToArpTpaAction());
+ ab.setOrder(4);
+ ab.setKey(new ActionKey(4));
+ actionList.add(ab.build());
+
+ // Load Mac to ARP SHA
+ ab.setAction(ActionUtils.nxLoadArpShaAction(macAddress));
+ ab.setOrder(5);
+ ab.setKey(new ActionKey(5));
+ actionList.add(ab.build());
+
+ // Load IP to ARP SPA
+ ab.setAction(ActionUtils.nxLoadArpSpaAction(ipAddress));
+ ab.setOrder(6);
+ ab.setKey(new ActionKey(6));
+ actionList.add(ab.build());
+
+ // Output of InPort
+ ab.setAction(ActionUtils.outputAction(
+ FlowUtils.getSpecialNodeConnectorId(dataPathId, OutputPortValues.INPORT.toString())));
+ ab.setOrder(7);
+ ab.setKey(new ActionKey(7));
+ actionList.add(ab.build());
+
+ // Create Apply Actions Instruction
+ aab.setAction(actionList);
+ ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
+ instructions.add(ib.build());
+
+ isb.setInstruction(instructions);
+ flowBuilder.setInstructions(isb.build());
+ writeFlow(flowBuilder, nodeBuilder);
+ } else {
+ removeFlow(flowBuilder, nodeBuilder);
+ }
+ }
+
private List<Action> getNshAction(NshUtils header, List<Action> actionList) {
// Build the Actions to Add the NSH Header
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC1Load =
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
+import com.google.common.collect.Maps;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Assert;
private static final String OVSDB_TRACE = "ovsdb.trace";
private static final String SF1NAME = "firewall-72";
private static final String SF2NAME = "dpi-72";
- private static final String SF1IP = "127.0.0.1";//"192.168.50.70";//"192.168.120.31";
- private static final String SF2IP = "192.168.120.32";
- private static final String SF1DPLNAME = "1";
- private static final String SF2DPLNAME = "2";
- private static final String SFF1IP = "192.168.120.31";
- private static final String SFF2IP = "192.168.120.32";
+ private static final String SF1IP = "10.2.1.1";//"192.168.50.70";//"192.168.120.31";
+ private static final String SF2IP = "10.2.1.2";
+ private static final String SF1DPLNAME = "sf1";
+ private static final String SF2DPLNAME = "sf2";
+ private static final String SFF1IP = "127.0.0.1";
+ private static final String SFF2IP = "127.0.0.1";
private static final String SFF1NAME = "SFF1";
private static final String SFF2NAME = "SFF2";
private static final String SFFDPL1NAME = "vxgpe";
editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
"log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.sfc",
LogLevel.TRACE.name()),
+ editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+ "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13",
+ LogLevel.TRACE.name()),
editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
"log4j.logger.org.opendaylight.sfc",
LogLevel.TRACE.name()),
String sf1Ip = SF1IP;
String sff1Ip = SF1IP;
String sff1Name = SFF1NAME;
- String sffDpl1Name = SFFDPL1NAME;
+ String sf1DplName = SF1DPLNAME;
String sn1Name = SN1NAME;
String bridge1Name= BRIDGE1NAME;
String sf2Name = SF2NAME;
String sf2Ip = SF2IP;
String sff2Ip = SF2IP;
String sff2Name = SFF2NAME;
- String sffDpl2Name = SFFDPL2NAME;
+ String sf2DplName = SF2DPLNAME;
String sn2Name = SN2NAME;
String bridge2Name= BRIDGE2NAME;
int port = GPEPORT;
ServiceFunctionBuilder serviceFunctionBuilder =
- serviceFunctionUtils.serviceFunctionBuilder(sf1Ip, port, sffDpl1Name, sff1Name, sf1Name);
+ serviceFunctionUtils.serviceFunctionBuilder(sf1Ip, port, sf1DplName, sff1Name, sf1Name);
List<ServiceFunction> serviceFunctionList = serviceFunctionUtils.list(
new ArrayList<ServiceFunction>(), serviceFunctionBuilder);
private ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder() {
String sf1Name = SF1NAME;
String sf1Ip = SF1IP;
- String sff1Ip = SF1IP;
+ String sff1Ip = SFF1IP;
String sff1Name = SFF1NAME;
String sffDpl1Name = SFFDPL1NAME;
String sn1Name = SN1NAME;
String bridge1Name= BRIDGE1NAME;
String sf2Name = SF2NAME;
String sf2Ip = SF2IP;
- String sff2Ip = SF2IP;
+ String sff2Ip = SFF2IP;
String sff2Name = SFF2NAME;
String sffDpl2Name = SFFDPL2NAME;
String sn2Name = SN2NAME;
ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
- sff1Name, sff1Ip, port, sffDpl1Name, sf1Name, sff1Ip, sn1Name, bridge1Name, Firewall.class);
+ sff1Name, sff1Ip, port, sffDpl1Name, sf1Name, sf1Ip, sn1Name, bridge1Name, Firewall.class);
List<ServiceFunctionForwarder> serviceFunctionForwarderList = serviceFunctionForwarderUtils.list(
new ArrayList<ServiceFunctionForwarder>(), serviceFunctionForwarderBuilder);
assertNotNull("node is not connected", ovsdbNode);
Thread.sleep(5000);
+ Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
+ assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
+ long datapathId = southbound.getDataPathId(bridgeNode);
+
+ Map<String, String> externalIds = Maps.newHashMap();
+ externalIds.put("attached-mac", "01:02:03:04:05:06");
+ southboundUtils.addTerminationPoint(bridgeNode, null, SF1DPLNAME, "internal", null, externalIds);
+ southboundUtils.addTerminationPoint(bridgeNode, null, "vm1", "internal");
+ southboundUtils.addTerminationPoint(bridgeNode, null, "vm2", "internal");
+ Map<String, String> options = Maps.newHashMap();
+ options.put("key", "flow");
+ options.put("remote_ip", "192.168.120.32");
+ southboundUtils.addTerminationPoint(bridgeNode, null, "vx", "vxlan", options, null);
+ Thread.sleep(1000);
testModelPut(serviceFunctionsBuilder(), ServiceFunctions.class);
testModelPut(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class);
Thread.sleep(10000);
- Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
- assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
- long datapathId = southbound.getDataPathId(bridgeNode);
-
ISfcClassifierService sfcClassifierService = (ISfcClassifierService) ServiceHelper.getGlobalInstance(ISfcClassifierService.class, this);
LOG.info("SfcClassifierService: {}", sfcClassifierService);
readwait();
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
return new NodeConnectorId(nodeName + ":" + ofPort);
}
+ public static NodeConnectorId getSpecialNodeConnectorId(long dpidLong, String portName) {
+ return new NodeConnectorId(getNodeName(dpidLong) + ":" + portName);
+ }
+
public static NodeConnectorId getNodeConnectorId(long dpidLong, long ofPort) {
return getNodeConnectorId(ofPort, getNodeName(dpidLong));
}
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.ovsdb.southbound.SouthboundConstants;
import org.opendaylight.ovsdb.southbound.SouthboundMapper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final String DEFAULT_OPENFLOW_PORT = "6653";
private static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
private MdsalUtils mdsalUtils;
+ public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
public SouthboundUtils(MdsalUtils mdsalUtils) {
this.mdsalUtils = mdsalUtils;
}
+ public static final ImmutableBiMap<String, Class<? extends InterfaceTypeBase>> OVSDB_INTERFACE_TYPE_MAP
+ = new ImmutableBiMap.Builder<String, Class<? extends InterfaceTypeBase>>()
+ .put("internal", InterfaceTypeInternal.class)
+ .put("vxlan", InterfaceTypeVxlan.class)
+ .put("patch", InterfaceTypePatch.class)
+ .put("system", InterfaceTypeSystem.class)
+ .put("tap", InterfaceTypeTap.class)
+ .put("geneve", InterfaceTypeGeneve.class)
+ .put("gre", InterfaceTypeGre.class)
+ .put("ipsec_gre", InterfaceTypeIpsecGre.class)
+ .put("gre64", InterfaceTypeGre64.class)
+ .put("ipsec_gre64", InterfaceTypeIpsecGre64.class)
+ .put("lisp", InterfaceTypeLisp.class)
+ .put("dpdk", InterfaceTypeDpdk.class)
+ .put("dpdkr", InterfaceTypeDpdkr.class)
+ .put("dpdkvhost", InterfaceTypeDpdkvhost.class)
+ .put("dpdkvhostuser", InterfaceTypeDpdkvhostuser.class)
+ .build();
+
public NodeId createNodeId(IpAddress ip, PortNumber port) {
String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
+ new String(ip.getValue()) + ":" + port.getValue();
return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
}
+ public InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node, String portName){
+
+ InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
+ .create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
+ .child(Node.class,node.getKey())
+ .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
+
+ LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
+ return terminationPointPath;
+ }
+
public NodeKey createNodeKey(IpAddress ip, PortNumber port) {
return new NodeKey(createNodeId(ip, port));
}
InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
}
+
+ public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName,
+ String type, Map<String, String> options,
+ Map<String, String> externalIds) {
+ InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
+ OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+
+ tpAugmentationBuilder.setName(portName);
+ if (type != null) {
+ tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
+ }
+
+ if (options != null && options.size() > 0) {
+ List<Options> optionsList = new ArrayList<>();
+ for (Map.Entry<String, String> entry : options.entrySet()) {
+ OptionsBuilder optionsBuilder = new OptionsBuilder();
+ optionsBuilder.setKey(new OptionsKey(entry.getKey()));
+ optionsBuilder.setOption(entry.getKey());
+ optionsBuilder.setValue(entry.getValue());
+ optionsList.add(optionsBuilder.build());
+ }
+ tpAugmentationBuilder.setOptions(optionsList);
+ }
+
+ if (externalIds != null && externalIds.size() > 0) {
+ List<InterfaceExternalIds> externalIdsList = new ArrayList<>();
+ for (Map.Entry<String, String> entry : externalIds.entrySet()) {
+ InterfaceExternalIdsBuilder interfaceExternalIdsBuilder = new InterfaceExternalIdsBuilder();
+ interfaceExternalIdsBuilder.setKey(new InterfaceExternalIdsKey(entry.getKey()));
+ interfaceExternalIdsBuilder.setExternalIdKey(entry.getKey());
+ interfaceExternalIdsBuilder.setExternalIdValue(entry.getValue());
+ externalIdsList.add(interfaceExternalIdsBuilder.build());
+ }
+ tpAugmentationBuilder.setInterfaceExternalIds(externalIdsList);
+ }
+
+ TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+ tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+ tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+ /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
+ return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
+ }
+
+ public TerminationPoint readTerminationPoint(Node bridgeNode, String bridgeName, String portName) {
+ InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+ bridgeNode, portName);
+ return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpIid);
+ }
+
+ public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type) {
+ return addTerminationPoint(bridgeNode, bridgeName, portName, type, null, null);
+ }
+
+ public Boolean addTunnelTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type,
+ Map<String, String> options) {
+ return addTerminationPoint(bridgeNode, bridgeName, portName, type, options, null);
+ }
}