b503fb7abc91ba6e3d24cb5ca9b5fad74e37fa8c
[lispflowmapping.git] / mappingservice / neutron / src / main / java / org / opendaylight / lispflowmapping / neutron / LispNeutronSubnetHandler.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.lispflowmapping.neutron;
10
11
12 import java.net.HttpURLConnection;
13
14 import org.apache.commons.net.util.SubnetUtils;
15 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
16 import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;
17 import org.opendaylight.controller.networkconfig.neutron.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;
24
25 /**
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.
30  *
31  */
32 public class LispNeutronSubnetHandler extends LispNeutronService implements INeutronSubnetAware {
33
34     // The implementation for each of these services is resolved by the OSGi Service Manager
35     private volatile ILispNeutronService lispNeutronService;
36
37         @Override
38         public int canCreateSubnet(NeutronSubnet subnet) {
39                 logger.info("Neutron canCreateSubnet : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
40                         subnet.getCidr());
41         logger.debug("Lisp Neutron Subnet: " + subnet.toString());
42
43         return HttpURLConnection.HTTP_OK;
44         }
45
46         /**
47          * Method adds the newly created subnet as an EID prefix to the
48          * MappingService. The subnet's network UUID is used as the key
49          * for this EID prefix.
50          *
51          */
52         @Override
53         public void neutronSubnetCreated(NeutronSubnet subnet) {
54                 //TODO update for multi-tenancy
55
56                 logger.info("Neutron Subnet Created request : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
57                         subnet.getCidr());
58         logger.debug("Lisp Neutron Subnet: " + subnet.toString());
59
60             int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
61             SubnetUtils util = new SubnetUtils(subnet.getCidr());
62         SubnetInfo info = util.getInfo();
63
64         // Determine the IANA code for the subnet IP version
65         // Default is set to IPv4 for neutron subnets
66
67         short ianaCode = 1;
68         if ( (new Integer(6)).equals(subnet.getIpVersion()) )
69                 ianaCode = 2;
70
71         LispAFIAddress lispAddress = new Ipv4Builder().setIpv4Address(new Ipv4Address(info.getNetworkAddress())).setAfi(ianaCode).build();
72         LispAddressContainer addressContainer = new LispAddressContainerBuilder().setAddress((Address) lispAddress).build();
73
74         try{
75                 lispNeutronService.getMappingService().addAuthenticationKey(addressContainer, masklen, subnet.getNetworkUUID());
76
77                 logger.debug("Neutron Subnet Added to MapServer : Subnet name: " + subnet.getName() + " EID Prefix: " +
78                         addressContainer.toString() + " Key: " + subnet.getNetworkUUID());
79         }
80         catch (Exception e){
81                 logger.error("Adding new subnet to lisp service mapping service failed. Subnet : " + subnet.toString());
82         }
83
84         }
85
86         /**
87          * Method to check whether new Subnet can be created by LISP
88          * implementation of Neutron service API.
89          * Since we store the Cidr part of the subnet as the main key to the Lisp
90          * mapping service, we do not support updates to subnets that change it's cidr.
91          */
92         @Override
93         public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original) {
94                 if (delta == null || original == null){
95                 logger.error("Neutron canUpdateSubnet rejected: subnet objects were null");
96                 return HttpURLConnection.HTTP_BAD_REQUEST;
97                 }
98                 logger.info("Neutron canUpdateSubnet : Subnet name: " + original.getName() + " Subnet Cidr: " +
99                         original.getCidr());
100         logger.debug("Lisp Neutron Subnet update: original : " + original.toString() + " delta : " + delta.toString());
101
102
103                 // We do not accept a Subnet update that changes the cidr. If cider or network UUID is changed, return error.
104                 if ( !(original.getCidr().equals(delta.getCidr())) ){
105                         logger.error("Neutron canUpdateSubnet rejected: Subnet name: " + original.getName() + " Subnet Cidr: " +
106                                 original.getCidr());
107                         return HttpURLConnection.HTTP_CONFLICT;
108                 }
109         return HttpURLConnection.HTTP_OK;
110         }
111
112         @Override
113         public void neutronSubnetUpdated(NeutronSubnet subnet) {
114                 // Nothing to do here.
115         }
116
117         /**
118          * Method to check if subnet can be deleted.
119          * Returns error only if subnet does not exist
120          * in the lisp mapping service.
121          */
122         @Override
123         public int canDeleteSubnet(NeutronSubnet subnet) {
124         logger.info("Neutron canDeleteSubnet : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
125                         subnet.getCidr() + "Key: " + subnet.getNetworkUUID());
126         logger.debug("Lisp Neutron Subnet: " + subnet.toString());
127
128         int result;
129             int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
130             SubnetUtils util = new SubnetUtils(subnet.getCidr());
131         SubnetInfo info = util.getInfo();
132
133         // Determine the IANA code for the subnet IP version
134         // Default is set to IPv4 for neutron subnets
135         short ianaCode = 1;
136         if ( (new Integer(6)).equals(subnet.getIpVersion()) )
137                 ianaCode = 2;
138
139         LispAFIAddress lispAddress = new Ipv4Builder().setIpv4Address(new Ipv4Address(info.getNetworkAddress())).setAfi(ianaCode).build();
140         LispAddressContainer addressContainer = new LispAddressContainerBuilder().setAddress((Address) lispAddress).build();
141
142         // if subnet does not exist in MapServer, return error
143         try{
144                 if (lispNeutronService.getMappingService().getAuthenticationKey(addressContainer, masklen) == null){
145
146                         logger.error("Neutron canDeleteSubnet rejected : Subnet does not exist: Subnet name: " +
147                                         subnet.getName() +
148                                         " Eid Prefix: " + addressContainer.toString() +
149                                         " Key: " + subnet.getNetworkUUID());
150                         return HttpURLConnection.HTTP_BAD_REQUEST;
151                 }
152                 result =  HttpURLConnection.HTTP_OK;
153         }
154         catch (Exception e){
155                 logger.error("canDeleteSubnet request rejected. Subnet : " + subnet.toString());
156                 result =  HttpURLConnection.HTTP_BAD_REQUEST;
157         }
158         return result;
159         }
160
161         /**
162          * Method removes the EID prefix and key associated
163          * with the deleted subnet from Lisp mapping service.
164          */
165         @Override
166         public void neutronSubnetDeleted(NeutronSubnet subnet) {
167                 logger.info("Neutron Subnet Deleted Request : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
168                         subnet.getCidr() + "Key: " + subnet.getNetworkUUID());
169         logger.debug("Lisp Neutron Subnet: " + subnet.toString());
170
171         int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
172             SubnetUtils util = new SubnetUtils(subnet.getCidr());
173         SubnetInfo info = util.getInfo();
174
175         // Determine the IANA code for the subnet IP version
176         // Default is set to IPv4 for neutron subnets
177
178         short ianaCode = 1;
179         if ( (new Integer(6)).equals(subnet.getIpVersion()) )
180                 ianaCode = 2;
181
182         LispAFIAddress lispAddress = new Ipv4Builder().setIpv4Address(new Ipv4Address(info.getNetworkAddress())).setAfi(ianaCode).build();
183         LispAddressContainer addressContainer = new LispAddressContainerBuilder().setAddress((Address) lispAddress).build();
184
185         try{
186                 // if subnet does not exist in MapServer, return error
187                 if (lispNeutronService.getMappingService().getAuthenticationKey(addressContainer,masklen) == null){
188                     logger.error("Neutron Delete Subnet Failed: Subnet does not exist: Subnet name: " + subnet.getName() +
189                                 " Eid Prefix: " + addressContainer.toString() +
190                                 "Key: " + subnet.getNetworkUUID());
191                     return;
192                 }
193                 lispNeutronService.getMappingService().removeAuthenticationKey(addressContainer, masklen);
194
195                 logger.debug("Neutron Subnet Deleted from MapServer : Subnet name: " + subnet.getName() +
196                                 " Eid Prefix: " + addressContainer.toString() +
197                                 " Key: " + subnet.getNetworkUUID());
198         }
199         catch (Exception e){
200                 logger.error("Deleting subnet's EID prefix from mapping service failed + Subnet: " + subnet.toString());
201         }
202         }
203
204 }