* http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
*
*/
+
+ if (portSecurityRule == null ||
+ portSecurityRule.getSecurityRuleEthertype() == null ||
+ portSecurityRule.getSecurityRuleDirection() == null) {
+ continue;
+ }
+
if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
&& portSecurityRule.getSecurityRuleDirection().equals("egress")) {
LOG.debug("programPortSecurityGroup: Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
break;
default:
- LOG.error("programPortSecurityRule: Protocol not supported", portSecurityRule);
+ LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
+ "protocol = ", portSecurityRule.getSecurityRuleProtocol());
+ egressOtherProtocolAclHandler(dpid, segmentationId, attachedMac,
+ portSecurityRule, ipaddress, write,
+ Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
break;
}
}
}
+ private void egressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String srcMac,
+ NeutronSecurityRule portSecurityRule, String dstAddress,
+ boolean write, Integer protoPortMatchPriority) {
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ String flowId = "Egress_Other_" + segmentationId + "_" + srcMac + "_";
+ matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+
+ short proto = 0;
+ try {
+ Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
+ proto = protocol.shortValue();
+ flowId = flowId + proto;
+ } catch (NumberFormatException e) {
+ LOG.error("Protocol vlaue conversion failure", e);
+ }
+ matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
+
+ if (null != dstAddress) {
+ flowId = flowId + dstAddress;
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+ MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
+
+ } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+ flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,new Ipv4Prefix(portSecurityRule
+ .getSecurityRuleRemoteIpPrefix()));
+ }
+ flowId = flowId + "_Permit";
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+ }
+
@Override
public void programFixedSecurityGroup(Long dpid, String segmentationId, String attachedMac,
long localPort, List<Neutron_IPs> srcAddressList,
if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
&& portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
- + portSecurityRule.getSecurityRulePortMax() + "_";
+ + portSecurityRule.getSecurityRulePortMax() + "_";
matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
}
/*TODO TCP PortRange Match*/
if (null != dstAddress) {
flowId = flowId + dstAddress;
matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
- MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
+ MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
} else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
- new Ipv4Prefix(portSecurityRule
- .getSecurityRuleRemoteIpPrefix()));
+ new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
}
flowId = flowId + "_Permit";
String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
private void egressAclIcmp(Long dpidLong, String segmentationId, String srcMac,
NeutronSecurityRule portSecurityRule, String dstAddress,
boolean write, Integer protoPortMatchPriority) {
+
MatchBuilder matchBuilder = new MatchBuilder();
- String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_"
- + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
- + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+ String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
- matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
- portSecurityRule.getSecurityRulePortMin().shortValue(),
- portSecurityRule.getSecurityRulePortMax().shortValue());
+ /*Custom ICMP Match */
+ if (portSecurityRule.getSecurityRulePortMin() != null &&
+ portSecurityRule.getSecurityRulePortMax() != null) {
+ flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
+ + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+ matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
+ portSecurityRule.getSecurityRulePortMin().shortValue(),
+ portSecurityRule.getSecurityRulePortMax().shortValue());
+ } else {
+ /* All ICMP Match */ // We are getting from neutron NULL for both min and max
+ flowId = flowId + "all" + "_" ;
+ matchBuilder = MatchUtils.createICMPv4Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
+ }
if (null != dstAddress) {
flowId = flowId + dstAddress;
matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
*
*/
+ if (portSecurityRule == null ||
+ portSecurityRule.getSecurityRuleEthertype() == null ||
+ portSecurityRule.getSecurityRuleDirection() == null) {
+ continue;
+ }
+
if ("IPv4".equals(portSecurityRule.getSecurityRuleEthertype())
&& "ingress".equals(portSecurityRule.getSecurityRuleDirection())) {
LOG.debug("programPortSecurityGroup: Rule matching IPv4 and ingress is: {} ", portSecurityRule);
securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
}
}
-
-
-
}
}
write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
break;
default:
- LOG.error("programPortSecurityRule: Protocol not supported", portSecurityRule);
+ LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
+ "protocol = ", portSecurityRule.getSecurityRuleProtocol());
+ ingressOtherProtocolAclHandler(dpid, segmentationId, attachedMac, portSecurityRule,
+ null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
break;
}
}
}
+ private void ingressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String dstMac,
+ NeutronSecurityRule portSecurityRule, String srcAddress,
+ boolean write, Integer protoPortMatchPriority) {
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ String flowId = "Ingress_Other_" + segmentationId + "_" + dstMac + "_";
+ matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+ short proto = 0;
+ try {
+ Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
+ proto = protocol.shortValue();
+ flowId = flowId + proto;
+ } catch (NumberFormatException e) {
+ LOG.error("Protocol vlaue conversion failure", e);
+ }
+ matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
+ if (null != srcAddress) {
+ flowId = flowId + srcAddress;
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
+ } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+ flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+ matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+ new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+ }
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+ NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+ flowId = flowId + "_Permit";
+ syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+ }
+
@Override
public void programFixedSecurityGroup(Long dpid, String segmentationId, String dhcpMacAddress,
long localPort, boolean isLastPortinSubnet,
boolean write, Integer protoPortMatchPriority) {
MatchBuilder matchBuilder = new MatchBuilder();
- FlowBuilder flowBuilder = new FlowBuilder();
- String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_"
- + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
- + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+ String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_";
matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
- matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
- portSecurityRule.getSecurityRulePortMin().shortValue(),
- portSecurityRule.getSecurityRulePortMax().shortValue());
+
+ /* Custom ICMP Match */
+ if (portSecurityRule.getSecurityRulePortMin() != null &&
+ portSecurityRule.getSecurityRulePortMax() != null) {
+ flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
+ + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
+ matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
+ portSecurityRule.getSecurityRulePortMin().shortValue(),
+ portSecurityRule.getSecurityRulePortMax().shortValue());
+ } else {
+ /* All ICMP Match */
+ flowId = flowId + "all" + "_";
+ matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
+ }
if (null != srcAddress) {
flowId = flowId + srcAddress;
matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
verify(commitFuture, times(1)).get();
}
*/
+ /**
+ * Test method {@link EgressAclService#programPortSecurityGroup(java.lang.Long, java.lang.String,
+ * java.lang.String, long, org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup,
+ * java.lang.String, boolean)} when portSecurityRule is incomplete
+ */
+ @Test
+ public void testProgramPortSecurityGroupWithIncompleteRule() throws Exception {
+ NeutronSecurityRule portSecurityRule1 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule1.getSecurityRuleEthertype()).thenReturn("IPv4");
+ when(portSecurityRule1.getSecurityRuleDirection()).thenReturn("not_egress"); // other direction
+
+ NeutronSecurityRule portSecurityRule2 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule2.getSecurityRuleEthertype()).thenReturn(null);
+ when(portSecurityRule2.getSecurityRuleDirection()).thenReturn("egress");
+
+ NeutronSecurityRule portSecurityRule3 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule3.getSecurityRuleEthertype()).thenReturn("IPv4");
+ when(portSecurityRule3.getSecurityRuleDirection()).thenReturn(null);
+
+ NeutronSecurityRule portSecurityRule4 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule4.getSecurityRuleEthertype()).thenReturn(null);
+ when(portSecurityRule4.getSecurityRuleDirection()).thenReturn(null);
+
+ List<NeutronSecurityRule> portSecurityList = new ArrayList<>();
+ portSecurityList.add(null);
+ portSecurityList.add(portSecurityRule1);
+ portSecurityList.add(portSecurityRule2);
+ portSecurityList.add(portSecurityRule3);
+ portSecurityList.add(portSecurityRule4);
+
+ NeutronSecurityGroup localSecurityGroup = mock(NeutronSecurityGroup.class);
+ when(localSecurityGroup.getSecurityRules()).thenReturn(portSecurityList);
+
+ egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT,
+ localSecurityGroup, PORT_UUID, true);
+ }
+
/**
* Test method {@link EgressAclService#egressACLDefaultTcpDrop(Long, String, String, int, boolean)}
*/
verify(commitFuture, times(1)).get();
}
*/
+ /**
+ * Test method {@link EgressAclService#programPortSecurityGroup(java.lang.Long, java.lang.String,
+ * java.lang.String, long, org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup,
+ * java.lang.String, boolean)} when portSecurityRule is incomplete
+ */
+ @Test
+ public void testProgramPortSecurityGroupWithIncompleteRule() throws Exception {
+ NeutronSecurityRule portSecurityRule1 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule1.getSecurityRuleEthertype()).thenReturn("IPv4");
+ when(portSecurityRule1.getSecurityRuleDirection()).thenReturn("not_ingress"); // other direction
+
+ NeutronSecurityRule portSecurityRule2 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule2.getSecurityRuleEthertype()).thenReturn(null);
+ when(portSecurityRule2.getSecurityRuleDirection()).thenReturn("ingress");
+
+ NeutronSecurityRule portSecurityRule3 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule3.getSecurityRuleEthertype()).thenReturn("IPv4");
+ when(portSecurityRule3.getSecurityRuleDirection()).thenReturn(null);
+
+ NeutronSecurityRule portSecurityRule4 = mock(NeutronSecurityRule.class);
+ when(portSecurityRule4.getSecurityRuleEthertype()).thenReturn(null);
+ when(portSecurityRule4.getSecurityRuleDirection()).thenReturn(null);
+
+ List<NeutronSecurityRule> portSecurityList = new ArrayList<>();
+ portSecurityList.add(null);
+ portSecurityList.add(portSecurityRule1);
+ portSecurityList.add(portSecurityRule2);
+ portSecurityList.add(portSecurityRule3);
+ portSecurityList.add(portSecurityRule4);
+
+ NeutronSecurityGroup localSecurityGroup = mock(NeutronSecurityGroup.class);
+ when(localSecurityGroup.getSecurityRules()).thenReturn(portSecurityList);
+
+ ingressAclServiceSpy.programPortSecurityGroup(
+ Long.valueOf(1554), "2", MAC_ADDRESS, 124, localSecurityGroup, PORT_UUID, false);
+ }
+
/**
* Test IPv4 add test case.
*/
<Export-Package>
org.opendaylight.yang.gen.v1.*,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.*,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.*,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.*
</Export-Package>
</instructions>
</configuration>
description "Initial revision of netvirt extensions to ietf-acl model";
}
- // TODO: Add choice for Neutron and add fields there instead of at the root of matches
//augment "/ietf-acl:access-lists/ietf-acl:access-list/ietf-acl:access-list-entries/ietf-acl:access-list-entry/ietf-acl:matches" {
augment "/ietf-acl:access-lists/ietf-acl:acl/ietf-acl:access-list-entries/ietf-acl:ace/ietf-acl:matches" {
description "Neutron network uuid";
}
}
- // TODO: Add choice for Neutron and add fields there instead of at the root of matches
augment "/ietf-acl:access-lists/ietf-acl:acl/ietf-acl:access-list-entries/ietf-acl:ace/ietf-acl:actions" {
- description "Redirect traffic to SFC identified by SFC Path ID";
+ description "Redirect traffic to SFC identified by either SFC, SFP or RSP";
ext:augment-identifier "redirect-to-sfc";
- leaf redirect-sfc {
+ leaf sfc-name {
+ type string;
+ }
+ leaf sfp-name {
+ type string;
+ }
+ leaf rsp-name {
type string;
}
}
<type>xml</type>
<scope>runtime</scope>
</dependency>
- <dependency>
- <groupId>org.opendaylight.sfc</groupId>
- <artifactId>features-sfc-ovs</artifactId>
- <version>${sfc.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.sfc</groupId>
- <artifactId>features-sfcofl2</artifactId>
- <version>${sfc.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>openstack.net-virt-sfc-impl</artifactId>
<repository>mvn:org.opendaylight.ovsdb/features-ovsdb/${project.version}/xml/features</repository>
<repository>mvn:org.opendaylight.ovsdb/southbound-features/${project.version}/xml/features</repository>
<repository>mvn:org.opendaylight.sfc/features-sfc/${sfc.version}/xml/features</repository>
- <!--<repository>mvn:org.opendaylight.sfc/features-sfc-ovs/${sfc.version}/xml/features</repository>-->
- <repository>mvn:org.opendaylight.sfc/features-sfcofl2/${sfc.version}/xml/features</repository>
<repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
<feature name='odl-ovsdb-sfc-api' version='${project.version}' description='OpenDaylight :: ovsdb-sfc :: api'>
<feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
<artifactId>openstack.net-virt-providers</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>${project.groupId}</groupId>
<artifactId>southbound-api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>southbound-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>utils.mdsal-utils</artifactId>
<version>${sonar-jacoco-listeners.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>iana-if-type-2014-05-08</artifactId>
+ <version>2014.05.08.8-SNAPSHOT</version>
+ </dependency>
</dependencies>
<build>
</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 org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.SfcClassifierService;
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.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.Bridges;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
+import org.osgi.framework.ServiceReference;
/**
* Open vSwitch OpenFlow 1.3 Networking Provider for Netvirt SFC
void addClassifierRules(Acl acl);
void removeClassifierRules(Acl acl);
+
+ void setSfcClassifierService(ISfcClassifierService sfcClassifierService);
+ public void setDependencies(ServiceReference serviceReference);
}
--- /dev/null
+/*
+ * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+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,
+ NshUtils nshHeader, long vxGpeOfPort, boolean write);
+
+ void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write);
+
+ void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ int tunnelOfPort, int tunnelId, short gotoTableId, boolean write);
+
+ void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ long sfOfPort, int tunnelId, boolean write);
+
+ void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ long sfOfPort, 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);
+}
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.NetvirtSfcStandaloneOF13Provider;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.services.SfcClassifierService;
-import org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.NetvirtSfcWorkaroundOF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.NetvirtSfcWorkaroundOF13Provider;
import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
MdsalUtils mdsalUtils = new MdsalUtils(dataBroker);
SfcUtils sfcUtils = new SfcUtils(mdsalUtils);
+
// Allocate provider based on config
INetvirtSfcOF13Provider provider;
if (of13Provider.equals("standalone")) {
aclListener = new NetvirtSfcAclListener(provider, dataBroker);
classifierListener = new NetvirtSfcClassifierListener(provider, dataBroker);
- addToPipeline();
+ addToPipeline(provider);
+ provider.setDependencies(null);
}
@Override
classifierListener.close();
}
- private void addToPipeline() {
- SfcClassifierService sfcClassifierService = new SfcClassifierService();
- registerService(bundleContext, SfcClassifierService.class.getName(),
- sfcClassifierService, Service.SFC_CLASSIFIER);
- sfcClassifierService.setDependencies(bundleContext, null);
+ private void addToPipeline(INetvirtSfcOF13Provider provider) {
+ if (provider instanceof NetvirtSfcStandaloneOF13Provider) {
+ SfcClassifierService sfcClassifierService =
+ new org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.services.SfcClassifierService();
+ registerService(bundleContext, ISfcClassifierService.class.getName(),
+ sfcClassifierService, Service.SFC_CLASSIFIER);
+ sfcClassifierService.setDependencies(bundleContext, null);
+ } else {
+ org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.SfcClassifierService sfcClassifierService =
+ new org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.SfcClassifierService();
+ registerService(bundleContext, ISfcClassifierService.class.getName(),
+ sfcClassifierService, Service.SFC_CLASSIFIER);
+ sfcClassifierService.setDependencies(bundleContext, null);
}
+ //provider.setSfcClassifierService(sfcClassifierService);
+ }
+
private ServiceRegistration<?> registerService(BundleContext bundleContext, String[] interfaces,
Dictionary<String, Object> properties, Object impl) {
ServiceRegistration<?> serviceRegistration = bundleContext.registerService(interfaces, impl, properties);
properties.put(AbstractServiceInstance.SERVICE_PROPERTY, serviceProperty);
properties.put(Constants.PROVIDER_NAME_PROPERTY, OF13Provider.NAME);
return registerService(bundleContext,
- new String[] {AbstractServiceInstance.class.getName(),
- interfaceClassName}, properties, impl);
+ new String[] {AbstractServiceInstance.class.getName(),interfaceClassName},
+ properties, impl);
}
}
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceFunctionAPI;
import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
+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.RenderedServicePaths;
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.RenderedServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctions;
+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.sf.rev140701.service.functions.ServiceFunctionKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
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.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.Ip;
+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.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class SfcUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(SfcUtils.class);
private MdsalUtils mdsalUtils;
public SfcUtils(MdsalUtils mdsalUtils) {
.child(RenderedServicePath.class, new RenderedServicePathKey(new RspName(rspName))).build();
}
+ public InstanceIdentifier<ServiceFunction> getSfId(String sfName) {
+ return InstanceIdentifier.builder(ServiceFunctions.class)
+ .child(ServiceFunction.class, new ServiceFunctionKey(SfName.getDefaultInstance(sfName))).build();
+ }
+
+ public RenderedServicePath getRsp(String rspName) {
+ return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, getRspId(rspName));
+ }
+
public RenderedServicePath getRspforSfp(String sfpName) {
RenderedServicePath rspFound = null;
RenderedServicePaths rsps = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, this.getRspsId());
}
return sfpFound;
}
+
+ public IpAddress getSfIpAddress(String sfname) {
+ ServiceFunction serviceFunction =
+ SfcProviderServiceFunctionAPI.readServiceFunction(SfName.getDefaultInstance(sfname));
+
+ if (serviceFunction == null) {
+ LOG.info("Failed to read ServiceFunction: {}", sfname);
+ return null;
+ }
+
+ return getSfIpAddress(serviceFunction);
+ }
+
+ public IpAddress getSfIpAddress(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 PortNumber getSfPort(ServiceFunction serviceFunction) {
+ if (serviceFunction == null) {
+ LOG.info("getSfIp: Servicefunction is null");
+ return null;
+ }
+
+ Ip ipLocator = (Ip) serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType();
+ return ipLocator.getPort();
+ }
+
+ public Ip getSfIp(ServiceFunction serviceFunction) {
+ if (serviceFunction == null) {
+ LOG.info("getSfIp: Servicefunction is null");
+ return null;
+ }
+
+ return (Ip)serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType();
+ }
+
+ 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;
+ }
+
+ public Ip getSffIp(ServiceFunctionForwarder serviceFunctionForwarder) {
+ if (serviceFunctionForwarder == null) {
+ LOG.info("getSfIp: ServicefunctionForwarder is null");
+ return null;
+ }
+
+ return (Ip)serviceFunctionForwarder.getSffDataPlaneLocator().get(0).getDataPlaneLocator().getLocatorType();
+ }
}
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.openstack.netvirt.sfc.ISfcClassifierService;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
public NetvirtSfcStandaloneOF13Provider(final DataBroker dataBroker) {
Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
mdsalUtils = new MdsalUtils(dataBroker);
- this.setDependencies(null);
+ //this.setDependencies(null);
sfcClassifier = new SfcClassifier(dataBroker, southbound, mdsalUtils);
}
}
}
+ @Override
+ public void setSfcClassifierService(ISfcClassifierService sfcClassifierService) {
+
+ }
+
@Override
public void addClassifierRules(Bridge bridge, Acl acl) {
return;
}
- RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
- LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
- if (sfcRedirect == null) {
- LOG.warn("processAClEntry: sfcRedirect is null");
- return;
- }
-
- String sfcName = sfcRedirect.getRedirectSfc();
- LOG.debug("Processing Redirect to SFC = {}", sfcRedirect.getRedirectSfc());
- ServiceFunctionPath sfp = getSfp(sfcName);
- if (sfp == null || sfp.getName() == null) {
- LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
- return;
- }
-
- LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcRedirect.getRedirectSfc(), sfp);
- // If RSP doesn't exist, create an RSP.
- String sfpName = sfp.getName().getValue();
- RenderedServicePath rsp = getRspforSfp(sfpName);
- String rspName = sfp.getName().getValue() + "_rsp";
+ RenderedServicePath rsp = getRenderedServicePath(entry);
if (rsp == null) {
- LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName);
- CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
- .setParentServiceFunctionPath(sfpName)
- .setName(rspName)
- .setSymmetric(sfp.isSymmetric())
- .build();
- rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
- if (rsp == null) {
- LOG.warn("failed to add RSP");
- return;
- }
-
- // If SFP is symmetric, create RSP in the reverse direction.
- if (sfp.isSymmetric()) {
- LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
- String rspNameRev = rspName + "-Reverse";
- RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
- this.getRspId(rspNameRev));
- if (rspReverse == null) {
- rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
- if (rspReverse == null) {
- LOG.warn("failed to add reverse RSP");
- return;
- }
- }
- }
+ LOG.warn("Failed to get renderedServicePatch for entry: {}", entry);
+ return;
}
LOG.info("processAclEntry: RSP: {}", rsp);
List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
if (pathHopList.isEmpty()) {
- LOG.warn("Service Path = {} has empty hops!!", sfpName);
+ LOG.warn("Service Path = {} has empty hops!!", rsp.getName());
return;
}
// Find the first Hop within an RSP.
// The classifier flow needs to send all matched traffic to this first hop SFF.
RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
- .readRenderedServicePathFirstHop(new RspName(rspName));
+ .readRenderedServicePathFirstHop(new RspName(rsp.getName()));
LOG.debug("First Hop IPAddress = {}, Port = {}", firstRspHop.getIp().getIpv4Address().getValue(),
- firstRspHop.getPort().getValue().intValue());
+ firstRspHop.getPort().getValue());
NshUtils nshHeader = new NshUtils();
// C1 is the normal overlay dest ip and c2 is the vnid
}
}
+ private RenderedServicePath getRenderedServicePath (Ace entry) {
+ RenderedServicePath rsp = null;
+ RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+ LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+ if (sfcRedirect == null) {
+ LOG.warn("processAClEntry: sfcRedirect is null");
+ return null;
+ }
+
+ if (sfcRedirect.getRspName() != null) {
+ rsp = getRenderedServicePathFromRsp(sfcRedirect.getRspName());
+ } else if (sfcRedirect.getSfpName() != null) {
+ LOG.warn("getRenderedServicePath: sfp not handled yet");
+ } else {
+ rsp = getRenderedServicePathFromSfc(entry);
+ }
+ LOG.info("getRenderedServicePath: rsp: {}", rsp);
+ return rsp;
+ }
+
+ private RenderedServicePath getRenderedServicePathFromRsp(String rspName) {
+ return null;//getRsp(rspName);
+ }
+
+ private RenderedServicePath getRenderedServicePathFromSfc (Ace entry) {
+ RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+ LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+ if (sfcRedirect == null) {
+ LOG.warn("processAClEntry: sfcRedirect is null");
+ return null;
+ }
+
+ String sfcName = sfcRedirect.getSfcName();
+ ServiceFunctionPath sfp = getSfp(sfcName);
+ if (sfp == null || sfp.getName() == null) {
+ LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
+ return null;
+ }
+
+ LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcName, sfp);
+ // If RSP doesn't exist, create an RSP.
+ String sfpName = sfp.getName().getValue();
+ RenderedServicePath rsp = getRspforSfp(sfpName);
+ String rspName = sfp.getName().getValue() + "_rsp";
+ if (rsp == null) {
+ LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName);
+ CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
+ .setParentServiceFunctionPath(sfpName)
+ .setName(rspName)
+ .setSymmetric(sfp.isSymmetric())
+ .build();
+ rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
+ if (rsp == null) {
+ LOG.warn("failed to add RSP");
+ return null;
+ }
+
+ // If SFP is symmetric, create RSP in the reverse direction.
+ if (sfp.isSymmetric()) {
+ LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
+ String rspNameRev = rspName + "-Reverse";
+ RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+ getRspId(rspNameRev));
+ if (rspReverse == null) {
+ rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
+ if (rspReverse == null) {
+ LOG.warn("failed to add reverse RSP");
+ return null;
+ }
+ }
+ }
+ }
+ return rsp;
+ }
+
private void handleLocalEgressPort(long dataPathId, String s, long localOfPort, short writeTable,
short gotoTable, boolean write) {
sfcClassifier.programLocalInPort(dpidLong, segmentationId, inPort, writeTable, goToTableId, matches, write);
}
- private void setDependencies(ServiceReference serviceReference) {
+ @Override
+ public void setDependencies(ServiceReference serviceReference) {
nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
}
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.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;
import org.slf4j.LoggerFactory;
-public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface {
+public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
public SfcClassifierService(Service service) {
@Override
public void setDependencies(Object impl) {}
+
+ @Override
+ public void programIngressClassifier(long dataPathId, String ruleName, Matches matches, NshUtils nshHeader, long vxGpeOfPort, boolean write) {
+
+ }
+
+ @Override
+ public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
+
+ }
+
+ @Override
+ public void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi, int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
+
+ }
+
+ @Override
+ public void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi, long sfOfPort, int tunnelId, boolean write) {
+
+ }
+
+ @Override
+ public void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi, long sfOfPort, int tunnelId, boolean write) {
+
+ }
+
+ @Override
+ 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) {
+
+ }
}
--- /dev/null
+/*
+ * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround;
+
+import com.google.common.base.Preconditions;
+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.OvsdbTables;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.INetvirtSfcOF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.SfcUtils;
+import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+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.SfcProviderServiceForwarderAPI;
+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.sl.rev140701.data.plane.locator.locator.type.Ip;
+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.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
+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.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.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.Bridges;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
+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.OvsdbNodeAugmentation;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider {
+ private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcWorkaroundOF13Provider.class);
+ private volatile NodeCacheManager nodeCacheManager;
+ private volatile Southbound southbound;
+ private volatile ISfcClassifierService sfcClassifierService;
+ private static final short SFC_TABLE = 150;
+ private static final int GPE_PORT = 6633;
+ private static final String NETWORK_TYPE_VXLAN = "vxlan";
+ private MdsalUtils mdsalUtils;
+ private SfcUtils sfcUtils;
+ private static final String VXGPE = "vxgpe";
+ private static final String TUNNEL_DST = "192.168.120.31";
+ private static final String TUNNEL_VNID = "10";
+ public static final String TUNNEL_ENDPOINT_KEY = "local_ip";
+
+ public NetvirtSfcWorkaroundOF13Provider(final DataBroker dataBroker, MdsalUtils mdsalUtils, SfcUtils sfcUtils) {
+ Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
+ Preconditions.checkNotNull(mdsalUtils, "Input mdsalUtils cannot be NULL!");
+ Preconditions.checkNotNull(sfcUtils, "Input sfcUtils cannot be NULL!");
+
+ this.mdsalUtils = mdsalUtils;
+ this.sfcUtils = sfcUtils;
+ //this.setDependencies(null);
+ }
+
+ public void setSfcClassifierService(ISfcClassifierService sfcClassifierService) {
+ this.sfcClassifierService = sfcClassifierService;
+ }
+
+ @Override
+ public void addClassifierRules(Bridge bridge, Acl acl) {
+
+ }
+
+ @Override
+ public void addClassifierRules(Bridges bridges, Acl acl) {
+ Preconditions.checkNotNull(bridges, "Input bridges cannot be NULL!");
+ Preconditions.checkNotNull(acl, "Input acl cannot be NULL!");
+ }
+
+ @Override
+ public void removeClassifierRules(Sff sff, Acl acl) {
+
+ }
+
+ @Override
+ public void addClassifierRules(Acl acl) {
+ String aclName = acl.getAclName();
+ Classifiers classifiers = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, sfcUtils.getClassifierIid());
+ if (classifiers == null) {
+ LOG.debug("addClassifierRules: No Classifiers found");
+ return;
+ }
+
+ LOG.debug("addClassifierRules: Classifiers: {}", classifiers);
+ for (Classifier classifier : classifiers.getClassifier()) {
+ if (classifier.getAcl().equals(aclName)) {
+ for (Ace ace : acl.getAccessListEntries().getAce()) {
+ processAclEntry(ace);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void removeClassifierRules(Acl acl) {
+
+ }
+
+ private void processAclEntry(Ace entry) {
+ Matches matches = entry.getMatches();
+ Preconditions.checkNotNull(matches, "Input bridges cannot be NULL!");
+
+ RenderedServicePath rsp = getRenderedServicePath(entry);
+ if (rsp == null) {
+ LOG.warn("Failed to get renderedServicePatch for entry: {}", entry);
+ return;
+ }
+
+ handleRenderedServicePath(rsp, entry);
+ }
+
+ private void handleRenderedServicePathOld(RenderedServicePath rsp, Ace entry) {
+ LOG.info("handleRenderedServicePath: RSP: {}", rsp);
+
+ Matches matches = entry.getMatches();
+ if (matches == null) {
+ LOG.warn("processAclEntry: matches not found");
+ return;
+ }
+
+ List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
+ if (pathHopList.isEmpty()) {
+ LOG.warn("handleRenderedServicePath: RSP {} has empty hops!!", rsp.getName());
+ return;
+ }
+ LOG.info("handleRenderedServicePath: pathHopList: {}", pathHopList);
+
+ final List<Node> bridgeNodes = nodeCacheManager.getBridgeNodes();
+ if (bridgeNodes == null || bridgeNodes.isEmpty()) {
+ LOG.warn("handleRenderedServicePath: There are no bridges to process");
+ return;
+ }
+ for (Node bridgeNode : bridgeNodes) {
+ OvsdbBridgeAugmentation ovsdbBridgeAugmentation = southbound.getBridge(bridgeNode, "br-int");
+ if (ovsdbBridgeAugmentation == null) {
+ continue;
+ }
+ long vxGpeOfPort = getOFPort(bridgeNode, VXGPE);
+ if (vxGpeOfPort == 0L) {
+ LOG.warn("programAclEntry: Could not identify tunnel port {} -> OF ({}) on {}",
+ VXGPE, vxGpeOfPort, bridgeNode);
+ continue;
+ }
+ long dataPathId = southbound.getDataPathId(bridgeNode);
+ if (dataPathId == 0L) {
+ LOG.warn("programAclEntry: Could not identify datapathId on {}", bridgeNode);
+ continue;
+ }
+
+ // Find the first Hop within an RSP.
+ // The classifier flow needs to send all matched traffic to this first hop SFF.
+ RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
+ .readRenderedServicePathFirstHop(rsp.getName());
+
+ LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop);
+ LOG.debug("handleRenderedServicePath: First Hop IPAddress = {}, Port = {}",
+ firstRspHop.getIp().getIpv4Address().getValue(),
+ firstRspHop.getPort().getValue());
+
+ NshUtils nshHeader = new NshUtils();
+ nshHeader.setNshMetaC1(NshUtils.convertIpAddressToLong(new Ipv4Address(TUNNEL_DST)));
+ nshHeader.setNshMetaC2(Long.parseLong(TUNNEL_VNID)); // get from register //get from
+ nshHeader.setNshNsp(rsp.getPathId());
+
+ 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.getSfIpAddress(serviceFunction);
+ String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+ //sfcUtils.getSfIp(firstHop.getServiceFunctionName().getValue());
+ nshHeader.setNshTunIpDst(sfIpAddress.getIpv4Address());
+ nshHeader.setNshTunUdpPort(firstRspHop.getPort());
+ LOG.debug("handleRenderedServicePath: NSH Header = {}", nshHeader);
+
+ sfcClassifierService.programIngressClassifier(dataPathId, entry.getRuleName(), matches,
+ nshHeader, vxGpeOfPort, true);
+
+ sfcClassifierService.program_sfEgress(dataPathId, GPE_PORT, true);
+ long sfOfPort = getSfPort(bridgeNode, sfDplName);
+
+ String sfMac = getMacFromExternalIds(bridgeNode, sfDplName);
+ String sfIpString = new String(sfIpAddress.getValue());
+ LOG.info("handleRenderedServicePath: 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);
+ sfcClassifierService.programEgressClassifier(dataPathId, vxGpeOfPort, rsp.getPathId(),
+ lastServiceindex, sfOfPort, 0, true);
+ sfcClassifierService.programEgressClassifierBypass(dataPathId, vxGpeOfPort, rsp.getPathId(),
+ lastServiceindex, sfOfPort, 0, true);
+
+ sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
+ }
+ }
+
+ private void handleRenderedServicePath(RenderedServicePath rsp, Ace entry) {
+ LOG.info("handleRenderedServicePath: RSP: {}", rsp);
+
+ Matches matches = entry.getMatches();
+ if (matches == null) {
+ LOG.warn("processAclEntry: matches not found");
+ return;
+ }
+
+ List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
+ if (pathHopList.isEmpty()) {
+ LOG.warn("handleRenderedServicePath: RSP {} has empty hops!!", rsp.getName());
+ return;
+ }
+ LOG.info("handleRenderedServicePath: pathHopList: {}", pathHopList);
+
+ RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
+ .readRenderedServicePathFirstHop(rsp.getName());
+ LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop);
+
+ RenderedServicePathHop firstHop = pathHopList.get(0);
+ RenderedServicePathHop lastHop = pathHopList.get(pathHopList.size()-1);
+
+ final List<Node> bridgeNodes = nodeCacheManager.getBridgeNodes();
+ if (bridgeNodes == null || bridgeNodes.isEmpty()) {
+ LOG.warn("handleRenderedServicePath: There are no bridges to process");
+ return;
+ }
+ for (RenderedServicePathHop hop : pathHopList) {
+ for (Node bridgeNode : bridgeNodes) {
+ // ignore bridges other than br-int
+ OvsdbBridgeAugmentation ovsdbBridgeAugmentation = southbound.getBridge(bridgeNode, "br-int");
+ if (ovsdbBridgeAugmentation == null) {
+ continue;
+ }
+ long vxGpeOfPort = getOFPort(bridgeNode, VXGPE);
+ if (vxGpeOfPort == 0L) {
+ LOG.warn("programAclEntry: Could not identify gpe vtep {} -> OF ({}) on {}",
+ VXGPE, vxGpeOfPort, bridgeNode);
+ continue;
+ }
+ long dataPathId = southbound.getDataPathId(bridgeNode);
+ if (dataPathId == 0L) {
+ LOG.warn("programAclEntry: Could not identify datapathId on {}", bridgeNode);
+ continue;
+ }
+
+ ServiceFunction serviceFunction =
+ SfcProviderServiceFunctionAPI.readServiceFunction(firstHop.getServiceFunctionName());
+ if (serviceFunction == null) {
+ LOG.warn("programAclEntry: Could not identify ServiceFunction {} on {}",
+ firstHop.getServiceFunctionName().getValue(), bridgeNode);
+ continue;
+ }
+ ServiceFunctionForwarder serviceFunctionForwarder =
+ SfcProviderServiceForwarderAPI
+ .readServiceFunctionForwarder(hop.getServiceFunctionForwarder());
+ if (serviceFunctionForwarder == null) {
+ LOG.warn("programAclEntry: Could not identify ServiceFunctionForwarder {} on {}",
+ firstHop.getServiceFunctionName().getValue(), bridgeNode);
+ continue;
+ }
+
+ handleSf(bridgeNode, serviceFunction);
+ handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, firstHop, lastHop,
+ entry.getRuleName(), matches, vxGpeOfPort, rsp);
+ if (firstHop == lastHop) {
+ handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, null, lastHop,
+ entry.getRuleName(), matches, vxGpeOfPort, rsp);
+ }
+ }
+ }
+ }
+
+ private void handleSff(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder,
+ ServiceFunction serviceFunction,
+ RenderedServicePathHop hop,
+ RenderedServicePathHop firstHop,
+ RenderedServicePathHop lastHop,
+ String ruleName, Matches matches,
+ long vxGpeOfPort, RenderedServicePath rsp) {
+ long dataPathId = southbound.getDataPathId(bridgeNode);
+
+ if (hop == firstHop) {
+ LOG.info("handleSff: first hop processing {} - {}",
+ bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+ NshUtils nshHeader = new NshUtils();
+ nshHeader.setNshNsp(rsp.getPathId());
+ nshHeader.setNshNsi(firstHop.getServiceIndex());
+ if (isSffOnBridge(bridgeNode, serviceFunctionForwarder)) {
+ LOG.info("handleSff: sff and bridge are the same: {} - {}, skipping first sff",
+ bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+ Ip ip = sfcUtils.getSfIp(serviceFunction);
+ nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
+ nshHeader.setNshTunUdpPort(ip.getPort());
+ } else {
+ LOG.info("handleSff: sff and bridge are not the same: {} - {}, sending to first sff",
+ bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+ Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder);
+ nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
+ nshHeader.setNshTunUdpPort(ip.getPort());
+ }
+ sfcClassifierService.programIngressClassifier(dataPathId, ruleName, matches,
+ nshHeader, vxGpeOfPort, true);
+ } else if (hop == lastHop) {
+ LOG.info("handleSff: last hop processing {} - {}",
+ bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
+ short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1);
+ String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+ long sfOfPort = getSfPort(bridgeNode, sfDplName);
+ sfcClassifierService.programEgressClassifier(dataPathId, vxGpeOfPort, rsp.getPathId(),
+ lastServiceindex, sfOfPort, 0, true);
+ sfcClassifierService.programEgressClassifierBypass(dataPathId, vxGpeOfPort, rsp.getPathId(),
+ lastServiceindex, sfOfPort, 0, true);
+ } else {
+ // add typical sff flows
+ }
+
+ sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
+ }
+
+ void handleSf(Node bridgeNode, ServiceFunction serviceFunction) {
+ if (isSfOnBridge(bridgeNode, serviceFunction)) {
+ LOG.info("handleSf: sf and bridge are on the same node: {} - {}, adding workaround and arp",
+ bridgeNode.getNodeId(), serviceFunction.getName());
+ long dataPathId = southbound.getDataPathId(bridgeNode);
+ Ip ip = sfcUtils.getSfIp(serviceFunction);
+ String sfIpAddr = String.valueOf(ip.getIp().getValue());
+ int sfIpPort = ip.getPort().getValue(); //GPE_PORT
+ String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+ long sfOfPort = getSfPort(bridgeNode, sfDplName);
+ String sfMac = getMacFromExternalIds(bridgeNode, sfDplName);
+ if (sfMac == null) {
+ LOG.warn("handleSff: could not find mac for {} on {}", sfDplName, bridgeNode);
+ return;
+ }
+ //should be sffdplport, but they should all be the same 6633/4790
+ sfcClassifierService.program_sfEgress(dataPathId, sfIpPort, true);
+ sfcClassifierService.program_sfIngress(dataPathId, sfIpPort, sfOfPort, sfIpAddr, sfDplName, true);
+ sfcClassifierService.programStaticArpEntry(dataPathId, 0L, sfMac, sfIpAddr, true);
+ }
+ }
+
+ private boolean isSffOnBridge(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder) {
+ String local_ip = "";
+ Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder);
+ Node ovsdbNode = southbound.readOvsdbNode(bridgeNode);
+ if (ovsdbNode != null) {
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
+ if (ovsdbNodeAugmentation != null && ovsdbNodeAugmentation.getOpenvswitchOtherConfigs() != null) {
+ southbound.getOtherConfig(ovsdbNode, OvsdbTables.OPENVSWITCH, TUNNEL_ENDPOINT_KEY);
+ }
+
+ }
+ return local_ip.equals(String.valueOf(ip.getIp().getValue()));
+ }
+
+ private boolean isSfOnBridge(Node bridgeNode, ServiceFunction serviceFunction) {
+ String sfDplName = sfcUtils.getSfDplName(serviceFunction);
+ long sfOfPort = getSfPort(bridgeNode, sfDplName);
+ return sfOfPort != 0L;
+ }
+
+ private RenderedServicePath getRenderedServicePath (Ace entry) {
+ RenderedServicePath rsp = null;
+ RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+ LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+ if (sfcRedirect == null) {
+ LOG.warn("processAClEntry: sfcRedirect is null");
+ return null;
+ }
+
+ if (sfcRedirect.getRspName() != null) {
+ rsp = getRenderedServicePathFromRsp(sfcRedirect.getRspName());
+ } else if (sfcRedirect.getSfpName() != null) {
+ LOG.warn("getRenderedServicePath: sfp not handled yet");
+ } else {
+ rsp = getRenderedServicePathFromSfc(entry);
+ }
+ LOG.info("getRenderedServicePath: rsp: {}", rsp);
+ return rsp;
+ }
+
+ private RenderedServicePath getRenderedServicePathFromRsp(String rspName) {
+ return sfcUtils.getRsp(rspName);
+ }
+
+ private RenderedServicePath getRenderedServicePathFromSfc (Ace entry) {
+ RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
+ LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
+ if (sfcRedirect == null) {
+ LOG.warn("processAClEntry: sfcRedirect is null");
+ return null;
+ }
+
+ String sfcName = sfcRedirect.getSfcName();
+ ServiceFunctionPath sfp = sfcUtils.getSfp(sfcName);
+ if (sfp == null || sfp.getName() == null) {
+ LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
+ return null;
+ }
+
+ LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcName, sfp);
+ // If RSP doesn't exist, create an RSP.
+ String sfpName = sfp.getName().getValue();
+ RenderedServicePath rsp = sfcUtils.getRspforSfp(sfpName);
+ String rspName = sfp.getName().getValue() + "_rsp";
+ if (rsp == null) {
+ LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName);
+ CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
+ .setParentServiceFunctionPath(sfpName)
+ .setName(rspName)
+ .setSymmetric(sfp.isSymmetric())
+ .build();
+ rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
+ if (rsp == null) {
+ LOG.warn("failed to add RSP");
+ return null;
+ }
+
+ // If SFP is symmetric, create RSP in the reverse direction.
+ if (sfp.isSymmetric()) {
+ LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
+ String rspNameRev = rspName + "-Reverse";
+ RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+ sfcUtils.getRspId(rspNameRev));
+ if (rspReverse == null) {
+ rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
+ if (rspReverse == null) {
+ LOG.warn("failed to add reverse RSP");
+ return null;
+ }
+ }
+ }
+ }
+ return rsp;
+ }
+
+ // loop through all ports looking for vxlan types, skip vxgpe, keep the rest
+ // first pass we only have two tunnels: one for normal vxlan and the other for gpe
+ // so just return the first non-gpe vxlan port
+ private long getTunnelOfPort(Node bridgeNode, String vxGpePortName) {
+ long port = 0L;
+ List<OvsdbTerminationPointAugmentation> ovsdbTerminationPointAugmentations =
+ southbound.getTerminationPointsOfBridge(bridgeNode);
+ if (!ovsdbTerminationPointAugmentations.isEmpty()) {
+ for (OvsdbTerminationPointAugmentation terminationPointAugmentation :
+ ovsdbTerminationPointAugmentations) {
+ if (terminationPointAugmentation.getInterfaceType() ==
+ SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(NETWORK_TYPE_VXLAN)) {
+ if (!terminationPointAugmentation.getName().equals(vxGpePortName)) {
+ port = terminationPointAugmentation.getOfport();
+ break;
+ }
+ }
+ }
+ }
+ 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);
+ }
+ 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();
+ }
+ }
+ }
+ 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.getTerminationPointOfBridge(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);
+ LOG.info("sfcClassifierService= {}", sfcClassifierService);
+ }
+}
+++ /dev/null
-/*
- * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services;
-
-import com.google.common.base.Preconditions;
-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.NodeCacheManager;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
-import org.opendaylight.ovsdb.openstack.netvirt.sfc.INetvirtSfcOF13Provider;
-import org.opendaylight.ovsdb.openstack.netvirt.sfc.SfcUtils;
-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.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.paths.RenderedServicePath;
-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.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.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.Classifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.Bridges;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider {
- private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcWorkaroundOF13Provider.class);
- private volatile NodeCacheManager nodeCacheManager;
- private volatile Southbound southbound;
- private MdsalUtils mdsalUtils;
- private SfcUtils sfcUtils;
- private SfcClassifierService sfcClassifierService;
-
- public NetvirtSfcWorkaroundOF13Provider(final DataBroker dataBroker, MdsalUtils mdsalUtils, SfcUtils sfcUtils) {
- Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
- Preconditions.checkNotNull(mdsalUtils, "Input mdsalUtils cannot be NULL!");
- Preconditions.checkNotNull(sfcUtils, "Input sfcUtils cannot be NULL!");
-
- this.mdsalUtils = mdsalUtils;
- this.sfcUtils = sfcUtils;
- this.setDependencies(null);
- }
-
- @Override
- public void addClassifierRules(Bridge bridge, Acl acl) {
-
- }
-
- @Override
- public void addClassifierRules(Bridges bridges, Acl acl) {
- Preconditions.checkNotNull(bridges, "Input bridges cannot be NULL!");
- Preconditions.checkNotNull(acl, "Input acl cannot be NULL!");
-
- for (Ace ace : acl.getAccessListEntries().getAce()) {
- processAclEntry(ace, bridges);
- }
- }
-
- @Override
- public void removeClassifierRules(Sff sff, Acl acl) {
-
- }
-
- @Override
- public void addClassifierRules(Acl acl) {
- String aclName = acl.getAclName();
- Classifiers classifiers = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, sfcUtils.getClassifierIid());
- if (classifiers == null) {
- LOG.debug("add: No Classifiers found");
- return;
- }
-
- LOG.debug("add: Classifiers: {}", classifiers);
- for (Classifier classifier : classifiers.getClassifier()) {
- if (classifier.getAcl().equals(aclName)) {
- if (classifier.getBridges() != null) {
- addClassifierRules(classifier.getBridges(), acl);
- }
- }
- }
- }
-
- @Override
- public void removeClassifierRules(Acl acl) {
-
- }
-
- private void processAclEntry(Ace entry, Bridges bridges) {
- Matches matches = entry.getMatches();
- Preconditions.checkNotNull(matches, "Input bridges cannot be NULL!");
-
- RenderedServicePath rsp = getRenderedServicePath(entry);
- if (rsp == null) {
- LOG.warn("Failed to get renderedServicePatch for entry: {}", entry);
- return;
- }
-
- //handleIngressClassifier();
- //handleEgressClassifier();
- //handleSfLoopback();
-
- }
-
- // loop through sf's:
- // - program arp responder
- // - program sf to sff
- // - program sff to sf
- private void handleSfWorkaround(RenderedServicePath rsp) {
-
- }
-
- private RenderedServicePath getRenderedServicePath (Ace entry) {
- RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
- LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
- if (sfcRedirect == null) {
- LOG.warn("processAClEntry: sfcRedirect is null");
- return null;
- }
-
- String sfcName = sfcRedirect.getRedirectSfc();
- ServiceFunctionPath sfp = sfcUtils.getSfp(sfcName);
- if (sfp == null || sfp.getName() == null) {
- LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
- return null;
- }
-
- LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcRedirect.getRedirectSfc(), sfp);
- // If RSP doesn't exist, create an RSP.
- String sfpName = sfp.getName().getValue();
- RenderedServicePath rsp = sfcUtils.getRspforSfp(sfpName);
- String rspName = sfp.getName().getValue() + "_rsp";
- if (rsp == null) {
- LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName);
- CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
- .setParentServiceFunctionPath(sfpName)
- .setName(rspName)
- .setSymmetric(sfp.isSymmetric())
- .build();
- rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
- if (rsp == null) {
- LOG.warn("failed to add RSP");
- return null;
- }
-
- // If SFP is symmetric, create RSP in the reverse direction.
- if (sfp.isSymmetric()) {
- LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
- String rspNameRev = rspName + "-Reverse";
- RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
- sfcUtils.getRspId(rspNameRev));
- if (rspReverse == null) {
- rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
- if (rspReverse == null) {
- LOG.warn("failed to add reverse RSP");
- return null;
- }
- }
- }
- }
- return rsp;
- }
-
- private void setDependencies(ServiceReference serviceReference) {
- nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
- southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
- sfcClassifierService = (SfcClassifierService) ServiceHelper.getGlobalInstance(SfcClassifierService.class, this);
- }
-}
package org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services;
+import com.google.common.collect.Lists;
+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.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
+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.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.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.action.types.rev131112.action.list.ActionKey;
+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.FlowCookie;
+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.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+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.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
+ private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
+ private static final short TABLE_0 = 0;
+ private static final short UDP_SHORT = 17;
+ static int cookieIndex = 0;
+
+ private enum FlowID {
+ FLOW_INGRESSCLASS(1), FLOW_SFINGRESS(2), FLOW_SFEGRESS(3), FLOW_SFARP(4),
+ FLOW_EGRESSCLASSUNUSED(5), FLOW_EGRESSCLASS(6), FLOW_EGRESSCLASSBYPASS(7), FLOW_SFCTABLE(8);
+
+ private int value;
+ FlowID(int value) {
+ this.value = value;
+ }
+
+ }
+
+ //private AtomicLong flowCookieInc = new AtomicLong(0x1L);
+ private BigInteger getCookie(FlowID flowID) {
+ String cookieString = new String().format("1110%02d%010d", flowID.value, cookieIndex++);
+ //new String().format("1100%02d00%04d", flowID.value, flowCookieInc.getAndIncrement());
+ // "1100%02000000d%04d"
+ return new BigInteger(cookieString, 16);
+ }
-public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface {
public SfcClassifierService(Service service) {
super(service);
}
@Override
public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
- super.setDependencies(bundleContext.getServiceReference(SfcClassifierService.class.getName()), this);
+ super.setDependencies(bundleContext.getServiceReference(ISfcClassifierService.class.getName()), this);
}
@Override
public void setDependencies(Object impl) {}
+
+ @Override
+ public void programIngressClassifier(long dataPathId, String ruleName, Matches matches,
+ NshUtils nshHeader, long vxGpeOfPort, boolean write) {
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ MatchBuilder matchBuilder = buildMatch(matches);
+ MatchUtils.addNxRegMatch(matchBuilder,
+ MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+ MatchUtils.addNxRegMatch(matchBuilder,
+ MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+ flowBuilder.setMatch(matchBuilder.build());
+
+ String flowId = "sfcIngressClass_" + ruleName;// + "_" + nshHeader.getNshNsp();
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setBarrier(true);
+ flowBuilder.setTableId(getTable());
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_INGRESSCLASS)));
+
+ if (write) {
+ ActionBuilder ab = new ActionBuilder();
+ List<Action> actionList = new ArrayList<>();
+
+ ab.setAction(ActionUtils.nxMoveTunIdtoNshc2());
+ ab.setOrder(actionList.size());
+ ab.setKey(new ActionKey(actionList.size()));
+ actionList.add(ab.build());
+
+ getNshAction(nshHeader, actionList);
+
+ ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dataPathId, vxGpeOfPort)));
+ ab.setOrder(actionList.size());
+ ab.setKey(new ActionKey(actionList.size()));
+ actionList.add(ab.build());
+
+ 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));
+ List<Instruction> instructions = Lists.newArrayList();
+ instructions.add(ib.build());
+
+ InstructionsBuilder isb = new InstructionsBuilder();
+ isb.setInstruction(instructions);
+ flowBuilder.setInstructions(isb.build());
+ writeFlow(flowBuilder, nodeBuilder);
+ } else {
+ removeFlow(flowBuilder, nodeBuilder);
+ }
+ }
+
+ @Override
+ public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
+ flowBuilder.setMatch(matchBuilder.build());
+
+ String flowId = "sfcTable_" + vxGpeOfPort;
+ 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);
+ flowBuilder.setPriority(1000);
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFCTABLE)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFCTABLE)));
+
+ if (write) {
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+ InstructionBuilder ib =
+ InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), goToTableId);
+ 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 programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
+ MatchUtils.addNxNspMatch(matchBuilder, nsp);
+ MatchUtils.addNxNsiMatch(matchBuilder, nsi);
+ flowBuilder.setMatch(matchBuilder.build());
+
+ String flowId = "sfcEgressClass1_" + vxGpeOfPort;
+ 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);
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSUNUSED)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSUNUSED)));
+
+ if (write) {
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+ InstructionBuilder ib = new InstructionBuilder();
+
+ /*List<Action> actionList = Lists.newArrayList();
+
+ ActionBuilder ab = new ActionBuilder();
+ ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
+ ab.setOrder(0);
+ ab.setKey(new ActionKey(0));
+ actionList.add(ab.build());
+
+ ApplyActionsBuilder aab = new ApplyActionsBuilder();
+ aab.setAction(actionList);
+ ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+ ib.setOrder(instructions.size());
+ ib.setKey(new InstructionKey(instructions.size()));
+ instructions.add(ib.build());*/
+
+ ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), getTable());
+ ib.setOrder(instructions.size());
+ ib.setKey(new InstructionKey(instructions.size()));
+ instructions.add(ib.build());
+
+ isb.setInstruction(instructions);
+ flowBuilder.setInstructions(isb.build());
+ writeFlow(flowBuilder, nodeBuilder);
+ } else {
+ removeFlow(flowBuilder, nodeBuilder);
+ }
+ }
+
+ @Override
+ public void programEgressClassifier(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ long sfOfPort, int tunnelId, boolean write) {
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort);
+ MatchUtils.addNxNspMatch(matchBuilder, nsp);
+ MatchUtils.addNxNsiMatch(matchBuilder, nsi);
+ flowBuilder.setMatch(matchBuilder.build());
+
+ String flowId = "sfcEgressClass_" + nsp + "_" + + nsi + "_" + vxGpeOfPort;
+ 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);
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASS)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASS)));
+
+ if (write) {
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+ List<Action> actionList = Lists.newArrayList();
+
+ ActionBuilder ab = new ActionBuilder();
+
+ ab.setAction(
+ ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(FlowUtils.REG_FIELD).build(),
+ BigInteger.valueOf(FlowUtils.REG_VALUE_FROM_LOCAL)));
+ ab.setOrder(actionList.size());
+ ab.setKey(new ActionKey(actionList.size()));
+ actionList.add(ab.build());
+
+ ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
+ ab.setOrder(actionList.size());
+ ab.setKey(new ActionKey(actionList.size()));
+ actionList.add(ab.build());
+
+ ab.setAction(ActionUtils.nxResubmitAction((int)sfOfPort, TABLE_0));
+ ab.setOrder(actionList.size());
+ ab.setKey(new ActionKey(actionList.size()));
+ actionList.add(ab.build());
+
+ 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());
+
+ isb.setInstruction(instructions);
+ flowBuilder.setInstructions(isb.build());
+ writeFlow(flowBuilder, nodeBuilder);
+ } else {
+ removeFlow(flowBuilder, nodeBuilder);
+ }
+ }
+
+ @Override
+ public void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+ long sfOfPort, int tunnelId, boolean write) {
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createInPortMatch(matchBuilder, dataPathId, sfOfPort);
+ MatchUtils.addNxRegMatch(matchBuilder,
+ MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+ MatchUtils.addNxNspMatch(matchBuilder, nsp);
+ MatchUtils.addNxNsiMatch(matchBuilder, nsi);
+ flowBuilder.setMatch(matchBuilder.build());
+
+ String flowId = "sfcEgressClassBypass_" + nsp + "_" + + nsi + "_" + sfOfPort;
+ 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);
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSBYPASS)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_EGRESSCLASSBYPASS)));
+ flowBuilder.setPriority(40000); //Needs to be above default priority of 32768
+
+ if (write) {
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+
+ InstructionBuilder ib;
+ ib = this.getMutablePipelineInstructionBuilder();
+ 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);
+ }
+ }
+
+ // 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);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
+ MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
+ MatchUtils.addNxRegMatch(matchBuilder,
+ MatchUtils.RegMatch.of(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+ flowBuilder.setMatch(matchBuilder.build());
+
+ String flowId = "sfEgress_" + dstPort;
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setBarrier(true);
+ flowBuilder.setTableId(getTable());
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFEGRESS)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFEGRESS)));
+
+ if (write) {
+ InstructionBuilder ib = new InstructionBuilder();
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+ InstructionUtils.createLocalInstructions(ib, dataPathId);
+ 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);
+ }
+ }
+
+ // 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));
+ MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort);
+ flowBuilder.setMatch(matchBuilder.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);
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFINGRESS)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFINGRESS)));
+
+ 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.createInPortReservedMatch(matchBuilder, dataPathId, OutputPortValues.LOCAL.toString());
+ 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);
+ flowBuilder.setCookie(new FlowCookie(getCookie(FlowID.FLOW_SFARP)));
+ flowBuilder.setCookieMask(new FlowCookie(getCookie(FlowID.FLOW_SFARP)));
+
+ 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(FlowUtils.ARP_OP_REPLY)));
+ 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 =
+ ActionUtils.nxLoadNshc1RegAction(header.getNshMetaC1());
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC2Load =
+ ActionUtils.nxLoadNshc2RegAction(header.getNshMetaC2());
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nspLoad =
+ ActionUtils.nxSetNspAction(header.getNshNsp());
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nsiLoad =
+ ActionUtils.nxSetNsiAction(header.getNshNsi());
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
+ ActionUtils.nxLoadTunIdAction(BigInteger.valueOf(header.getNshNsp()), false);
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
+ ActionUtils.nxLoadTunIPv4Action(header.getNshTunIpDst().getValue(), false);
+
+ int count = actionList.size();
+ actionList.add(new ActionBuilder()
+ .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC1Load).build());
+ //actionList.add(new ActionBuilder()
+ // .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC2Load).build());
+ actionList.add(new ActionBuilder()
+ .setKey(new ActionKey(count)).setOrder(count++).setAction(nspLoad).build());
+ actionList.add(new ActionBuilder()
+ .setKey(new ActionKey(count)).setOrder(count++).setAction(nsiLoad).build());
+ actionList.add(new ActionBuilder()
+ .setKey(new ActionKey(count)).setOrder(count++).setAction(loadChainTunDest).build());
+ actionList.add(new ActionBuilder()
+ .setKey(new ActionKey(count)).setOrder(count).setAction(loadChainTunVnid).build());
+ return actionList;
+ }
+
+ public MatchBuilder buildMatch(Matches matches) {
+ MatchBuilder matchBuilder = new MatchBuilder();
+
+ if (matches.getAceType() instanceof AceIp) {
+ AceIp aceIp = (AceIp)matches.getAceType();
+ if (aceIp.getAceIpVersion() instanceof AceIpv4) {
+ //AceIpv4 aceIpv4 = (AceIpv4) aceIp.getAceIpVersion();
+ //MatchUtils.createSrcL3IPv4Match(matchBuilder, aceIpv4.getSourceIpv4Network());
+ //MatchUtils.createDstL3IPv4Match(matchBuilder, aceIpv4.getDestinationIpv4Network());
+ MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
+ MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
+ aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
+ } else {
+ MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
+ MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
+ aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
+ }
+ } else if (matches.getAceType() instanceof AceEth) {
+ AceEth aceEth = (AceEth) matches.getAceType();
+ MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(aceEth.getSourceMacAddress().getValue()));
+ MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(aceEth.getDestinationMacAddress().getValue()),
+ new MacAddress(aceEth.getDestinationMacAddressMask().getValue()));
+ }
+
+ LOG.info("buildMatch: {}", matchBuilder.build());
+ return matchBuilder;
+ }
}
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;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.SfcClassifier;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.AclUtils;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ClassifierUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionChainUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionPathUtils;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.SfcUtils;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionForwarderUtils;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionUtils;
import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctions;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.entry.SfDataPlaneLocator;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.entry.SfDataPlaneLocatorBuilder;
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.sf.rev140701.service.functions.ServiceFunctionBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChains;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChainsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChain;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChainBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunction;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunctionBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwarders;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwardersBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionary;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionaryBuilder;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.SffDataPlaneLocator;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.SffDataPlaneLocatorBuilder;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.service.function.dictionary.SffSfDataPlaneLocatorBuilder;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.sff.data.plane.locator.DataPlaneLocatorBuilder;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.Dpi;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
+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.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.Firewall;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessLists;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessListsBuilder;
private static SfcUtils sfcUtils = new SfcUtils();
private static ServiceFunctionUtils serviceFunctionUtils = new ServiceFunctionUtils();
private static ServiceFunctionForwarderUtils serviceFunctionForwarderUtils = new ServiceFunctionForwarderUtils();
+ private static ServiceFunctionChainUtils serviceFunctionChainUtils = new ServiceFunctionChainUtils();
+ private static ServiceFunctionPathUtils serviceFunctionPathUtils = new ServiceFunctionPathUtils();
private static MdsalUtils mdsalUtils;
private static AtomicBoolean setup = new AtomicBoolean(false);
private static SouthboundUtils southboundUtils;
public static final String INTEGRATION_BRIDGE_NAME = "br-int";
private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
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 = "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"; //"192.168.1.129"
+ private static final String SFF2IP = "192.168.1.129";//"127.0.0.1";
+ private static final String SFF1NAME = "SFF1";
+ private static final String SFF2NAME = "SFF2";
+ private static final String SFFDPL1NAME = "vxgpe";
+ private static final String SFFDPL2NAME = "vxgpe";
+ private static final String SN1NAME = "OVSDB1";
+ private static final String SN2NAME = "OVSDB2";
+ private static final String BRIDGE1NAME= "br-int";
+ private static final String BRIDGE2NAME= "br-int";
+ private static final String ACLNAME= "httpAcl";
+ private static final String SFCNAME = "SFC";
+ private static final int GPEPORT = 6633;
@Override
public String getModuleName() {
editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
"log4j.logger.org.opendaylight.ovsdb",
LogLevelOption.LogLevel.TRACE.name())),
+ //editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+ // "log4j.logger.org.opendaylight.ovsdb",
+ // LogLevelOption.LogLevel.TRACE.name()),
editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
logConfiguration(NetvirtSfcIT.class),
LogLevel.INFO.name()),
"log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.sfc",
LogLevel.TRACE.name()),
editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
- "log4j.logger.org.opendaylight.ovsdb.sfc",
+ "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()),
super.getLoggingOption());
}
assertTrue(true);
}
- private AccessListsBuilder setAccessLists () {
+ private AccessListsBuilder accessListsBuilder() {
MatchesBuilder matchesBuilder = aclUtils.matchesBuilder(new MatchesBuilder(), 80);
- ActionsBuilder actionsBuilder = aclUtils.actionsBuilder(new ActionsBuilder(), Boolean.TRUE);
- AceBuilder accessListEntryBuilder = aclUtils.aceBuilder(
- new AceBuilder(), "http", matchesBuilder, actionsBuilder);
- AccessListEntriesBuilder accessListEntriesBuilder = aclUtils.accessListEntriesBuidler(
- new AccessListEntriesBuilder(), accessListEntryBuilder);
- AclBuilder accessListBuilder = aclUtils.aclBuilder(new AclBuilder(),
- "http", accessListEntriesBuilder);
- AccessListsBuilder accessListsBuilder = aclUtils.accessListsBuidler(new AccessListsBuilder(),
- accessListBuilder);
+ LOG.info("Matches: {}", matchesBuilder.build());
+ //ActionsBuilder actionsBuilder = aclUtils.actionsBuilder(new ActionsBuilder(), Boolean.TRUE);
+ ActionsBuilder actionsBuilder = aclUtils.actionsBuilder(new ActionsBuilder(), SFCNAME);
+ AceBuilder accessListEntryBuilder =
+ aclUtils.aceBuilder(new AceBuilder(), "httpRule", matchesBuilder, actionsBuilder);
+ AccessListEntriesBuilder accessListEntriesBuilder =
+ aclUtils.accessListEntriesBuidler(new AccessListEntriesBuilder(), accessListEntryBuilder);
+ AclBuilder accessListBuilder =
+ aclUtils.aclBuilder(new AclBuilder(), ACLNAME, accessListEntriesBuilder);
+ AccessListsBuilder accessListsBuilder =
+ aclUtils.accesslistsbuilder(new AccessListsBuilder(), accessListBuilder);
LOG.info("AccessLists: {}", accessListsBuilder.build());
return accessListsBuilder;
}
@Test
public void testAccessLists() throws InterruptedException {
- testModel(setAccessLists(), AccessLists.class, 0);
+ testModel(accessListsBuilder(), AccessLists.class, 0);
}
- private ClassifiersBuilder setClassifiers() {
- SffBuilder sffBuilder = classifierUtils.sffBuilder(new SffBuilder(), "sffname");
+ private ClassifiersBuilder classifiersBuilder() {
+ SffBuilder sffBuilder = classifierUtils.sffBuilder(new SffBuilder(), SFF1NAME);
SffsBuilder sffsBuilder = classifierUtils.sffsBuilder(new SffsBuilder(), sffBuilder);
ClassifierBuilder classifierBuilder = classifierUtils.classifierBuilder(new ClassifierBuilder(),
- "classifierName", "aclName", sffsBuilder);
+ "classifierName", ACLNAME, sffsBuilder);
ClassifiersBuilder classifiersBuilder = classifierUtils.ClassifiersBuilder(new ClassifiersBuilder(),
classifierBuilder);
LOG.info("Classifiers: {}", classifiersBuilder.build());
@Test
public void testClassifiers() throws InterruptedException {
- testModel(setClassifiers(), Classifiers.class, 0);
+ testModel(classifiersBuilder(), Classifiers.class, 0);
}
private SfcBuilder netvirtSfcBuilder() {
testModel(netvirtSfcBuilder(), Sfc.class, 0);
}
- private <T extends DataObject> void testModel(Builder<T> builder, Class<T> clazz, long wait)
- throws InterruptedException {
+ private <T extends DataObject> void testModelPut(Builder<T> builder, Class<T> clazz) {
InstanceIdentifier<T> path = InstanceIdentifier.create(clazz);
assertTrue(mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, path, builder.build()));
T result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
assertNotNull(clazz.getSimpleName() + " should not be null", result);
- Thread.sleep(wait);
+ }
+
+ private <T extends DataObject> void testModelDelete(Builder<T> builder, Class<T> clazz)
+ throws InterruptedException {
+ InstanceIdentifier<T> path = InstanceIdentifier.create(clazz);
assertTrue("Failed to remove " + clazz.getSimpleName(),
mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, path));
- result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
+ T result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
assertNull(clazz.getSimpleName() + " should be null", result);
}
+ private <T extends DataObject> void testModel(Builder<T> builder, Class<T> clazz, long wait)
+ throws InterruptedException {
+ testModelPut(builder, clazz);
+ Thread.sleep(wait);
+ testModelDelete(builder, clazz);
+ }
+
private ServiceFunctionsBuilder serviceFunctionsBuilder() {
- SfDataPlaneLocatorBuilder sfDataPlaneLocator =
- serviceFunctionUtils.sfDataPlaneLocatorBuilder(new SfDataPlaneLocatorBuilder(),
- "192.168.120.31", 6633, "testDpl1-1234-uuid", "testSff1");
- List<SfDataPlaneLocator> sfDataPlaneLocatorList = serviceFunctionUtils.list(
- new ArrayList<SfDataPlaneLocator>(), sfDataPlaneLocator);
+ String sf1Name = SF1NAME;
+ String sf1Ip = SF1IP;
+ String sff1Ip = SF1IP;
+ String sff1Name = SFF1NAME;
+ String sf1DplName = SF1DPLNAME;
+ String sn1Name = SN1NAME;
+ String bridge1Name= BRIDGE1NAME;
+ String sf2Name = SF2NAME;
+ String sf2Ip = SF2IP;
+ String sff2Ip = SF2IP;
+ String sff2Name = SFF2NAME;
+ String sf2DplName = SF2DPLNAME;
+ String sn2Name = SN2NAME;
+ String bridge2Name= BRIDGE2NAME;
+ int port = GPEPORT;
+
ServiceFunctionBuilder serviceFunctionBuilder =
- serviceFunctionUtils.serviceFunctionBuidler(new ServiceFunctionBuilder(),
- "192.168.120.31", "testSf", sfDataPlaneLocatorList, Firewall.class);
+ serviceFunctionUtils.serviceFunctionBuilder(sf1Ip, port, sf1DplName, sff1Name, sf1Name);
List<ServiceFunction> serviceFunctionList = serviceFunctionUtils.list(
new ArrayList<ServiceFunction>(), serviceFunctionBuilder);
- sfDataPlaneLocator =
- serviceFunctionUtils.sfDataPlaneLocatorBuilder(new SfDataPlaneLocatorBuilder(),
- "192.168.120.32", 6633, "testDpl2-1234-uuid", "testSff2");
- sfDataPlaneLocatorList = serviceFunctionUtils.list(
- new ArrayList<SfDataPlaneLocator>(), sfDataPlaneLocator);
- serviceFunctionBuilder =
- serviceFunctionUtils.serviceFunctionBuidler(new ServiceFunctionBuilder(),
- "192.168.120.32", "testSf2", sfDataPlaneLocatorList, Dpi.class);
- serviceFunctionList = serviceFunctionUtils.list(
- serviceFunctionList, serviceFunctionBuilder);
+ //serviceFunctionBuilder =
+ // serviceFunctionUtils.serviceFunctionBuilder(sf2Ip, port, sffDpl2Name, sff2Name, sf2Name);
+ //serviceFunctionList = serviceFunctionUtils.list(
+ // serviceFunctionList, serviceFunctionBuilder);
ServiceFunctionsBuilder serviceFunctionsBuilder =
serviceFunctionUtils.serviceFunctionsBuilder(new ServiceFunctionsBuilder(),
}
private ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder() {
- String sf1Name = "firewall-72";
- String sff1Ip = "192.168.120.31";
- String sff1Name = "SFF1";
- String sffDpl1Name = "sfc-tun2";
- String sn1Name = "OVSDB2";
- String bridge1Name= "sw2";
- int port = 6633;
-
- DataPlaneLocatorBuilder dataPlaneLocatorBuilder =
- serviceFunctionForwarderUtils.dataPlaneLocatorBuilder(
- new DataPlaneLocatorBuilder(), sff1Ip, port);
- SffDataPlaneLocatorBuilder sffDataPlaneLocatorBuilder =
- serviceFunctionForwarderUtils.sffDataPlaneLocatorBuilder(
- new SffDataPlaneLocatorBuilder(), dataPlaneLocatorBuilder, sffDpl1Name);
- List<SffDataPlaneLocator> sffDataPlaneLocatorList = serviceFunctionForwarderUtils.list(
- new ArrayList<SffDataPlaneLocator>(), sffDataPlaneLocatorBuilder);
-
- SffSfDataPlaneLocatorBuilder sffSfDataPlaneLocatorBuilder =
- serviceFunctionForwarderUtils.sffSfDataPlaneLocatorBuilder(
- new SffSfDataPlaneLocatorBuilder(), sff1Ip, port);
- ServiceFunctionDictionaryBuilder serviceFunctionDictionaryBuilder =
- serviceFunctionForwarderUtils.serviceFunctionDictionaryBuilder(
- new ServiceFunctionDictionaryBuilder(), sf1Name, Firewall.class,
- sffSfDataPlaneLocatorBuilder);
- List<ServiceFunctionDictionary> serviceFunctionDictionaryList = serviceFunctionForwarderUtils.list(
- new ArrayList<ServiceFunctionDictionary>(), serviceFunctionDictionaryBuilder);
+ String sf1Name = SF1NAME;
+ String sf1Ip = SF1IP;
+ String sff1Ip = SFF1IP;
+ String sff1Name = SFF1NAME;
+ String sffDpl1Name = SFFDPL1NAME;
+ String sn1Name = SN1NAME;
+ String bridge1Name= BRIDGE1NAME;
+ String sf2Name = SF2NAME;
+ String sf2Ip = SF2IP;
+ String sff2Ip = SFF2IP;
+ String sff2Name = SFF2NAME;
+ String sffDpl2Name = SFFDPL2NAME;
+ String sn2Name = SN2NAME;
+ String bridge2Name= BRIDGE2NAME;
+ String aclName = ACLNAME;
+ int port = GPEPORT;
ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
- new ServiceFunctionForwarderBuilder(), sff1Name, sn1Name, bridge1Name,
- sffDataPlaneLocatorList, serviceFunctionDictionaryList);
+ sff1Name, sff1Ip, port, sffDpl1Name, sf1Name, sf1Ip, sn1Name, bridge1Name, Firewall.class);
List<ServiceFunctionForwarder> serviceFunctionForwarderList = serviceFunctionForwarderUtils.list(
new ArrayList<ServiceFunctionForwarder>(), serviceFunctionForwarderBuilder);
+
+ //serviceFunctionForwarderBuilder =
+ // serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
+ // sff2Name, sff2Ip, port, sffDpl2Name, sf2Name, sff2Ip, sn2Name, bridge2Name, Dpi.class);
+ //serviceFunctionForwarderList = serviceFunctionForwarderUtils.list(
+ // serviceFunctionForwarderList, serviceFunctionForwarderBuilder);
+
ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder =
serviceFunctionForwarderUtils.serviceFunctionForwardersBuilder(
new ServiceFunctionForwardersBuilder(), serviceFunctionForwarderList);
return serviceFunctionForwardersBuilder;
}
+ private ServiceFunctionChainsBuilder serviceFunctionChainsBuilder() {
+ String sf1Name = "firewall-abstract1";
+ String sf2Name = "dpi-abstract1";
+ String sfcName = SFCNAME;
+
+ SfcServiceFunctionBuilder sfcServiceFunctionBuilder = serviceFunctionChainUtils.sfcServiceFunctionBuilder(
+ new SfcServiceFunctionBuilder(), sf1Name, Firewall.class);
+ List<SfcServiceFunction> sfcServiceFunctionList =
+ serviceFunctionChainUtils.list(new ArrayList<SfcServiceFunction>(), sfcServiceFunctionBuilder);
+
+ //sfcServiceFunctionBuilder = serviceFunctionChainUtils.sfcServiceFunctionBuilder(
+ // sfcServiceFunctionBuilder, sf2Name, Dpi.class);
+ //sfcServiceFunctionList = serviceFunctionChainUtils.list(sfcServiceFunctionList, sfcServiceFunctionBuilder);
+
+ ServiceFunctionChainBuilder serviceFunctionChainBuilder =
+ serviceFunctionChainUtils.serviceFunctionChainBuilder(
+ new ServiceFunctionChainBuilder(), sfcName, false, sfcServiceFunctionList);
+ ServiceFunctionChainsBuilder serviceFunctionChainsBuilder =
+ serviceFunctionChainUtils.serviceFunctionChainsBuilder(
+ new ServiceFunctionChainsBuilder(),
+ serviceFunctionChainUtils.list(new ArrayList<ServiceFunctionChain>(),
+ serviceFunctionChainBuilder));
+ LOG.info("ServiceFunctionChains: {}", serviceFunctionChainBuilder.build());
+ return serviceFunctionChainsBuilder;
+ }
+
+ private ServiceFunctionPathsBuilder serviceFunctionPathsBuilder() {
+ String sfpName = "SFC-Path";
+ String sfcName = "SFC";
+ short startingIndex = 255;
+
+ ServiceFunctionPathBuilder serviceFunctionPathBuilder =
+ serviceFunctionPathUtils.serviceFunctionPathBuilder(
+ new ServiceFunctionPathBuilder(), sfpName, sfcName, startingIndex, false);
+ ServiceFunctionPathsBuilder serviceFunctionPathsBuilder =
+ serviceFunctionPathUtils.serviceFunctionPathsBuilder(
+ serviceFunctionPathUtils.list(new ArrayList<ServiceFunctionPath>(),
+ serviceFunctionPathBuilder));
+ LOG.info("ServiceFunctionPaths: {}", serviceFunctionPathsBuilder.build());
+ return serviceFunctionPathsBuilder;
+ }
+
@Test
public void testSfcModel() throws InterruptedException {
testModel(serviceFunctionsBuilder(), ServiceFunctions.class, 3000);
testModel(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class, 3000);
+ testModel(serviceFunctionChainsBuilder(), ServiceFunctionChains.class, 3000);
+ testModel(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class, 3000);
+ }
+
+ @Test
+ public void testSfcModels() throws InterruptedException {
+ String bridgeName = INTEGRATION_BRIDGE_NAME;
+ ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
+ assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
+ Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
+ 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", "f6:00:00:0f:00:01");
+ 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);
+ testModelPut(serviceFunctionChainsBuilder(), ServiceFunctionChains.class);
+ testModelPut(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class);
+
+ Thread.sleep(5000);
+
+ testModelPut(accessListsBuilder(), AccessLists.class);
+ testModelPut(classifiersBuilder(), Classifiers.class);
+
+ Thread.sleep(10000);
+
+ ISfcClassifierService sfcClassifierService = (ISfcClassifierService) ServiceHelper.getGlobalInstance(ISfcClassifierService.class, this);
+ LOG.info("SfcClassifierService: {}", sfcClassifierService);
+ readwait();
+ //sfcClassifierService.programIngressClassifier(datapathId);
+
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
+ FlowBuilder flowBuilder = getSfcIngressClassifierFlowBuilder();
+ Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+ assertNotNull("Could not find flow in config", flow);
+ flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+ assertNotNull("Could not find flow in operational", flow);
+
+ assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
+ Thread.sleep(1000);
+ assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
}
/*
return flowBuilder;
}
+ private FlowBuilder getSfcIngressClassifierFlowBuilder() {
+ FlowBuilder flowBuilder = new FlowBuilder();
+ String flowId = "sfcClass_" + "httpRule";
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setTableId((short)10);
+ return flowBuilder;
+ }
+
private Flow getFlow (FlowBuilder flowBuilder, NodeBuilder nodeBuilder, LogicalDatastoreType store)
throws InterruptedException {
Flow flow = null;
for (int i = 0; i < 10; i++) {
flow = FlowUtils.getFlow(flowBuilder, nodeBuilder, dataBroker.newReadOnlyTransaction(), store);
if (flow != null) {
- LOG.info("getFlow: flow({}): {}", store, flow);
+ LOG.info("getFlow: flow: {}: {}", store, flow);
break;
}
Thread.sleep(1000);
}
return flow;
}
+
+ private void readwait() {
+ try {
+ System.in.read();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
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.AceIpv4Builder;
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.packet.fields.rev150611.acl.transport.header.fields.DestinationPortRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfcBuilder;
public class AclUtils extends AbstractUtils {
public MatchesBuilder matchesBuilder(MatchesBuilder matchesBuilder, int destPort) {
return actionsBuilder.setPacketHandling(new PermitBuilder().setPermit(permit).build());
}
+ public ActionsBuilder actionsBuilder(ActionsBuilder actionsBuilder, String sfcName) {
+ RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder().setSfcName(sfcName);
+
+ return actionsBuilder.addAugmentation(RedirectToSfc.class, redirectToSfcBuilder.build());
+ }
+
public AceBuilder aceBuilder(AceBuilder accessListEntryBuilder,
String ruleName,
MatchesBuilder matchesBuilder,
}
public AccessListEntriesBuilder accessListEntriesBuidler(AccessListEntriesBuilder accessListEntriesBuilder,
- AceBuilder accessListEntryBuilder) {
- List<Ace> accessListEntriesList = new ArrayList<>();
- accessListEntriesList.add(accessListEntryBuilder.build());
+ AceBuilder aceBuilder) {
+ List<Ace> aceList = new ArrayList<>();
+ aceList.add(aceBuilder.build());
- return accessListEntriesBuilder;
+ return accessListEntriesBuilder.setAce(aceList);
}
- public AclBuilder aclBuilder(AclBuilder accessListBuilder,
+ public AclBuilder aclBuilder(AclBuilder aclBuilder,
String aclName,
AccessListEntriesBuilder accessListEntriesBuilder) {
- return accessListBuilder
+ return aclBuilder
.setAclName(aclName)
.setAccessListEntries(accessListEntriesBuilder.build());
}
- public AccessListsBuilder accessListsBuidler(AccessListsBuilder accessListsBuilder,
- AclBuilder accessListBuilder) {
- List<Acl> accessListList = new ArrayList<>();
- accessListList.add(accessListBuilder.build());
- accessListsBuilder.setAcl(accessListList);
+ public AccessListsBuilder accesslistsbuilder(AccessListsBuilder accessListsBuilder,
+ AclBuilder aclBuilder) {
+ List<Acl> aclList = new ArrayList<>();
+ aclList.add(aclBuilder.build());
- return accessListsBuilder;
+ return accessListsBuilder.setAcl(aclList);
}
}
--- /dev/null
+/*
+ * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
+
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
+
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChainsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChain;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChainBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunction;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunctionBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.ServiceFunctionTypeIdentity;
+
+public class ServiceFunctionChainUtils extends AbstractUtils {
+ public SfcServiceFunctionBuilder sfcServiceFunctionBuilder(SfcServiceFunctionBuilder sfcServiceFunctionBuilder,
+ String name,
+ Class<? extends ServiceFunctionTypeIdentity> type) {
+ return sfcServiceFunctionBuilder
+ .setName(name)
+ .setType(type);
+ }
+
+ public ServiceFunctionChainBuilder serviceFunctionChainBuilder(
+ ServiceFunctionChainBuilder serviceFunctionChainBuilder, String name, Boolean symmetric,
+ List<SfcServiceFunction> sfcServiceFunctionList) {
+
+ return serviceFunctionChainBuilder
+ .setName(SfcName.getDefaultInstance(name))
+ .setSymmetric(symmetric)
+ .setSfcServiceFunction(sfcServiceFunctionList);
+ }
+
+ public ServiceFunctionChainsBuilder serviceFunctionChainsBuilder(
+ ServiceFunctionChainsBuilder serviceFunctionChainsBuilder,
+ List<ServiceFunctionChain> serviceFunctionChainBuilderList) {
+
+ return serviceFunctionChainsBuilder.setServiceFunctionChain(serviceFunctionChainBuilderList);
+ }
+}
package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
+import java.util.ArrayList;
import java.util.List;
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.common.rev151017.SffDataPlaneLocatorName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SnName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsBridgeAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsLocatorOptionsAugmentation;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsLocatorOptionsAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.bridge.OvsBridgeBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.options.OvsOptionsBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwardersBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.sff.data.plane.locator.DataPlaneLocatorBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.ServiceFunctionTypeIdentity;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.VxlanGpe;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
public class ServiceFunctionForwarderUtils extends AbstractUtils {
public OvsOptionsBuilder ovsOptionsBuilder(OvsOptionsBuilder ovsOptionsBuilder, int port) {
.setSffSfDataPlaneLocator(sffSfDataPlaneLocatorBuilder.build());
}
+ public OvsBridgeBuilder ovsBridgeBuilder(OvsBridgeBuilder ovsBridgeBuilder, String bridgeNme) {
+ return ovsBridgeBuilder.setBridgeName(bridgeNme);
+ }
+
public ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder(
ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder,
String sffName, String serviceNodeName, String bridgeName,
List<SffDataPlaneLocator> sffDataPlaneLocatorList,
List<ServiceFunctionDictionary> serviceFunctionDictionaryList) {
+ SffOvsBridgeAugmentationBuilder sffOvsBridgeAugmentationBuilder = new SffOvsBridgeAugmentationBuilder();
+ sffOvsBridgeAugmentationBuilder.setOvsBridge(ovsBridgeBuilder(new OvsBridgeBuilder(), bridgeName).build());
+
return serviceFunctionForwarderBuilder
.setName(new SffName(sffName))
.setServiceNode(new SnName(serviceNodeName))
.setServiceFunctionDictionary(serviceFunctionDictionaryList)
- .setSffDataPlaneLocator(sffDataPlaneLocatorList);
+ .setSffDataPlaneLocator(sffDataPlaneLocatorList)
+ .addAugmentation(SffOvsBridgeAugmentation.class, sffOvsBridgeAugmentationBuilder.build());
}
public ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder(
List<ServiceFunctionForwarder> serviceFunctionForwarderList) {
return serviceFunctionForwardersBuilder.setServiceFunctionForwarder(serviceFunctionForwarderList);
}
+
+ public ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder(
+ String sffName, String sffIp, int port, String sffDplName,
+ String sfName, String sfIp, String snName, String bridgeName,
+ Class<? extends ServiceFunctionTypeIdentity> type) {
+
+ DataPlaneLocatorBuilder dataPlaneLocatorBuilder =
+ dataPlaneLocatorBuilder(new DataPlaneLocatorBuilder(), sffIp, port);
+ SffDataPlaneLocatorBuilder sffDataPlaneLocatorBuilder =
+ sffDataPlaneLocatorBuilder( new SffDataPlaneLocatorBuilder(), dataPlaneLocatorBuilder, sffDplName);
+ List<SffDataPlaneLocator> sffDataPlaneLocatorList =
+ list(new ArrayList<SffDataPlaneLocator>(), sffDataPlaneLocatorBuilder);
+
+ SffSfDataPlaneLocatorBuilder sffSfDataPlaneLocatorBuilder =
+ sffSfDataPlaneLocatorBuilder(new SffSfDataPlaneLocatorBuilder(), sffIp, port);
+ ServiceFunctionDictionaryBuilder serviceFunctionDictionaryBuilder =
+ serviceFunctionDictionaryBuilder(new ServiceFunctionDictionaryBuilder(), sfName, type,
+ sffSfDataPlaneLocatorBuilder);
+ List<ServiceFunctionDictionary> serviceFunctionDictionaryList =
+ list(new ArrayList<ServiceFunctionDictionary>(), serviceFunctionDictionaryBuilder);
+
+ ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
+ serviceFunctionForwarderBuilder(
+ new ServiceFunctionForwarderBuilder(), sffName, snName, bridgeName,
+ sffDataPlaneLocatorList, serviceFunctionDictionaryList);
+ return serviceFunctionForwarderBuilder;
+ }
}
--- /dev/null
+/*
+ * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
+
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
+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.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
+
+public class ServiceFunctionPathUtils extends AbstractUtils {
+ public ServiceFunctionPathBuilder serviceFunctionPathBuilder(
+ ServiceFunctionPathBuilder serviceFunctionPathBuilder,
+ String sfpName, String sfcName, short startingIndex, Boolean symmetric) {
+
+ return serviceFunctionPathBuilder
+ .setSymmetric(symmetric)
+ .setName(SfpName.getDefaultInstance(sfpName))
+ .setServiceChainName(SfcName.getDefaultInstance(sfcName))
+ .setStartingIndex(startingIndex);
+ }
+
+ public ServiceFunctionPathsBuilder serviceFunctionPathsBuilder(
+ List<ServiceFunctionPath> serviceFunctionPathList) {
+
+ return new ServiceFunctionPathsBuilder().setServiceFunctionPath(serviceFunctionPathList);
+ }
+}
package org.opendaylight.ovsdb.openstack.netvirt.sfc.utils;
+import java.util.ArrayList;
import java.util.List;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfDataPlaneLocatorName;
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.sf.rev140701.service.function.entry.SfDataPlaneLocatorBuilder;
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.sf.rev140701.service.functions.ServiceFunctionBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.Firewall;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.ServiceFunctionTypeIdentity;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.VxlanGpe;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
.setServiceFunctionForwarder(new SffName(sffName));
}
- public ServiceFunctionBuilder serviceFunctionBuidler(ServiceFunctionBuilder serviceFunctionBuilder,
+ public ServiceFunctionBuilder serviceFunctionBuilder(ServiceFunctionBuilder serviceFunctionBuilder,
String ip, String sfName,
List<SfDataPlaneLocator> sfDataPlaneLocatorList,
Class<? extends ServiceFunctionTypeIdentity> type) {
List<ServiceFunction> serviceFunctionList) {
return serviceFunctionsBuilder.setServiceFunction(serviceFunctionList);
}
+
+ public ServiceFunctionBuilder serviceFunctionBuilder(String sfIp, int port, String sf1DplName,
+ String sffname, String sfName) {
+ SfDataPlaneLocatorBuilder sfDataPlaneLocator =
+ sfDataPlaneLocatorBuilder(new SfDataPlaneLocatorBuilder(), sfIp, port, sf1DplName, sffname);
+ List<SfDataPlaneLocator> sfDataPlaneLocatorList =
+ list(new ArrayList<SfDataPlaneLocator>(), sfDataPlaneLocator);
+ return serviceFunctionBuilder(
+ new ServiceFunctionBuilder(), sfIp, sfName, sfDataPlaneLocatorList, Firewall.class);
+ }
+
+
}
public static final String OVSDB_URI_PREFIX = "ovsdb";
public static final String BRIDGE_URI_PREFIX = "bridge";
public static final String TP_URI_PREFIX = "termination-point";
+ public static final String DISABLE_IN_BAND = "disable-in-band";
public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
= new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
ovsdbBridgeAugmentationBuilder.setFailMode(
MdsalHelper.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
+ BridgeOtherConfigsBuilder bridgeOtherConfigsBuilder = new BridgeOtherConfigsBuilder();
+ bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(MdsalHelper.DISABLE_IN_BAND);
+ bridgeOtherConfigsBuilder.setBridgeOtherConfigValue("true");
+ bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(MdsalHelper.DISABLE_IN_BAND);
+ List<BridgeOtherConfigs> bridgeOtherConfigsList = new ArrayList<>();
+ bridgeOtherConfigsList.add(bridgeOtherConfigsBuilder.build());
+ ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(bridgeOtherConfigsList);
setManagedByForBridge(ovsdbBridgeAugmentationBuilder, ovsdbNode.getKey());
if (isOvsdbNodeDpdk(ovsdbNode)) {
ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
--- /dev/null
+{
+ "id":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "name":"Ovsdb HwvtepSouthbound",
+ "timestamp":1424977469540,
+ "order":[
+ "e9ff6957-4dc2-9257-c0c6-21560bfd5de2",
+ "ee151670-85a0-30ec-b22b-5defe7b66e0b",
+ "6de1ede7-817c-ccbb-3df9-ef510bdaf583",
+ "6e7c88e4-485d-ab9f-4c3a-cc235e022905",
+ "92ee7422-5b08-6d63-2b95-961ec0e18ffa",
+ "e92ac963-daaf-0899-c3e8-a00d897be0e2",
+ "9bc22ca7-049c-af51-7c12-6bf71044b2ec",
+ "f6d300f7-380a-d090-0d4a-2b2ddefe5104",
+ "f9f71d74-a49d-b190-d929-b6772ce0ba73",
+ "18032e93-3bc5-9976-4525-fe1e77e98207",
+ "22354294-1d01-cebf-180c-d609747be9bc",
+ "c8e8f3fd-3bfb-aafa-e3ec-a671a942f426",
+ "d362ddc4-1c5f-67d5-e354-c2a8d2ba9d79",
+ "538c71b3-e3e6-f01b-cc4c-d2b686686aa8"
+ ],
+ "owner":0,
+ "sharedWithTeam":false,
+ "synced":false,
+ "subscribed":false,
+ "hasRequests":true,
+ "requests":[
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"18032e93-3bc5-9976-4525-fe1e77e98207",
+ "name":"Delete Specific Config Logical Switch",
+ "description":"This restconf request delete specific logical switch from the config data store.",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F192.168.1.115:6640%2Flogicalswitch%2Fls0",
+ "method":"DELETE",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":[],
+ "dataMode":"params",
+ "timestamp":0,
+ "version":2,
+ "time":1447335528744
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"22354294-1d01-cebf-180c-d609747be9bc",
+ "name":"Get All Operational Topology",
+ "description":"This restconf request will fetch the operational topology. Operational topology details are fetch by hwvtepsouthbound plugin from all the connected hwvtep node.",
+ "url":"http://odl:8181/restconf/operational/network-topology:network-topology/",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":[],
+ "dataMode":"params",
+ "timestamp":0,
+ "version":2
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"538c71b3-e3e6-f01b-cc4c-d2b686686aa8",
+ "name":"Get Specific Operational Logical Switch",
+ "description":"This restconf request fetch the operational for specific Logical Switch",
+ "url":"http://odl:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F192.168.1.115:6640%2logicalswitch%2ls0",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\"\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335701900
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"6de1ede7-817c-ccbb-3df9-ef510bdaf583",
+ "name":"Create Specific Config HwvtepNode",
+ "description":"Fire this Restconf request if you want to initiate the connection to hwvtep node from controller. It assumes that hwvtep node is listening for tcp connection in passive mode.",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/",
+ "method":"POST",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640\",\n \"connection-info\": {\n \"ovsdb:remote-port\": 6640,\n \"ovsdb:remote-ip\": \"192.168.1.115\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447334840814
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"6e7c88e4-485d-ab9f-4c3a-cc235e022905",
+ "name":"Update Specific Config HwvtepNode",
+ "description":"Fire this Restconf request if you want to update the connection to Hwvtep node from controller.",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F192.168.1.115:6640",
+ "method":"PUT",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640\",\n \"connection-info\": {\n \"ovsdb:remote-port\": 6640,\n \"ovsdb:remote-ip\": \"192.168.1.115\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447334483164
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"92ee7422-5b08-6d63-2b95-961ec0e18ffa",
+ "name":"Get Specific Config HwvtepNode",
+ "description":"This restconf request fetch the configration for specific hwvtep node.",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F192.168.1.115:6640",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640\",\n \"connection-info\": {\n \"ovsdb:remote-port\": 6640,\n \"ovsdb:remote-ip\": \"192.168.1.115\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447334914971
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"9bc22ca7-049c-af51-7c12-6bf71044b2ec",
+ "name":"Create Specific Config Logical Switch",
+ "description":"Fire this Restconf request if you want to create a logical switch.",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/",
+ "method":"POST",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\",\n \"managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://192.168.1.115:6640']\" \n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447340822378
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"c8e8f3fd-3bfb-aafa-e3ec-a671a942f426",
+ "name":"Get Operational Hwvtep Topology",
+ "description":"",
+ "url":"http://odl:8181/restconf/operational/network-topology:network-topology/hwvtep:1/",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640\",\n \"connection-info\": {\n \"ovsdb:remote-port\": 6640,\n \"ovsdb:remote-ip\": \"192.168.1.115\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335830695
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"d362ddc4-1c5f-67d5-e354-c2a8d2ba9d79",
+ "name":"Get Specific Operational HwvtepNode",
+ "description":"This restconf request fetch the operational for specific HwvtepNode",
+ "url":"http://odl:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F192.168.1.115:6640",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\"\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335686540
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"e92ac963-daaf-0899-c3e8-a00d897be0e2",
+ "name":"Delete Specific Config HwvtepNode",
+ "description":"This restconf request delete any node (ovsdb node or bridge node) from the config data store. You can use the same request to delete the ovsdb node by using the following URI: http://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:22222",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F219.141.189.115:6640",
+ "method":"DELETE",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":[],
+ "dataMode":"params",
+ "timestamp":0,
+ "version":2
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"e9ff6957-4dc2-9257-c0c6-21560bfd5de2",
+ "name":"Get All Config Topology",
+ "description":"Fetch all the config topology from configuration data store.",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://219.141.189.115:6640\",\n \"connection-info\": {\n \"ovsdb:remote-port\": 6640,\n \"ovsdb:remote-ip\": \"219.141.189.115\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447311894927
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"ee151670-85a0-30ec-b22b-5defe7b66e0b",
+ "name":"Get Config Hwvtep Topology",
+ "description":"Fetch the config hwvtep topology from configuration data store.",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/hwvtep:1/",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640\",\n \"connection-info\": {\n \"ovsdb:remote-port\": 6640,\n \"ovsdb:remote-ip\": \"192.168.1.115\"\n }\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335823182
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"f6d300f7-380a-d090-0d4a-2b2ddefe5104",
+ "name":"Create Specific Config Logical Switch",
+ "description":"Fire this request if you want to update specific logical switch.",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F192.168.1.115:6640%2Flogicalswitch%2Fls0",
+ "method":"PUT",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\",\n \"managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://192.168.1.115:6640']\" \n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447340847211
+ },
+ {
+ "collectionId":"19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+ "id":"f9f71d74-a49d-b190-d929-b6772ce0ba73",
+ "name":"Get Specific Config Logical Switch",
+ "description":"This restconf request fetch configuration for specific logical switch.",
+ "url":"http://odl:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F192.168.1.115:6640%2Flogicalswitch%2Fls0",
+ "method":"GET",
+ "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+ "data":"{\n \"network-topology:node\": [\n {\n \"node-id\": \"hwvtep://192.168.1.115:6640/logicalswitch/ls0\",\n \"hwvtep-node-description\": \"\",\n \"hwvtep-node-name\": \"ls0\",\n \"tunnel-key\": \"10000\"\n }\n ]\n}",
+ "dataMode":"raw",
+ "timestamp":0,
+ "version":2,
+ "time":1447335408595
+ }
+ ]
+}
- showOvsdbMdsal.py : Dumps mdsal related info from running ODL that is related to ovsdb and netvirt. Use 'showOvsdbMdsal.py -h' for usage
- ODL-Clustering.json.postman_collection : Collection contains Restconf request to fetch clustering service related data to check the state of 3 node cluster and inventory/topology shards.
- - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
+ - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
- Ovsdb-Southbound-Collection-for-Single-Node-Cluster.json.postman_collection : Collection contains Restconf request for doing CRUD operations (connection, bridge, termination point) on southbound plugin running in standalone controller.
- - Please import and load Single-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
+ - Please import and load Single-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
-- Ovsdb-Southbound-Collection-for-3-Node-Cluster.json.postman_collection :
- - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
+- Ovsdb-Southbound-Collection-for-3-Node-Cluster.json.postman_collection :
+ - Please import and load 3-Node-Cluster-Setup-Environment-Variables.postman_environment file, because Restconf request present in this collection depends on the variable defined in this collection.
- Single-Node-Cluster-Setup-Environment-Variables.postman_environment : Postman environment file that defines variables for Restconf request for southbound plugin running in Single controller instance
- 3-Node-Cluster-Setup-Environment-Variables.postman_environment : Postman environment file that defines variables for Restconf request for southbound plugin running in 3 node cluster environment
- NetvirtSfc.json.postman_collection : Collection of REST-APIs to interact with Netvirt-Sfc.
+
+- Ovsdb-HwvtepSouthbound-Collection.json.postman_collection : Collection contains Restconf request for doing CRUD operations (hwvtep global node, physical switch, logical switch, physical locator, and physical port) on hwvtepsouthbound plugin running in standalone controller.
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.action.list.ActionBuilder;
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.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._4.grouping.NxSetNshc4Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.SrcChoice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxArpShaCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc1CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc2CaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIdCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIpv4DstCaseBuilder;
public static Action nxMoveRegTunIdAction(Class<? extends NxmNxReg> src,
boolean groupBucket) {
- return nxMoveRegAction(new SrcNxRegCaseBuilder()
- .setNxReg(src).build(),
- new DstNxTunIdCaseBuilder()
- .setNxTunId(Boolean.TRUE).build(),
+ return nxMoveRegAction(new SrcNxRegCaseBuilder().setNxReg(src).build(),
+ new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
31,
groupBucket);
}
public static Action nxMoveArpShaToArpThaAction() {
- return nxMoveRegAction(new SrcNxArpShaCaseBuilder()
- .setNxArpSha(Boolean.TRUE).build(),
- new DstNxArpThaCaseBuilder()
- .setNxArpTha(Boolean.TRUE).build(),
+ return nxMoveRegAction(new SrcNxArpShaCaseBuilder().setNxArpSha(Boolean.TRUE).build(),
+ new DstNxArpThaCaseBuilder().setNxArpTha(Boolean.TRUE).build(),
47, false);
}
public static Action nxMoveEthSrcToEthDstAction() {
- return nxMoveRegAction(new SrcOfEthSrcCaseBuilder()
- .setOfEthSrc(Boolean.TRUE).build(),
- new DstOfEthDstCaseBuilder()
- .setOfEthDst(Boolean.TRUE).build(),
+ return nxMoveRegAction(new SrcOfEthSrcCaseBuilder().setOfEthSrc(Boolean.TRUE).build(),
+ new DstOfEthDstCaseBuilder().setOfEthDst(Boolean.TRUE).build(),
47, false);
}
public static Action nxMoveArpSpaToArpTpaAction() {
- return nxMoveRegAction(new SrcOfArpSpaCaseBuilder()
- .setOfArpSpa(Boolean.TRUE).build(),
- new DstOfArpTpaCaseBuilder()
- .setOfArpTpa(Boolean.TRUE).build());
+ return nxMoveRegAction(new SrcOfArpSpaCaseBuilder().setOfArpSpa(Boolean.TRUE).build(),
+ new DstOfArpTpaCaseBuilder().setOfArpTpa(Boolean.TRUE).build());
}
public static Action nxOutputRegAction(SrcChoice srcChoice) {
}
public static Action nxMoveRegTunDstToNshc1() {
- return nxMoveRegAction(new SrcNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(),
- new DstNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(), 31, false);
+ return nxMoveRegAction(
+ new SrcNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(),
+ new DstNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(),
+ 31, false);
}
public static Action nxMoveTunIdtoNshc2() {
- return nxMoveRegAction(new SrcNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
- new DstNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(), 31, false);
+ return nxMoveRegAction(
+ new SrcNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
+ new DstNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(),
+ 31, false);
+ }
+
+ public static Action nxMoveNshc1ToTunIpv4Dst() {
+ return nxMoveRegAction(
+ new SrcNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(),
+ new DstNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(),
+ 31, false);
+ }
+
+ public static Action nxMoveNshc2ToTunId() {
+ return nxMoveRegAction(
+ new SrcNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(),
+ new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
+ 31, false);
}
public static Action nxLoadTunIdAction(BigInteger tunnelId, boolean groupBucket) {
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
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.openflowjava.nx.match.rev140421.NxmNxReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FlowUtils {
private static final Logger LOG = LoggerFactory.getLogger(FlowUtils.class);
private static final String OPENFLOW = "openflow";
+ public final static long REG_VALUE_FROM_LOCAL = 0x1L;
+ public final static long REG_VALUE_FROM_REMOTE = 0x2L;
+ public static final Class<? extends NxmNxReg> REG_FIELD = NxmNxReg0.class;
+ public static final int ARP_OP_REQUEST = 0x1;
+ public static final int ARP_OP_REPLY = 0x2;
+
public static String getNodeName(long dpidLong) {
return OPENFLOW + ":" + dpidLong;
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));
}
LOG.error(e.getMessage(), e);
}
- LOG.info("Cannot find data for Flow {}", flowBuilder.getFlowName());
+ LOG.info("Cannot find data for Flow {} in {}", flowBuilder.getFlowName(), store);
return null;
}
return ib;
}
+ /**
+ * Create LOCAL Reserved Port Instruction
+ *
+ * @param ib Map InstructionBuilder without any instructions
+ * @param dpidLong Long the datapath ID of a switch/node
+ * @return ib Map InstructionBuilder with instructions
+ */
+ public static InstructionBuilder createLocalInstructions(InstructionBuilder ib, long dpidLong) {
+ List<Action> actionList = new ArrayList<>();
+ ActionBuilder ab = new ActionBuilder();
+
+ OutputActionBuilder output = new OutputActionBuilder();
+ output.setOutputNodeConnector(new NodeConnectorId("openflow:" + dpidLong + ":"
+ + OutputPortValues.LOCAL.toString()));
+ ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
+ ab.setOrder(0);
+ ab.setKey(new ActionKey(0));
+ actionList.add(ab.build());
+
+ // Create an Apply Action
+ ApplyActionsBuilder aab = new ApplyActionsBuilder();
+ aab.setAction(actionList);
+
+ // Wrap our Apply Action in an Instruction
+ ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+ return ib;
+ }
+
/**
* Create Output Port Instruction
*
public static final String UDP = "udp";
private static final int TCP_SYN = 0x0002;
public static final String ICMP = "icmp";
+ public static final short ALL_ICMP = -1;
/**
* Create Ingress Port Match dpidLong, inPort
return matchBuilder;
}
+ public static MatchBuilder createInPortReservedMatch(MatchBuilder matchBuilder, Long dpidLong, String inPort) {
+
+ NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
+ LOG.debug("createInPortResrevedMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ",
+ dpidLong, inPort);
+ matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
+ matchBuilder.setInPort(ncid);
+
+ return matchBuilder;
+ }
+
/**
* Create EtherType Match
*
// Build the ICMPv4 Match
Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
- icmpv4match.setIcmpv4Type(type);
- icmpv4match.setIcmpv4Code(code);
+ if (type != ALL_ICMP || code != ALL_ICMP) {
+ icmpv4match.setIcmpv4Type(type);
+ icmpv4match.setIcmpv4Code(code);
+ }
matchBuilder.setIcmpv4Match(icmpv4match.build());
return matchBuilder;
*/
public static MatchBuilder createArpDstIpv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
ArpMatchBuilder arpDstMatch = new ArpMatchBuilder();
- arpDstMatch.setArpTargetTransportAddress(dstip);
+ arpDstMatch.setArpTargetTransportAddress(dstip)
+ .setArpOp(FlowUtils.ARP_OP_REQUEST);
matchBuilder.setLayer3Match(arpDstMatch.build());
return matchBuilder;
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);
+ }
}