/*
- * Copyright (c) 2015 Red Hat, Inc. and others. All rights reserved.
+ * Copyright (c) 2015, 2016 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,
package org.opendaylight.ovsdb.openstack.netvirt.providers;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolver;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IcmpEchoProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.InboundNatProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.L2ForwardingProvider;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.ArpResponderService;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.ClassifierService;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.EgressAclService;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.IcmpEchoResponderService;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.InboundNatService;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.IngressAclService;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.L2ForwardingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
public class ConfigActivator implements BundleActivator {
private static final Logger LOG = LoggerFactory.getLogger(ConfigActivator.class);
private List<ServiceRegistration<?>> registrations = new ArrayList<>();
gatewayMacResolverService, Service.GATEWAY_RESOLVER);
getNotificationProviderService().registerNotificationListener(gatewayMacResolverService);
+ IcmpEchoResponderService icmpEchoResponderService = new IcmpEchoResponderService();
+ registerService(context, IcmpEchoProvider.class.getName(),
+ icmpEchoResponderService, Service.ICMP_ECHO);
+
netvirtProvidersConfig.setDependencies(context, null);
pipelineOrchestrator.setDependencies(context, null);
outboundNatService.setDependencies(context, null);
classifierService.setDependencies(context, null);
of13Provider.setDependencies(context, null);
gatewayMacResolverService.setDependencies(context, null);
+ icmpEchoResponderService.setDependencies(context, null);
@SuppressWarnings("unchecked")
ServiceTracker networkingProviderManagerTracker = new ServiceTracker(context,
/*
- * Copyright (c) 2014, 2015 Red Hat, Inc. and others. All rights reserved.
+ * Copyright (c) 2014 - 2016 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,
DIRECTOR ((short) 10, "Director"),
SFC_CLASSIFIER ((short) 10, "SFC Classifier"),
ARP_RESPONDER ((short) 20, "Distributed ARP Responder"),
+ ICMP_ECHO ((short) 20, "Distributed ICMP Echo Responder"),
INBOUND_NAT ((short) 30, "DNAT for inbound floating-ip traffic"),
EGRESS_ACL ((short) 40, "Egress Acces-control"),
LOAD_BALANCER ((short) 50, "Distributed LBaaS"),
--- /dev/null
+/*
+ * Copyright (c) 2016 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.providers.openflow13.services;
+
+import com.google.common.collect.Lists;
+import org.opendaylight.ovsdb.openstack.netvirt.api.*;
+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.OF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+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.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.List;
+
+/**
+ * @author Josh Hershberg (jhershbe@redhat.com)
+ */
+public class IcmpEchoResponderService extends AbstractServiceInstance implements IcmpEchoProvider, ConfigInterface {
+ private static final Logger LOG = LoggerFactory.getLogger(IcmpEchoResponderService.class);
+
+ public IcmpEchoResponderService() {
+ super(Service.ICMP_ECHO);
+ }
+
+ public IcmpEchoResponderService(Service service) {
+ super(service);
+ }
+
+ @Override
+ public Status programIcmpEchoEntry(Long dpid, String segmentationId, String macAddressStr, InetAddress ipAddress, Action action) {
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
+ MacAddress macAddress = new MacAddress(macAddressStr);
+
+ MatchBuilder matchBuilder = new MatchBuilder();
+ NodeBuilder nodeBuilder = OF13Provider.createNodeBuilder(nodeName);
+
+ // Instructions List Stores Individual Instructions
+ InstructionsBuilder isb = new InstructionsBuilder();
+ List<Instruction> instructions = Lists.newArrayList();
+ InstructionBuilder ib = new InstructionBuilder();
+ ApplyActionsBuilder aab = new ApplyActionsBuilder();
+ ActionBuilder ab = new ActionBuilder();
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList = Lists.newArrayList();
+
+ if (segmentationId != null) {
+ final Long inPort = MatchUtils.parseExplicitOFPort(segmentationId);
+ if (inPort != null) {
+ MatchUtils.createInPortMatch(matchBuilder, dpid, inPort);
+ } else {
+ MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+ }
+ }
+
+ if (ipAddress instanceof Inet6Address) {
+ // WORKAROUND: For now ipv6 is not supported
+ // TODO: implement ipv6 case
+ LOG.debug("ipv6 address case is not implemented yet. dpid {} segmentationId {} macAddressStr, ipAddress {} action {}",
+ dpid, segmentationId, macAddressStr, ipAddress, action);
+ return new Status(StatusCode.NOTIMPLEMENTED);
+ }
+
+ // Match ICMP echo requests, type=8, code=0
+ MatchUtils.createICMPv4Match(matchBuilder, (short)8, (short)0);
+ MatchUtils.createDstL3IPv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress.getHostAddress()));
+
+ // 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());
+
+ // Move Ip Src to Ip Dst
+ ab.setAction(ActionUtils.nxMoveIpSrcToIpDstAction());
+ ab.setOrder(2);
+ ab.setKey(new ActionKey(2));
+ actionList.add(ab.build());
+
+ // Set Ip Src
+ ab.setAction(ActionUtils.setNwSrcAction(new Ipv4Builder().setIpv4Address(
+ MatchUtils.iPv4PrefixFromIPv4Address(ipAddress.getHostAddress())).build()));
+ ab.setOrder(3);
+ ab.setKey(new ActionKey(3));
+ actionList.add(ab.build());
+
+ // Set the ICMP type to 0 (echo reply)
+ ab.setAction(ActionUtils.setIcmpTypeAction((byte)0));
+ ab.setOrder(4);
+ ab.setKey(new ActionKey(4));
+ actionList.add(ab.build());
+
+ // Output of InPort
+ ab.setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":INPORT")));
+ ab.setOrder(5);
+ ab.setKey(new ActionKey(5));
+ 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());
+
+ FlowBuilder flowBuilder = new FlowBuilder();
+ String flowName = "IcmpEchoResponder_" + segmentationId + "_" + ipAddress.getHostAddress();
+ FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(1024);
+ flowBuilder.setMatch(matchBuilder.build());
+ flowBuilder.setInstructions(isb.setInstruction(instructions).build());
+
+ if (action.equals(Action.ADD)) {
+ writeFlow(flowBuilder, nodeBuilder);
+ } else {
+ removeFlow(flowBuilder, nodeBuilder);
+ }
+
+ // ToDo: WriteFlow/RemoveFlow should return something we can use to check success
+ return new Status(StatusCode.SUCCESS);
+ }
+
+ @Override
+ public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+ super.setDependencies(bundleContext.getServiceReference(IcmpEchoProvider.class.getName()), this);
+ }
+
+ @Override
+ public void setDependencies(Object impl) {}
+}
/*
- * Copyright (c) 2015 Inocybe and others. All rights reserved.
+ * Copyright (c) 2015, 2016 Inocybe 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,
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.ovsdb.openstack.netvirt.NetvirtProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
import org.opendaylight.ovsdb.openstack.netvirt.providers.NetvirtProvidersProvider;
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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.osgi.framework.ServiceReference;
import org.powermock.api.mockito.PowerMockito;
/*
- * Copyright (c) 2015 Inocybe and others. All rights reserved.
+ * Copyright (c) 2015, 2016 Inocybe 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,
import static org.mockito.Mockito.when;
import java.net.InetAddress;
-import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
import org.opendaylight.ovsdb.openstack.netvirt.api.Status;
import org.opendaylight.ovsdb.openstack.netvirt.api.StatusCode;
-import org.opendaylight.ovsdb.openstack.netvirt.providers.NetvirtProvidersProvider;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
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.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.powermock.api.support.membermodification.MemberModifier;
import com.google.common.util.concurrent.CheckedFuture;
--- /dev/null
+/*
+ * Copyright (c) 2016 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.providers.openflow13.services;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Status;
+import org.opendaylight.ovsdb.openstack.netvirt.api.StatusCode;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+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.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.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.util.concurrent.CheckedFuture;
+
+import java.net.InetAddress;
+
+/**
+ * Unit test for {@link IcmpEchoResponderService}
+ */
+@RunWith(MockitoJUnitRunner.class)
+@SuppressWarnings("unchecked")
+public class IcmpEchoResponderServiceTest {
+ @InjectMocks private IcmpEchoResponderService icmpEchoResponderService = new IcmpEchoResponderService();
+
+ @Mock
+ private DataBroker dataBroker;
+
+ private static final String HOST_ADDRESS = "121.0.0.1";
+ private static final String MAC_ADDRESS = "87:1D:5E:02:40:B7";
+
+ @Test
+ public void testProgramIcmpEchoEntry() throws Exception {
+ icmpEchoResponderService.setService(Service.ARP_RESPONDER);
+
+ InetAddress ipAddress = mock(InetAddress.class);
+ when(ipAddress.getHostAddress()).thenReturn(HOST_ADDRESS);
+
+ WriteTransaction transaction = mock(WriteTransaction.class);
+ when(dataBroker.newWriteOnlyTransaction()).thenReturn(transaction);
+ CheckedFuture<Void, TransactionCommitFailedException> commitFuture = mock(CheckedFuture.class);
+ when(transaction.submit()).thenReturn(commitFuture);
+
+ NodeBuilder nodeBuilder = mock(NodeBuilder.class);
+ when(nodeBuilder.getKey()).thenReturn(mock(NodeKey.class));
+
+ FlowBuilder flowBuilder = mock(FlowBuilder.class);
+ when(flowBuilder.getKey()).thenReturn(mock(FlowKey.class));
+
+ // test Action.ADD
+ assertEquals("Error, did not return the expected StatusCode", new Status(StatusCode.SUCCESS), icmpEchoResponderService.programIcmpEchoEntry(Long.valueOf(12), "2", MAC_ADDRESS, ipAddress, Action.ADD));
+
+ verify(transaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
+ verify(transaction, times(1)).submit();
+ verify(commitFuture, times(1)).get();
+
+ // test Action.DELETE
+ assertEquals("Error, did not return the expected StatusCode", new Status(StatusCode.SUCCESS), icmpEchoResponderService.programIcmpEchoEntry(Long.valueOf(12), "2", MAC_ADDRESS, ipAddress, Action.DELETE));
+
+ verify(transaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+ verify(commitFuture, times(2)).get(); // 1 + 1 above
+ }
+}
/*
- * Copyright (c) 2015 Red Hat, Inc. and others. All rights reserved.
+ * Copyright (c) 2015, 2016 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,
import org.apache.commons.lang3.tuple.Pair;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.ovsdb.openstack.netvirt.api.ArpProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IcmpEchoProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
+import org.opendaylight.ovsdb.openstack.netvirt.api.ArpProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
-import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
-import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
import org.opendaylight.ovsdb.openstack.netvirt.impl.BridgeConfigurationManagerImpl;
import org.opendaylight.ovsdb.openstack.netvirt.impl.ConfigurationServiceImpl;
import org.opendaylight.ovsdb.openstack.netvirt.impl.EventDispatcherImpl;
trackService(context, GatewayMacResolver.class, neutronL3Adapter);
trackService(context, IngressAclProvider.class, securityServices);
trackService(context, EgressAclProvider.class, securityServices);
+ trackService(context, IcmpEchoProvider.class, neutronL3Adapter);
// We no longer need to track the services, avoid keeping references around
servicesAndRegistrations.clear();
--- /dev/null
+/*
+ * Copyright (c) 2016 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.api;
+
+import java.net.InetAddress;
+
+/**
+ * @author Josh Hershberg (jhershbe@redhat.com)
+ */
+public interface IcmpEchoProvider {
+
+ Status programIcmpEchoEntry(Long dpid, String segmentationId,
+ String macAddress, InetAddress ipAddress, Action action);
+}
/*
- * Copyright (c) 2014, 2015 Red Hat, Inc. and others. All rights reserved.
+ * Copyright (c) 2014 - 2016 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,
import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolver;
import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolverListener;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IcmpEchoProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.InboundNatProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.L3ForwardingProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
private volatile RoutingProvider routingProvider;
private volatile GatewayMacResolver gatewayMacResolver;
private volatile SecurityServicesManager securityServicesManager;
+ private volatile IcmpEchoProvider icmpEchoProvider;
private class FloatIpData {
// br-int of node where floating ip is associated with tenant port
}
// Enable ARP responder by default, because router interface needs to be responded always.
programStaticArpStage1(dpid, destinationSegmentationId, macAddress, ipStr, actionForNode);
+ programIcmpEcho(dpid, destinationSegmentationId, macAddress, ipStr, actionForNode);
}
// Compute action to be programmed. In the case of rewrite exclusions, we must never program rules
return status;
}
+ private boolean programIcmpEcho(Long dpid, String segOrOfPort,
+ String macAddress, String ipStr,
+ Action action) {
+ if (action == Action.DELETE ) {
+ LOG.trace("Deleting Flow : programIcmpEcho dpid {} segOrOfPort {} mac {} ip {} action {}",
+ dpid, segOrOfPort, macAddress, ipStr, action);
+ }
+ if (action == Action.ADD) {
+ LOG.trace("Adding Flow : programIcmpEcho dpid {} segOrOfPort {} mac {} ip {} action {}",
+ dpid, segOrOfPort, macAddress, ipStr, action);
+ }
+
+ Status status = new Status(StatusCode.UNSUPPORTED);
+ if (icmpEchoProvider != null){
+ try {
+ InetAddress inetAddress = InetAddress.getByName(ipStr);
+ status = icmpEchoProvider.programIcmpEchoEntry(dpid, segOrOfPort,
+ macAddress, inetAddress, action);
+ } catch (UnknownHostException e) {
+ status = new Status(StatusCode.BADREQUEST);
+ }
+ }
+
+ if (status.isSuccess()) {
+ LOG.debug("programIcmpEcho {} for mac:{} addr:{} dpid:{} segOrOfPort:{} action:{}",
+ icmpEchoProvider == null ? "skipped" : "programmed",
+ macAddress, ipStr, dpid, segOrOfPort, action);
+ } else {
+ LOG.error("programIcmpEcho failed for mac:{} addr:{} dpid:{} segOrOfPort:{} action:{} status:{}",
+ macAddress, ipStr, dpid, segOrOfPort, action, status);
+ }
+
+ return status.isSuccess();
+ }
+
private boolean programStaticArpStage1(Long dpid, String segOrOfPort,
String macAddress, String ipStr,
Action action) {
dpid, segOrOfPort, macAddress, ipStr, action);
}
if (action == Action.ADD) {
- LOG.trace("Adding Flow : programStaticArpStage1 dpid {} segOrOfPort {} mac {} ip {} action {} is already done",
+ LOG.trace("Adding Flow : programStaticArpStage1 dpid {} segOrOfPort {} mac {} ip {} action {}",
dpid, segOrOfPort, macAddress, ipStr, action);
}
(GatewayMacResolver) ServiceHelper.getGlobalInstance(GatewayMacResolver.class, this);
securityServicesManager =
(SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
+
initL3AdapterMembers();
}
l3ForwardingProvider = (L3ForwardingProvider)impl;
}else if (impl instanceof GatewayMacResolver) {
gatewayMacResolver = (GatewayMacResolver)impl;
+ }else if (impl instanceof IcmpEchoProvider) {
+ icmpEchoProvider = (IcmpEchoProvider)impl;
}
+
populateL3ForwardingCaches();
}
}
package org.opendaylight.ovsdb.utils.mdsal.openflow;
+import com.google.common.net.InetAddresses;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
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.Action;
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.Icmpv4MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxHashFields;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxMpAlgorithm;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpSpaCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpTpaCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfEthDstCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfIpDstCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNodesNodeTableFlowApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIpv4DstCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfArpSpaCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfEthSrcCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxHashFields;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxMpAlgorithm;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmit;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmitBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsi.grouping.NxSetNsi;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsi.grouping.NxSetNsiBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsp.grouping.NxSetNsp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsp.grouping.NxSetNspBuilder;
-
-import com.google.common.net.InetAddresses;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfIpSrcCaseBuilder;
import java.math.BigInteger;
return nxLoadArpSpaAction(BigInteger.valueOf(ipl));
}
+ public static Action setIcmpTypeAction(byte value) {
+ SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
+ setFieldBuilder.setIcmpv4Match(new Icmpv4MatchBuilder().setIcmpv4Type((short)value).build());
+ return new SetFieldCaseBuilder()
+ .setSetField(setFieldBuilder.build())
+ .build();
+ }
+
public static Action nxMoveRegAction(SrcChoice srcChoice,
DstChoice dstChoice,
int endOffset,
new DstOfArpTpaCaseBuilder().setOfArpTpa(Boolean.TRUE).build());
}
+ public static Action nxMoveIpSrcToIpDstAction() {
+ return nxMoveRegAction(new SrcOfIpSrcCaseBuilder().setOfIpSrc(Boolean.TRUE).build(),
+ new DstOfIpDstCaseBuilder().setOfIpDst(Boolean.TRUE).build());
+ }
+
+
public static Action nxOutputRegAction(SrcChoice srcChoice) {
NxOutputReg r = new NxOutputRegBuilder()
.setSrc(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.nx.output.reg.SrcBuilder()