2 * Copyright (C) 2013 Red Hat, Inc.
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
8 * Authors : Madhu Venugopal, Brent Salisbury, Hsin-Yi Shen
10 package org.opendaylight.ovsdb.openstack.netvirt;
12 import org.opendaylight.neutron.spi.INeutronNetworkAware;
13 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
14 import org.opendaylight.neutron.spi.NeutronNetwork;
15 import org.opendaylight.ovsdb.lib.notation.Row;
16 import org.opendaylight.ovsdb.lib.notation.UUID;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
19 //import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
20 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
21 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
22 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
23 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
24 //import org.opendaylight.ovsdb.plugin.api.OvsdbInventoryListener;
25 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
26 import org.opendaylight.ovsdb.schema.openvswitch.Port;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 import java.net.HttpURLConnection;
33 import java.util.List;
34 import java.util.concurrent.ConcurrentMap;
37 * Handle requests for Neutron Network.
39 public class NetworkHandler extends AbstractHandler
40 implements INeutronNetworkAware {
42 public static final String NETWORK_TYPE_VXLAN = "vxlan";
43 public static final String NETWORK_TYPE_GRE = "gre";
44 public static final String NETWORK_TYPE_VLAN = "vlan";
49 static final Logger logger = LoggerFactory.getLogger(NetworkHandler.class);
51 // The implementation for each of these services is resolved by the OSGi Service Manager
52 private volatile TenantNetworkManager tenantNetworkManager;
53 private volatile BridgeConfigurationManager bridgeConfigurationManager;
54 //private volatile ConfigurationService configurationService;
55 private volatile OvsdbConfigurationService ovsdbConfigurationService;
56 private volatile OvsdbConnectionService connectionService;
57 private volatile INeutronNetworkCRUD neutronNetworkCache;
58 //private volatile OvsdbInventoryListener ovsdbInventoryListener;
59 private volatile NeutronL3Adapter neutronL3Adapter;
62 * Invoked when a network creation is requested
63 * to indicate if the specified network can be created.
65 * @param network An instance of proposed new Neutron Network object.
66 * @return A HTTP status code to the creation request.
69 public int canCreateNetwork(NeutronNetwork network) {
70 if (network.isShared()) {
71 logger.error(" Network shared attribute not supported ");
72 return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
75 return HttpURLConnection.HTTP_OK;
79 * Invoked to take action after a network has been created.
81 * @param network An instance of new Neutron Network object.
84 public void neutronNetworkCreated(NeutronNetwork network) {
85 enqueueEvent(new NorthboundEvent(network, Action.ADD));
87 private void doNeutronNetworkCreated(NeutronNetwork network) {
88 neutronL3Adapter.handleNeutronNetworkEvent(network, Action.ADD);
92 * Invoked when a network update is requested
93 * to indicate if the specified network can be changed
94 * using the specified delta.
96 * @param delta Updates to the network object using patch semantics.
97 * @param original An instance of the Neutron Network object
99 * @return A HTTP status code to the update request.
102 public int canUpdateNetwork(NeutronNetwork delta,
103 NeutronNetwork original) {
104 if (delta.isShared()) {
105 logger.error(" Network shared attribute not supported ");
106 return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
109 return HttpURLConnection.HTTP_OK;
113 * Invoked to take action after a network has been updated.
115 * @param network An instance of modified Neutron Network object.
118 public void neutronNetworkUpdated(NeutronNetwork network) {
119 enqueueEvent(new NorthboundEvent(network, Action.UPDATE));
121 private void doNeutronNetworkUpdated(NeutronNetwork network) {
122 neutronL3Adapter.handleNeutronNetworkEvent(network, Action.UPDATE);
126 * Invoked when a network deletion is requested
127 * to indicate if the specified network can be deleted.
129 * @param network An instance of the Neutron Network object to be deleted.
130 * @return A HTTP status code to the deletion request.
133 public int canDeleteNetwork(NeutronNetwork network) {
134 return HttpURLConnection.HTTP_OK;
138 * Invoked to take action after a network has been deleted.
140 * @param network An instance of deleted Neutron Network object.
143 public void neutronNetworkDeleted(NeutronNetwork network) {
144 enqueueEvent(new NorthboundEvent(network, Action.DELETE));
146 private void doNeutronNetworkDeleted(NeutronNetwork network) {
147 neutronL3Adapter.handleNeutronNetworkEvent(network, Action.DELETE);
149 /* Is this the last Neutron tenant network */
150 List <NeutronNetwork> networks;
151 if (neutronNetworkCache != null) {
152 networks = neutronNetworkCache.getAllNetworks();
153 if (networks.isEmpty()) {
154 logger.trace("neutronNetworkDeleted: last tenant network, delete tunnel ports...");
155 List<Node> nodes = connectionService.getNodes();
157 for (Node node : nodes) {
158 List<String> phyIfName = bridgeConfigurationManager.getAllPhysicalInterfaceNames(node);
160 ConcurrentMap<String, Row> ports =
161 this.ovsdbConfigurationService.getRows(node,
162 ovsdbConfigurationService.getTableName(node, Port.class));
164 for (Row portRow : ports.values()) {
165 Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow);
166 for (UUID interfaceUuid : port.getInterfacesColumn().getData()) {
167 Row ifaceRow = ovsdbConfigurationService
169 ovsdbConfigurationService.getTableName(node, Interface.class),
170 interfaceUuid.toString());
171 Interface iface = ovsdbConfigurationService.getTypedRow(node, Interface.class, ifaceRow);
172 String interfaceType = iface.getTypeColumn().getData();
173 if (interfaceType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)
174 || interfaceType.equalsIgnoreCase(
175 NetworkHandler.NETWORK_TYPE_GRE)) {
176 /* delete tunnel ports on this node */
177 logger.trace("Delete tunnel interface {}", iface.getName());
178 ovsdbConfigurationService.deleteRow(node,
179 ovsdbConfigurationService.getTableName(node, Port.class),
180 port.getUuid().toString());
182 } else if (!phyIfName.isEmpty() && phyIfName.contains(iface.getName())) {
183 logger.trace("Delete physical interface {}", iface.getName());
184 ovsdbConfigurationService.deleteRow(node,
185 ovsdbConfigurationService.getTableName(node, Port.class),
186 port.getUuid().toString());
192 } catch (Exception e) {
193 logger.error("Exception during handlingNeutron network delete", e);
198 tenantNetworkManager.networkDeleted(network.getID());
204 * @param abstractEvent the {@link org.opendaylight.ovsdb.openstack.netvirt.AbstractEvent} event to be handled.
205 * @see org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher
208 public void processEvent(AbstractEvent abstractEvent) {
209 if (!(abstractEvent instanceof NorthboundEvent)) {
210 logger.error("Unable to process abstract event " + abstractEvent);
213 NorthboundEvent ev = (NorthboundEvent) abstractEvent;
214 switch (ev.getAction()) {
216 doNeutronNetworkCreated(ev.getNeutronNetwork());
219 doNeutronNetworkUpdated(ev.getNeutronNetwork());
222 doNeutronNetworkDeleted(ev.getNeutronNetwork());
225 logger.warn("Unable to process event action " + ev.getAction());