2 * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.ovsdb.openstack.netvirt.sfc;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.junit.Assert.fail;
16 import static org.ops4j.pax.exam.CoreOptions.composite;
17 import static org.ops4j.pax.exam.CoreOptions.maven;
18 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
19 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties;
20 import static org.ops4j.pax.exam.CoreOptions.vmOption;
21 import static org.ops4j.pax.exam.CoreOptions.when;
22 import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
23 import static org.ops4j.pax.exam.MavenUtils.asInProject;
24 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
25 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
26 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
28 import java.io.IOException;
29 import java.math.BigInteger;
30 import java.util.ArrayList;
31 import java.util.List;
33 import java.util.Properties;
34 import java.util.concurrent.atomic.AtomicBoolean;
36 import org.junit.Assert;
37 import org.junit.Before;
38 import org.junit.Ignore;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
42 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
43 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
44 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
45 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
46 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
47 import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.SfcClassifier;
48 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.AclUtils;
49 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ClassifierUtils;
50 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionChainUtils;
51 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionForwarderUtils;
52 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionPathUtils;
53 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionUtils;
54 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.SfcUtils;
55 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
56 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
57 import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
58 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
59 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
60 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
61 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
62 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SftType;
63 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctions;
64 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctionsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
66 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunctionBuilder;
67 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChains;
68 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChainsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChain;
70 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChainBuilder;
71 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunction;
72 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunctionBuilder;
73 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwarders;
74 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwardersBuilder;
75 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
76 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
77 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
78 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
79 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
80 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
81 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessLists;
82 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessListsBuilder;
83 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.AclBuilder;
84 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.AccessListEntriesBuilder;
85 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.AceBuilder;
86 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.ActionsBuilder;
87 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;
88 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.MatchesBuilder;
89 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
90 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
91 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.ClassifiersBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.ClassifierBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.SffsBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.SffBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.Sfc;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.SfcBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
108 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
109 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
110 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
111 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
112 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
113 import org.opendaylight.yangtools.concepts.Builder;
114 import org.opendaylight.yangtools.yang.binding.DataObject;
115 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
116 import org.ops4j.pax.exam.Configuration;
117 import org.ops4j.pax.exam.Option;
118 import org.ops4j.pax.exam.junit.PaxExam;
119 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
120 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
121 import org.ops4j.pax.exam.options.MavenUrlReference;
122 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
123 import org.ops4j.pax.exam.spi.reactors.PerClass;
124 import org.slf4j.Logger;
125 import org.slf4j.LoggerFactory;
127 import com.google.common.collect.Maps;
129 @RunWith(PaxExam.class)
130 @ExamReactorStrategy(PerClass.class)
131 public class NetvirtSfcIT extends AbstractMdsalTestBase {
132 private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcIT.class);
133 private static AclUtils aclUtils = new AclUtils();
134 private static ClassifierUtils classifierUtils = new ClassifierUtils();
135 private static SfcUtils sfcUtils = new SfcUtils();
136 private static ServiceFunctionUtils serviceFunctionUtils = new ServiceFunctionUtils();
137 private static ServiceFunctionForwarderUtils serviceFunctionForwarderUtils = new ServiceFunctionForwarderUtils();
138 private static ServiceFunctionChainUtils serviceFunctionChainUtils = new ServiceFunctionChainUtils();
139 private static ServiceFunctionPathUtils serviceFunctionPathUtils = new ServiceFunctionPathUtils();
140 private static MdsalUtils mdsalUtils;
141 private static AtomicBoolean setup = new AtomicBoolean(false);
142 private static SouthboundUtils southboundUtils;
143 private static String addressStr;
144 private static String portStr;
145 private static String connectionType;
146 private static boolean ovsdb_wait = false;
147 private static Southbound southbound;
148 private static DataBroker dataBroker;
149 public static final String CONTROLLER_IPADDRESS = "ovsdb.controller.address";
150 public static final String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
151 public static final String SERVER_PORT = "ovsdbserver.port";
152 public static final String CONNECTION_TYPE = "ovsdbserver.connection";
153 public static final String CONNECTION_TYPE_ACTIVE = "active";
154 public static final String CONNECTION_TYPE_PASSIVE = "passive";
155 public static final String DEFAULT_SERVER_PORT = "6640";
156 public static final String INTEGRATION_BRIDGE_NAME = "br-int";
157 private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
158 private static final String OVSDB_TRACE = "ovsdb.trace";
159 private static final String OVSDB_WAIT = "ovsdb.wait";
160 private static final String SF1NAME = "firewall-72";
161 private static final String SF2NAME = "dpi-72";
162 private static final String SF1IP = "10.2.1.1";//"192.168.50.70";//"192.168.120.31";
163 private static final String SF2IP = "10.2.1.2";
164 private static final String SF1DPLNAME = "sf1Dpl";
165 private static final String SF2DPLNAME = "sf2Dpl";
166 private static final String SFF1IP = "127.0.0.1"; //"192.168.1.129"
167 private static final String SFF2IP = "192.168.1.129";//"127.0.0.1";
168 private static final String SFF1NAME = "sff1";
169 private static final String SFF2NAME = "sff2";
170 private static final String SFFDPL1NAME = "vxgpe";
171 private static final String SFFDPL2NAME = "vxgpe";
172 private static final String SN1NAME = "ovsdb1";
173 private static final String SN2NAME = "ovsdb2";
174 private static final String BRIDGE1NAME= "br-int";
175 private static final String BRIDGE2NAME= "br-int";
176 private static final String ACLNAME= "httpAcl";
177 private static final String RULENAME= "httpRule";
178 private static final String SFCNAME = "sfc1";
179 private static final String SFCPATH = "SFC-Path";
180 private static final String SFCSF1NAME = "firewall-abstract";
181 private static final SftType SFCSF1TYPE = new SftType("firewall");
182 private static final int GPEPORT = 6633;
185 public String getModuleName() {
186 return "netvirt-sfc";
190 public String getInstanceName() {
191 return "netvirt-sfc-default";
195 public MavenUrlReference getFeatureRepo() {
197 .groupId("org.opendaylight.ovsdb")
198 .artifactId("openstack.net-virt-sfc-features-test")
199 .classifier("features")
201 .versionAsInProject();
205 public String getFeatureName() {
206 return "odl-ovsdb-sfc-test";
211 public Option[] config() {
212 Option[] parentOptions = super.config();
213 Option[] propertiesOptions = getPropertiesOptions();
214 Option[] otherOptions = getOtherOptions();
215 Option[] options = new Option[parentOptions.length + propertiesOptions.length + otherOptions.length];
216 System.arraycopy(parentOptions, 0, options, 0, parentOptions.length);
217 System.arraycopy(propertiesOptions, 0, options, parentOptions.length, propertiesOptions.length);
218 System.arraycopy(otherOptions, 0, options, parentOptions.length + propertiesOptions.length,
219 otherOptions.length);
223 private Option[] getOtherOptions() {
224 return new Option[] {
226 mavenBundle("org.opendaylight.ovsdb", "utils.mdsal-openflow")
227 .version(asInProject())
229 configureConsole().startLocalConsole(),
230 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
235 public Option[] getPropertiesOptions() {
236 return new Option[] {
237 propagateSystemProperties(SERVER_IPADDRESS, SERVER_PORT, CONNECTION_TYPE,
238 CONTROLLER_IPADDRESS, OVSDB_TRACE, OVSDB_WAIT),
243 public Option getLoggingOption() {
245 when(Boolean.getBoolean(OVSDB_TRACE)).useOptions(
246 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
247 "log4j.logger.org.opendaylight.ovsdb",
248 LogLevelOption.LogLevel.TRACE.name())),
249 //editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
250 // "log4j.logger.org.opendaylight.ovsdb",
251 // LogLevelOption.LogLevel.TRACE.name()),
252 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
253 logConfiguration(NetvirtSfcIT.class),
254 LogLevel.INFO.name()),
255 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
256 "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.sfc",
257 LogLevel.TRACE.name()),
258 //editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
259 // "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13",
260 // LogLevel.TRACE.name()),
261 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
262 "log4j.logger.org.opendaylight.sfc",
263 LogLevel.TRACE.name()),
264 super.getLoggingOption());
267 protected String usage() {
268 return "Integration Test needs a valid connection configuration as follows :\n"
269 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
270 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
273 private void getProperties() {
274 Properties props = System.getProperties();
275 addressStr = props.getProperty(SERVER_IPADDRESS);
276 portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
277 connectionType = props.getProperty(CONNECTION_TYPE, "active");
278 LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
279 connectionType, addressStr, portStr);
280 if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
281 if (addressStr == null) {
285 LOG.info("getProperties {}: {}", OVSDB_TRACE, props.getProperty(OVSDB_TRACE));
286 LOG.info("getProperties {}: {}", OVSDB_WAIT, props.getProperty(OVSDB_WAIT));
287 if (props.getProperty(OVSDB_WAIT).equals("true")) {
294 public void setup() {
296 LOG.info("Skipping setUp, already initialized");
303 } catch (Exception e) {
309 dataBroker = getDatabroker(getProviderContext());
310 mdsalUtils = new MdsalUtils(dataBroker);
311 assertNotNull("mdsalUtils should not be null", mdsalUtils);
312 southboundUtils = new SouthboundUtils(mdsalUtils);
313 assertTrue("Did not find " + NETVIRT_TOPOLOGY_ID, getNetvirtTopology());
314 southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
315 assertNotNull("southbound should not be null", southbound);
319 private ProviderContext getProviderContext() {
320 ProviderContext providerContext = null;
321 for (int i=0; i < 60; i++) {
322 providerContext = getSession();
323 if (providerContext != null) {
328 } catch (InterruptedException e) {
333 assertNotNull("providercontext should not be null", providerContext);
334 /* One more second to let the provider finish initialization */
337 } catch (InterruptedException e) {
340 return providerContext;
343 private DataBroker getDatabroker(ProviderContext providerContext) {
344 DataBroker dataBroker = providerContext.getSALService(DataBroker.class);
345 assertNotNull("dataBroker should not be null", dataBroker);
349 private Boolean getNetvirtTopology() {
350 LOG.info("getNetvirtTopology: looking for {}...", NETVIRT_TOPOLOGY_ID);
351 Boolean found = false;
352 final TopologyId topologyId = new TopologyId(new Uri(NETVIRT_TOPOLOGY_ID));
353 InstanceIdentifier<Topology> path =
354 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
355 for (int i = 0; i < 60; i++) {
356 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
357 if (topology != null) {
358 LOG.info("getNetvirtTopology: found {}...", NETVIRT_TOPOLOGY_ID);
362 LOG.info("getNetvirtTopology: still looking ({})...", i);
365 } catch (InterruptedException e) {
374 public void testNetvirtSfcFeatureLoad() {
378 private AccessListsBuilder accessListsBuilder() {
379 String ruleName = RULENAME;
380 String sfcName = SFCNAME;
381 MatchesBuilder matchesBuilder = aclUtils.matchesBuilder(new MatchesBuilder(), 80);
382 LOG.info("Matches: {}", matchesBuilder.build());
383 ActionsBuilder actionsBuilder = aclUtils.actionsBuilder(new ActionsBuilder(), sfcName);
384 AceBuilder accessListEntryBuilder =
385 aclUtils.aceBuilder(new AceBuilder(), ruleName, matchesBuilder, actionsBuilder);
386 AccessListEntriesBuilder accessListEntriesBuilder =
387 aclUtils.accessListEntriesBuidler(new AccessListEntriesBuilder(), accessListEntryBuilder);
388 AclBuilder accessListBuilder =
389 aclUtils.aclBuilder(new AclBuilder(), ACLNAME, accessListEntriesBuilder);
390 AccessListsBuilder accessListsBuilder =
391 aclUtils.accesslistsbuilder(new AccessListsBuilder(), accessListBuilder);
392 LOG.info("AccessLists: {}", accessListsBuilder.build());
393 return accessListsBuilder;
397 public void testAccessLists() throws InterruptedException {
398 testModel(accessListsBuilder(), AccessLists.class, 0);
401 private ClassifiersBuilder classifiersBuilder() {
402 SffBuilder sffBuilder = classifierUtils.sffBuilder(new SffBuilder(), SFF1NAME);
403 SffsBuilder sffsBuilder = classifierUtils.sffsBuilder(new SffsBuilder(), sffBuilder);
404 ClassifierBuilder classifierBuilder = classifierUtils.classifierBuilder(new ClassifierBuilder(),
405 "classifierName", ACLNAME, sffsBuilder);
406 ClassifiersBuilder classifiersBuilder = classifierUtils.ClassifiersBuilder(new ClassifiersBuilder(),
408 LOG.info("Classifiers: {}", classifiersBuilder.build());
409 return classifiersBuilder;
413 public void testClassifiers() throws InterruptedException {
414 testModel(classifiersBuilder(), Classifiers.class, 0);
417 private SfcBuilder netvirtSfcBuilder() {
418 return sfcUtils.sfcBuilder(new SfcBuilder(), "sfc");
422 public void testNetvirtSfcModel() throws InterruptedException {
423 testModel(netvirtSfcBuilder(), Sfc.class, 0);
426 private <T extends DataObject> void testModelPut(Builder<T> builder, Class<T> clazz) {
427 InstanceIdentifier<T> path = InstanceIdentifier.create(clazz);
428 assertTrue(mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, path, builder.build()));
429 T result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
430 assertNotNull(clazz.getSimpleName() + " should not be null", result);
433 private <T extends DataObject> void testModelDelete(Builder<T> builder, Class<T> clazz)
434 throws InterruptedException {
435 InstanceIdentifier<T> path = InstanceIdentifier.create(clazz);
436 assertTrue("Failed to remove " + clazz.getSimpleName(),
437 mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, path));
438 T result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
439 assertNull(clazz.getSimpleName() + " should be null", result);
442 private <T extends DataObject> void testModel(Builder<T> builder, Class<T> clazz, long wait)
443 throws InterruptedException {
444 testModelPut(builder, clazz);
446 testModelDelete(builder, clazz);
449 private ServiceFunctionsBuilder serviceFunctionsBuilder() {
450 String sf1Name = SF1NAME;
451 String sf1Ip = SF1IP;
452 String sff1Ip = SF1IP;
453 String sff1Name = SFF1NAME;
454 String sf1DplName = SF1DPLNAME;
455 String sn1Name = SN1NAME;
456 String bridge1Name= BRIDGE1NAME;
457 String sf2Name = SF2NAME;
458 String sf2Ip = SF2IP;
459 String sff2Ip = SF2IP;
460 String sff2Name = SFF2NAME;
461 String sf2DplName = SF2DPLNAME;
462 String sn2Name = SN2NAME;
463 String bridge2Name= BRIDGE2NAME;
466 ServiceFunctionBuilder serviceFunctionBuilder =
467 serviceFunctionUtils.serviceFunctionBuilder(sf1Ip, port, sf1DplName, sff1Name, sf1Name);
468 List<ServiceFunction> serviceFunctionList = serviceFunctionUtils.list(
469 new ArrayList<ServiceFunction>(), serviceFunctionBuilder);
471 //serviceFunctionBuilder =
472 // serviceFunctionUtils.serviceFunctionBuilder(sf2Ip, port, sffDpl2Name, sff2Name, sf2Name);
473 //serviceFunctionList = serviceFunctionUtils.list(
474 // serviceFunctionList, serviceFunctionBuilder);
476 ServiceFunctionsBuilder serviceFunctionsBuilder =
477 serviceFunctionUtils.serviceFunctionsBuilder(new ServiceFunctionsBuilder(),
478 serviceFunctionList);
479 LOG.info("ServiceFunctions: {}", serviceFunctionsBuilder.build());
480 return serviceFunctionsBuilder;
483 private ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder() {
484 String sf1Name = SF1NAME;
485 String sf1Ip = SF1IP;
486 String sf1DplName = SF1DPLNAME;
487 String sff1Ip = SFF1IP;
488 String sff1Name = SFF1NAME;
489 String sffDpl1Name = SFFDPL1NAME;
490 String sn1Name = SN1NAME;
491 String bridge1Name= BRIDGE1NAME;
492 String sf2Name = SF2NAME;
493 String sf2Ip = SF2IP;
494 String sff2Ip = SFF2IP;
495 String sff2Name = SFF2NAME;
496 String sffDpl2Name = SFFDPL2NAME;
497 String sn2Name = SN2NAME;
498 String bridge2Name= BRIDGE2NAME;
499 String aclName = ACLNAME;
502 ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
503 serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
504 sff1Name, sff1Ip, port, sffDpl1Name, sf1Ip, sn1Name, bridge1Name, sf1Name, sf1DplName);
505 List<ServiceFunctionForwarder> serviceFunctionForwarderList = serviceFunctionForwarderUtils.list(
506 new ArrayList<ServiceFunctionForwarder>(), serviceFunctionForwarderBuilder);
508 //serviceFunctionForwarderBuilder =
509 // serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
510 // sff2Name, sff2Ip, port, sffDpl2Name, sf2Name, sff2Ip, sn2Name, bridge2Name, Dpi.class);
511 //serviceFunctionForwarderList = serviceFunctionForwarderUtils.list(
512 // serviceFunctionForwarderList, serviceFunctionForwarderBuilder);
514 ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder =
515 serviceFunctionForwarderUtils.serviceFunctionForwardersBuilder(
516 new ServiceFunctionForwardersBuilder(), serviceFunctionForwarderList);
517 LOG.info("ServiceFunctionForwarders: {}", serviceFunctionForwardersBuilder.build());
518 return serviceFunctionForwardersBuilder;
521 private ServiceFunctionChainsBuilder serviceFunctionChainsBuilder() {
522 String sf1Name = SFCSF1NAME;
523 SftType sfType = SFCSF1TYPE;
524 String sfcName = SFCNAME;
526 SfcServiceFunctionBuilder sfcServiceFunctionBuilder = serviceFunctionChainUtils.sfcServiceFunctionBuilder(
527 new SfcServiceFunctionBuilder(), sf1Name, sfType);
528 List<SfcServiceFunction> sfcServiceFunctionList =
529 serviceFunctionChainUtils.list(new ArrayList<SfcServiceFunction>(), sfcServiceFunctionBuilder);
531 //sfcServiceFunctionBuilder = serviceFunctionChainUtils.sfcServiceFunctionBuilder(
532 // sfcServiceFunctionBuilder, sf2Name, Dpi.class);
533 //sfcServiceFunctionList = serviceFunctionChainUtils.list(sfcServiceFunctionList, sfcServiceFunctionBuilder);
535 ServiceFunctionChainBuilder serviceFunctionChainBuilder =
536 serviceFunctionChainUtils.serviceFunctionChainBuilder(
537 new ServiceFunctionChainBuilder(), sfcName, false, sfcServiceFunctionList);
538 ServiceFunctionChainsBuilder serviceFunctionChainsBuilder =
539 serviceFunctionChainUtils.serviceFunctionChainsBuilder(
540 new ServiceFunctionChainsBuilder(),
541 serviceFunctionChainUtils.list(new ArrayList<ServiceFunctionChain>(),
542 serviceFunctionChainBuilder));
543 LOG.info("ServiceFunctionChains: {}", serviceFunctionChainBuilder.build());
544 return serviceFunctionChainsBuilder;
547 private ServiceFunctionPathsBuilder serviceFunctionPathsBuilder() {
548 String sfpName = SFCPATH;
549 String sfcName = SFCNAME;
550 short startingIndex = 255;
552 ServiceFunctionPathBuilder serviceFunctionPathBuilder =
553 serviceFunctionPathUtils.serviceFunctionPathBuilder(
554 new ServiceFunctionPathBuilder(), sfpName, sfcName, startingIndex, false);
555 ServiceFunctionPathsBuilder serviceFunctionPathsBuilder =
556 serviceFunctionPathUtils.serviceFunctionPathsBuilder(
557 serviceFunctionPathUtils.list(new ArrayList<ServiceFunctionPath>(),
558 serviceFunctionPathBuilder));
559 LOG.info("ServiceFunctionPaths: {}", serviceFunctionPathsBuilder.build());
560 return serviceFunctionPathsBuilder;
564 public void testSfcModel() throws InterruptedException {
565 testModel(serviceFunctionsBuilder(), ServiceFunctions.class, 3000);
566 testModel(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class, 3000);
567 testModel(serviceFunctionChainsBuilder(), ServiceFunctionChains.class, 3000);
568 testModel(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class, 3000);
572 public void testSfcModels() throws InterruptedException {
573 String bridgeName = INTEGRATION_BRIDGE_NAME;
574 ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
575 assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
576 Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
577 assertNotNull("node is not connected", ovsdbNode);
580 Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
581 assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
582 long datapathId = southbound.getDataPathId(bridgeNode);
584 Map<String, String> externalIds = Maps.newHashMap();
585 externalIds.put("attached-mac", "f6:00:00:0f:00:01");
586 southboundUtils.addTerminationPoint(bridgeNode, SF1DPLNAME, "internal", null, externalIds);
587 southboundUtils.addTerminationPoint(bridgeNode, "vm1", "internal");
588 southboundUtils.addTerminationPoint(bridgeNode, "vm2", "internal");
589 Map<String, String> options = Maps.newHashMap();
590 options.put("key", "flow");
591 options.put("remote_ip", "192.168.120.32");
592 southboundUtils.addTerminationPoint(bridgeNode, "vx", "vxlan", options, null);
595 testModelPut(serviceFunctionsBuilder(), ServiceFunctions.class);
596 testModelPut(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class);
597 testModelPut(serviceFunctionChainsBuilder(), ServiceFunctionChains.class);
598 testModelPut(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class);
602 testModelPut(accessListsBuilder(), AccessLists.class);
603 testModelPut(classifiersBuilder(), Classifiers.class);
609 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
610 FlowBuilder flowBuilder = getSfcIngressClassifierFlowBuilder();
611 Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
612 assertNotNull("Could not find flow in config", flow);
613 flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
614 assertNotNull("Could not find flow in operational", flow);
616 assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
618 assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
622 * Connect to an ovsdb node. Netvirt should add br-int, add the controller address
623 * and program the pipeline flows.
626 public void testNetvirtSfc() throws InterruptedException {
627 String bridgeName = INTEGRATION_BRIDGE_NAME;
628 ConnectionInfo connectionInfo = SouthboundUtils.getConnectionInfo(addressStr, portStr);
629 assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
630 Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
631 assertNotNull("node is not connected", ovsdbNode);
632 ControllerEntry controllerEntry;
633 // Loop 10s checking if the controller was added
634 for (int i = 0; i < 10; i++) {
635 ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
636 assertNotNull("ovsdb node not found", ovsdbNode);
637 String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
638 assertNotNull("Failed to get controller target", controllerTarget);
639 OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, bridgeName);
640 if (bridge != null) {
641 assertNotNull("Failed to read bridge", bridge);
642 assertNotNull("Failed to extract controllerEntry", bridge.getControllerEntry());
643 controllerEntry = bridge.getControllerEntry().iterator().next();
644 assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
645 if (controllerEntry.isIsConnected()) {
646 Assert.assertTrue("switch is not connected to the controller", controllerEntry.isIsConnected());
653 Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
654 assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
655 long datapathId = southbound.getDataPathId(bridgeNode);
657 //Thread.sleep(10000);
659 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
660 FlowBuilder flowBuilder = FlowUtils.getPipelineFlow(Service.SFC_CLASSIFIER.getTable(), (short)0);
661 Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
662 assertNotNull("Could not find flow in config", flow);
663 flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
664 assertNotNull("Could not find flow in operational", flow);
666 assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
668 assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
673 public void testStandalone() throws InterruptedException {
674 String bridgeName = "sw1";
675 ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
676 assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
677 Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
678 assertNotNull("node is not connected", ovsdbNode);
679 String controllerTarget = "tcp:192.168.50.1:6653";
680 List<ControllerEntry> setControllerEntry = southboundUtils.createControllerEntry(controllerTarget);
681 Assert.assertTrue(southboundUtils.addBridge(connectionInfo, null, bridgeName, null, true,
682 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
683 setControllerEntry, null, "00:00:00:00:00:00:00:01"));
684 // Loop 10s checking if the controller was added
685 for (int i = 0; i < 10; i++) {
686 ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
687 assertNotNull("ovsdb node not found", ovsdbNode);
688 assertNotNull("Failed to get controller target", controllerTarget);
689 OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, bridgeName);
690 assertNotNull(bridge);
691 assertNotNull(bridge.getControllerEntry());
692 ControllerEntry controllerEntry = bridge.getControllerEntry().iterator().next();
693 assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
694 if (controllerEntry.isIsConnected()) {
695 Assert.assertTrue(controllerEntry.isIsConnected());
701 Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
702 assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
703 long datapathId = southbound.getDataPathId(bridgeNode);
705 SfcClassifier sfcClassifier = new SfcClassifier(dataBroker, southbound, mdsalUtils);
706 //sfcClassifier.programLocalInPort(datapathId, "4096", (long)1, (short)0, (short)50, true);
708 NshUtils nshUtils = new NshUtils(new Ipv4Address("192.168.50.71"), new PortNumber(6633),
709 (long)10, (short)255, (long)4096, (long)4096);
710 MatchesBuilder matchesBuilder = aclUtils.matchesBuilder(new MatchesBuilder(), 80);
711 sfcClassifier.programSfcClassiferFlows(datapathId, (short)0, "test", matchesBuilder.build(),
712 nshUtils, (long)2, true);
714 nshUtils = new NshUtils(null, null, (long)10, (short)253, 0, 0);
715 //sfcClassifier.programEgressSfcClassiferFlows(datapathId, (short)0, "test", null,
716 // nshUtils, (long)2, (long)3, true);
720 //} catch (IOException e) {
721 // e.printStackTrace();
724 //NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
725 //FlowBuilder flowBuilder = getLocalInPortFlow(datapathId, "4096", (long) 1, (short) 0);
726 //Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
727 //assertNotNull("Could not find flow in config", flow);
728 //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
729 //assertNotNull("Could not find flow in operational", flow);
731 MatchBuilder matchBuilder = sfcClassifier.buildMatch(matchesBuilder.build());
732 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
733 FlowBuilder flowBuilder = getSfcClassifierFlow(datapathId, (short) 0, "test", null,
734 nshUtils, (long) 2, matchBuilder);
735 Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
736 assertNotNull("Could not find flow in config", flow);
737 flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
738 assertNotNull("Could not find flow in operational", flow);
740 //nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
741 //flowBuilder = getEgressSfcClassifierFlow(datapathId, (short) 0, "test", nshUtils, (long) 2);
742 //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
743 //assertNotNull("Could not find flow in config", flow);
744 //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
745 //assertNotNull("Could not find flow in operational", flow);
747 LOG.info("***** Go look for flows *****");
749 assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
751 assertTrue(southboundUtils.deleteBridge(connectionInfo, INTEGRATION_BRIDGE_NAME));
753 assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
756 private FlowBuilder getLocalInPortFlow(long dpidLong, String segmentationId, long inPort, short writeTable) {
757 MatchBuilder matchBuilder = new MatchBuilder();
759 FlowBuilder flowBuilder = new FlowBuilder();
761 flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build());
762 String flowId = "sfcIngress_" + segmentationId + "_" + inPort;
763 flowBuilder.setId(new FlowId(flowId));
764 FlowKey key = new FlowKey(new FlowId(flowId));
765 flowBuilder.setStrict(true);
766 flowBuilder.setBarrier(false);
767 flowBuilder.setTableId(writeTable);
768 flowBuilder.setKey(key);
769 flowBuilder.setFlowName(flowId);
770 flowBuilder.setHardTimeout(0);
771 flowBuilder.setIdleTimeout(0);
775 public FlowBuilder getSfcClassifierFlow(long dpidLong, short writeTable, String ruleName, Matches match,
776 NshUtils nshHeader, long tunnelOfPort, MatchBuilder matchBuilder) {
777 FlowBuilder flowBuilder = new FlowBuilder();
779 flowBuilder.setMatch(matchBuilder.build());
781 String flowId = "sfcClass_" + ruleName + "_" + nshHeader.getNshNsp();
782 flowBuilder.setId(new FlowId(flowId));
783 FlowKey key = new FlowKey(new FlowId(flowId));
784 flowBuilder.setBarrier(true);
785 flowBuilder.setTableId(writeTable);
786 flowBuilder.setKey(key);
787 flowBuilder.setFlowName(flowId);
788 flowBuilder.setHardTimeout(0);
789 flowBuilder.setIdleTimeout(0);
793 private FlowBuilder getEgressSfcClassifierFlow(long dpidLong, short writeTable, String ruleName,
794 NshUtils nshHeader, long tunnelOfPort) {
795 FlowBuilder flowBuilder = new FlowBuilder();
797 MatchBuilder matchBuilder = new MatchBuilder();
798 flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, tunnelOfPort).build());
799 flowBuilder.setMatch(
800 MatchUtils.createTunnelIDMatch(matchBuilder, BigInteger.valueOf(nshHeader.getNshNsp())).build());
801 flowBuilder.setMatch(MatchUtils.addNxNspMatch(matchBuilder, nshHeader.getNshNsp()).build());
802 flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nshHeader.getNshNsi()).build());
804 String flowId = "egressSfcClass_" + ruleName + "_" + nshHeader.getNshNsp() + "_" + nshHeader.getNshNsi();
805 flowBuilder.setId(new FlowId(flowId));
806 FlowKey key = new FlowKey(new FlowId(flowId));
807 flowBuilder.setStrict(true);
808 flowBuilder.setBarrier(false);
809 flowBuilder.setTableId(writeTable);
810 flowBuilder.setKey(key);
811 flowBuilder.setFlowName(flowId);
812 flowBuilder.setHardTimeout(0);
813 flowBuilder.setIdleTimeout(0);
817 private FlowBuilder getSfcIngressClassifierFlowBuilder() {
818 FlowBuilder flowBuilder = new FlowBuilder();
819 String flowId = "sfcIngressClass_" + "httpRule";
820 flowBuilder.setId(new FlowId(flowId));
821 FlowKey key = new FlowKey(new FlowId(flowId));
822 flowBuilder.setKey(key);
823 flowBuilder.setFlowName(flowId);
824 flowBuilder.setTableId((short)10);
828 private Flow getFlow (FlowBuilder flowBuilder, NodeBuilder nodeBuilder, LogicalDatastoreType store)
829 throws InterruptedException {
831 for (int i = 0; i < 10; i++) {
832 flow = FlowUtils.getFlow(flowBuilder, nodeBuilder, dataBroker.newReadOnlyTransaction(), store);
834 LOG.info("getFlow: flow: {}: {}", store, flow);
842 private void readwait() {
844 LOG.warn("Waiting, kill with ps -ef | grep java, kill xxx... ");
847 } catch (IOException e) {