2 * Copyright (c) 2014 Cisco Systems, Inc. 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.lispflowmapping.neutron;
12 import java.net.HttpURLConnection;
14 import org.apache.commons.net.util.SubnetUtils;
15 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
16 import org.opendaylight.neutron.spi.INeutronSubnetAware;
17 import org.opendaylight.neutron.spi.NeutronSubnet;
18 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.LispAFIAddress;
19 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainer;
20 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainerBuilder;
21 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.Address;
22 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.address.Ipv4Builder;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
26 * Lisp Service implementation of NeutronSubnetAware API
27 * Creation of a new Subnet results in defining the subnet as an EID prefix
28 * in the LISP Mapping System with subnet's network UUID as the key to use
29 * for registering mappings for the subnet.
32 public class LispNeutronSubnetHandler extends LispNeutronService implements INeutronSubnetAware {
33 private static final Integer SIX = Integer.valueOf(6);
35 // The implementation for each of these services is resolved by the OSGi Service Manager
36 private volatile ILispNeutronService lispNeutronService;
39 public int canCreateSubnet(NeutronSubnet subnet) {
40 LOG.info("Neutron canCreateSubnet : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
42 LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
44 return HttpURLConnection.HTTP_OK;
48 * Method adds the newly created subnet as an EID prefix to the
49 * MappingService. The subnet's network UUID is used as the key
50 * for this EID prefix.
54 public void neutronSubnetCreated(NeutronSubnet subnet) {
55 //TODO update for multi-tenancy
57 LOG.info("Neutron Subnet Created request : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
59 LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
61 int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
62 SubnetUtils util = new SubnetUtils(subnet.getCidr());
63 SubnetInfo info = util.getInfo();
65 // Determine the IANA code for the subnet IP version
66 // Default is set to IPv4 for neutron subnets
69 if ( SIX.equals(subnet.getIpVersion()) )
72 LispAFIAddress lispAddress = new Ipv4Builder().setIpv4Address(new Ipv4Address(info.getNetworkAddress())).setAfi(ianaCode).build();
73 LispAddressContainer addressContainer = new LispAddressContainerBuilder().setAddress((Address) lispAddress).build();
76 lispNeutronService.getMappingService().addAuthenticationKey(addressContainer, masklen, subnet.getNetworkUUID());
78 LOG.debug("Neutron Subnet Added to MapServer : Subnet name: " + subnet.getName() + " EID Prefix: " +
79 addressContainer.toString() + " Key: " + subnet.getNetworkUUID());
82 LOG.error("Adding new subnet to lisp service mapping service failed. Subnet : " + subnet.toString());
88 * Method to check whether new Subnet can be created by LISP
89 * implementation of Neutron service API.
90 * Since we store the Cidr part of the subnet as the main key to the Lisp
91 * mapping service, we do not support updates to subnets that change it's cidr.
94 public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original) {
95 if (delta == null || original == null){
96 LOG.error("Neutron canUpdateSubnet rejected: subnet objects were null");
97 return HttpURLConnection.HTTP_BAD_REQUEST;
99 LOG.info("Neutron canUpdateSubnet : Subnet name: " + original.getName() + " Subnet Cidr: " +
101 LOG.debug("Lisp Neutron Subnet update: original : " + original.toString() + " delta : " + delta.toString());
104 // We do not accept a Subnet update that changes the cidr. If cider or network UUID is changed, return error.
105 if ( !(original.getCidr().equals(delta.getCidr())) ){
106 LOG.error("Neutron canUpdateSubnet rejected: Subnet name: " + original.getName() + " Subnet Cidr: " +
108 return HttpURLConnection.HTTP_CONFLICT;
110 return HttpURLConnection.HTTP_OK;
114 public void neutronSubnetUpdated(NeutronSubnet subnet) {
115 // Nothing to do here.
119 * Method to check if subnet can be deleted.
120 * Returns error only if subnet does not exist
121 * in the lisp mapping service.
124 public int canDeleteSubnet(NeutronSubnet subnet) {
125 LOG.info("Neutron canDeleteSubnet : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
126 subnet.getCidr() + "Key: " + subnet.getNetworkUUID());
127 LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
130 int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
131 SubnetUtils util = new SubnetUtils(subnet.getCidr());
132 SubnetInfo info = util.getInfo();
134 // Determine the IANA code for the subnet IP version
135 // Default is set to IPv4 for neutron subnets
137 if ( SIX.equals(subnet.getIpVersion()) )
140 LispAFIAddress lispAddress = new Ipv4Builder().setIpv4Address(new Ipv4Address(info.getNetworkAddress())).setAfi(ianaCode).build();
141 LispAddressContainer addressContainer = new LispAddressContainerBuilder().setAddress((Address) lispAddress).build();
143 // if subnet does not exist in MapServer, return error
145 if (lispNeutronService.getMappingService().getAuthenticationKey(addressContainer, masklen) == null){
147 LOG.error("Neutron canDeleteSubnet rejected : Subnet does not exist: Subnet name: " +
149 " Eid Prefix: " + addressContainer.toString() +
150 " Key: " + subnet.getNetworkUUID());
151 return HttpURLConnection.HTTP_BAD_REQUEST;
153 result = HttpURLConnection.HTTP_OK;
156 LOG.error("canDeleteSubnet request rejected. Subnet : " + subnet.toString());
157 result = HttpURLConnection.HTTP_BAD_REQUEST;
163 * Method removes the EID prefix and key associated
164 * with the deleted subnet from Lisp mapping service.
167 public void neutronSubnetDeleted(NeutronSubnet subnet) {
168 LOG.info("Neutron Subnet Deleted Request : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
169 subnet.getCidr() + "Key: " + subnet.getNetworkUUID());
170 LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
172 int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
173 SubnetUtils util = new SubnetUtils(subnet.getCidr());
174 SubnetInfo info = util.getInfo();
176 // Determine the IANA code for the subnet IP version
177 // Default is set to IPv4 for neutron subnets
180 if ( SIX.equals(subnet.getIpVersion()) )
183 LispAFIAddress lispAddress = new Ipv4Builder().setIpv4Address(new Ipv4Address(info.getNetworkAddress())).setAfi(ianaCode).build();
184 LispAddressContainer addressContainer = new LispAddressContainerBuilder().setAddress((Address) lispAddress).build();
187 // if subnet does not exist in MapServer, return error
188 if (lispNeutronService.getMappingService().getAuthenticationKey(addressContainer,masklen) == null){
189 LOG.error("Neutron Delete Subnet Failed: Subnet does not exist: Subnet name: " + subnet.getName() +
190 " Eid Prefix: " + addressContainer.toString() +
191 "Key: " + subnet.getNetworkUUID());
194 lispNeutronService.getMappingService().removeAuthenticationKey(addressContainer, masklen);
196 LOG.debug("Neutron Subnet Deleted from MapServer : Subnet name: " + subnet.getName() +
197 " Eid Prefix: " + addressContainer.toString() +
198 " Key: " + subnet.getNetworkUUID());
201 LOG.error("Deleting subnet's EID prefix from mapping service failed + Subnet: " + subnet.toString());