Revision f8615d6e

View differences:

include/AddressRange.h
35 35
{
36 36
public:
37 37

  
38
    AddressRange(unsigned int _id):id(_id),next(0),used_addr(0){};
39

  
40 38
    virtual ~AddressRange(){};
41 39

  
42 40
    // *************************************************************************
......
103 101
     *            SIZE = 1024,
104 102
     *            ULA_PREFIX    = "fd00:0:0:1::",
105 103
     *            GLOBAL_PREFIX = "2001::"]
104
     *
105
     * NOTE: This function is part of the AddressRange interface. The AR
106
     * implementation may contact an external IPAM to complete or validate
107
     * the AR allocation request.
106 108
     */
107
    int from_vattr(VectorAttribute * attr, string& error_msg);
109
    virtual int from_vattr(VectorAttribute * attr, string& error_msg) = 0;
108 110

  
109 111
    /**
110 112
     *  Builds an Address Range from a vector attribute stored in the DB
......
276 278
     */
277 279
    unsigned int get_used_addr() const
278 280
    {
279
        return used_addr;
281
        return allocated.size();
280 282
    }
281 283

  
282 284
    /**
......
284 286
     */
285 287
    unsigned int get_free_addr() const
286 288
    {
287
        return size - used_addr;
289
        return size - allocated.size();
288 290
    }
289 291

  
290 292
    /**
......
331 333
            string&             error_msg);
332 334

  
333 335
    /**
336
     *  Helper function to initialize restricte attributes of an AddressRange
337
     */
338
    static void set_restricted_attributes(vector<const SingleAttribute *>& ras);
339

  
340
    /**
334 341
     *  Get the security groups for this AR.
335 342
     *    @return a reference to the security group set
336 343
     */
......
345 352
     */
346 353
    friend int AddressRangePool::add_ar(AddressRange * ar);
347 354

  
348
    static void set_restricted_attributes(vector<const SingleAttribute *>& rattrs);
355
protected:
356
    /**
357
     *  Base constructor it cannot be called directly but from the
358
     *  AddressRange factory constructor.
359
     */
360
    AddressRange(unsigned int _id):id(_id){};
361

  
362
    /**
363
     * Builds the AddressRange from its vector attribute representation
364
     */
365
    int from_attr(VectorAttribute * attr, string& error_msg);
366

  
367
    /* ---------------------------------------------------------------------- */
368
    /* Implementation specific address management interface                   */
369
    /* ---------------------------------------------------------------------- */
370
    /**
371
     *  Sets the given range of addresses (by index) as used
372
     *    @param index the first address to set as used
373
     *    @param sz number of addresses to set
374
     *    @param msg describing the error if any
375
     *
376
     *    @return 0 if success
377
     */
378
    virtual int allocate_addr(unsigned int index, unsigned int sz, string& msg) = 0;
379
    /**
380
     *  Gets a range of free addresses
381
     *    @param index the first address in the range
382
     *    @param size number of addresses requested in the range
383
     *    @param msg describing the error if any
384
     *
385
     *    @return 0 if success
386
     */
387
    virtual int get_addr(unsigned int& index, unsigned int sz, string& msg) = 0;
388

  
389
    /**
390
     *  Sets the given address (by index) as free
391
     *    @param index of the address
392
     *    @param msg describing the error if any
393
     *
394
     *    @return 0 if success
395
     */
396
    virtual int free_addr(unsigned int index, string& msg) = 0;
397

  
398
    /* ---------------------------------------------------------------------- */
399
    /* Allocated addresses                                                    */
400
    /* ---------------------------------------------------------------------- */
401
    /**
402
     *  Map to store the allocated address indexed by the address index relative
403
     *  to the mac/ip values. It contains also the type and id of the object
404
     *  owning the address.
405
     *
406
     *              +--------------------+--------------------+
407
     *  index ----> | ObjectType(32bits) | Object ID (32bits) |
408
     *              +--------------------+--------------------+
409
     *
410
     *  Address = First Address + index
411
     */
412
    map<unsigned int, long long> allocated;
349 413

  
350 414
private:
351 415
    /* ---------------------------------------------------------------------- */
......
399 463
    /* ---------------------------------------------------------------------- */
400 464
    /* NIC setup functions                                                    */
401 465
    /* ---------------------------------------------------------------------- */
466

  
467
    /**
468
     *  Check if the given MAC is valid for this address range by verifying:
469
     *    - Correct : notation
470
     *    - Part of the AR
471
     *
472
     *    @param index of the MAC in the AR
473
     *    @param mac_s string representation of the MAC in : notation
474
     *    @param check_free apart from previous checks
475
     *
476
     *    @return true if the MAC is valid
477
     */
478
    bool is_valid_mac(unsigned int& index, const string& mac_s, bool check_free);
479

  
480
    /**
481
     *  Check if the given IP is valid for this address range by verifying:
482
     *    - AR is of type IP4 or IP4_6
483
     *    - Correct . notation
484
     *    - Part of the AR
485
     *
486
     *    @param index of the IP in the AR
487
     *    @param ip_s string representation of the IP in . notation
488
     *    @param check_free apart from previous checks
489
     *
490
     *    @return true if the IP is valid
491
     */
492
    bool is_valid_ip(unsigned int& index, const string& ip_s, bool check_free);
493

  
402 494
    /**
403 495
     *  Writes MAC address to the given NIC attribute
404 496
     *    @param addr_index internal index for the lease
......
450 542
    /**
451 543
     *  Adds a new allocated address to the map. Updates the ALLOCATED attribute
452 544
     */
453
    void allocate_addr(PoolObjectSQL::ObjectType ot, int obid,
545
    void set_allocated_addr(PoolObjectSQL::ObjectType ot, int obid,
454 546
        unsigned int addr_index);
455 547

  
456 548
    /**
549
     *  Sets the address lease as used and fills a NIC attribute with the
550
     *  configuration parameters from the address range.
551
     *    @param index of the lease in the address range
552
     *    @param ot the type of the object allocating the address
553
     *    @param obid the id of the object
554
     *    @param nic the VM NIC attribute
555
     *    @param inherit attributes to be added to the NIC attribute
556
     *    @return 0 if success
557
     */
558
    void allocate_by_index(unsigned int index,
559
        PoolObjectSQL::ObjectType ot,
560
        int                       obid,
561
        VectorAttribute*          nic,
562
        const vector<string>&     inherit);
563

  
564
    /**
457 565
     *  Frees an address from the map. Updates the ALLOCATED attribute
458 566
     */
459
    int free_addr(PoolObjectSQL::ObjectType ot, int obid,
567
    int free_allocated_addr(PoolObjectSQL::ObjectType ot, int obid,
460 568
        unsigned int addr_index);
461 569

  
462 570
    /**
......
529 637
    set<int> security_groups;
530 638

  
531 639
    /**
532
     *  The Address Range attributes as a Template VectorAttribute. This is
533
     *  used to generate XML or a template representation of the AR.
640
     *  The name of the IPAM driver (internal for OpenNebula built-in)
534 641
     */
535
    VectorAttribute * attr;
642
    string ipam_mad;
536 643

  
537
    /* ---------------------------------------------------------------------- */
538
    /* Allocated address & control                                            */
539
    /* ---------------------------------------------------------------------- */
540 644
    /**
541
     *  Map to store the allocated address indexed by the address index relative
542
     *  to the mac/ip values. It contains also the type and id of the object
543
     *  owning the address ObjectType(32bits) | Object ID (32)
645
     *  The Address Range attributes as a Template VectorAttribute. This is
646
     *  used to generate XML or a template representation of the AR.
544 647
     */
545
    map<unsigned int, long long> allocated;
546

  
547
    unsigned int next;
548

  
549
    unsigned int used_addr;
648
    VectorAttribute * attr;
550 649

  
551 650
    /* ---------------------------------------------------------------------- */
552 651
    /* Restricted Attributes                                                  */
include/AddressRangeIPAM.h
1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems                */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

  
17
#ifndef ADDRESS_RANGE_IPAM_H_
18
#define ADDRESS_RANGE_IPAM_H_
19

  
20
#include <string>
21

  
22
#include "AddressRange.h"
23
#include "AddressRangePool.h"
24

  
25
class VectorAttribute;
26

  
27
class AddressRangeIPAM : public AddressRange
28
{
29
public:
30
    AddressRangeIPAM(unsigned int _id):AddressRange(_id){};
31

  
32
    virtual ~AddressRangeIPAM(){};
33

  
34
    /* ---------------------------------------------------------------------- */
35
    /* AddressRange Interface **TODO contact IPAM**                           */
36
    /* ---------------------------------------------------------------------- */
37
    int from_vattr(VectorAttribute * attr, std::string& error_msg)
38
    {
39
        error_msg = "Not Implemented";
40
        return -1;
41
    };
42

  
43
    int allocate_addr(unsigned int index, unsigned int size, string& error_msg)
44
    {
45
        error_msg = "Not Implemented";
46
        return -1;
47
    };
48

  
49
    int get_addr(unsigned int& index, unsigned int rsize, string& error_msg)
50
    {
51
        error_msg = "Not Implemented";
52
        return -1;
53
    };
54

  
55
    int free_addr(unsigned int index, string& error_msg)
56
    {
57
        error_msg = "Not Implemented";
58
        return -1;
59
    };
60
};
61

  
62
#endif
include/AddressRangeInternal.h
1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems                */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

  
17
#ifndef ADDRESS_RANGE_INTERNAL_H_
18
#define ADDRESS_RANGE_INTERNAL_H_
19

  
20
#include <string>
21

  
22
#include "AddressRange.h"
23
#include "AddressRangePool.h"
24

  
25
class VectorAttribute;
26

  
27
class AddressRangeInternal : public AddressRange
28
{
29
public:
30
    AddressRangeInternal(unsigned int _id):AddressRange(_id), next(0){};
31

  
32
    virtual ~AddressRangeInternal(){};
33

  
34
    /* ---------------------------------------------------------------------- */
35
    /* AddressRange Interface                                                 */
36
    /* ---------------------------------------------------------------------- */
37

  
38
    /**
39
     *  Init an Address Range based on a vector attribute.
40
     *    @param attr the description of the AddressRange
41
     *    @param error_msg description if error
42
     *    @return 0 on success
43
     */
44
    int from_vattr(VectorAttribute * attr, std::string& error_msg)
45
    {
46
        return AddressRange::from_attr(attr, error_msg);
47
    }
48

  
49
    /**
50
     *  Sets the given range of addresses (by index) as used
51
     *    @param index the first address to set as used
52
     *    @param sz number of addresses to set
53
     *    @param msg describing the error if any
54
     *
55
     *    @return 0 if success
56
     */
57
    int allocate_addr(unsigned int index, unsigned int size, string& error_msg)
58
    {
59
        return 0;
60
    }
61

  
62
    /**
63
     *  Gets a range of free addresses
64
     *    @param index the first address in the range
65
     *    @param size number of addresses requested in the range
66
     *    @param msg describing the error if any
67
     *
68
     *    @return 0 if success
69
     */
70
    int get_addr(unsigned int& index, unsigned int rsize, string& error_msg)
71
    {
72
        if ( rsize == 1 )
73
        {
74
            return get_single_addr(index, error_msg);
75
        }
76

  
77
        return get_range_addr(index, rsize, error_msg);
78
    }
79

  
80
    /**
81
     *  Sets the given address (by index) as free
82
     *    @param index of the address
83
     *    @param msg describing the error if any
84
     *
85
     *    @return 0 if success
86
     */
87
    int free_addr(unsigned int index, string& msg)
88
    {
89
        return 0;
90
    };
91

  
92
private:
93
    /**
94
     *  Lookup index for the next free address lease
95
     */
96
    unsigned int next;
97

  
98
    /**
99
     *  Get a free lease
100
     *    @param index of the free lease, undefined if error
101
     *    @param msg with error description if any
102
     *    @return 0 on success -1 otherwise
103
     */
104
    int get_single_addr(unsigned int& index, std::string& msg);
105

  
106
    /**
107
     *  Get a free and continuous range of leases
108
     *    @param index of the first free lease in range, undefined if error
109
     *    @param sz of the range
110
     *    @param msg with error description if any
111
     *    @return 0 on success -1 otherwise
112
     */
113
    int get_range_addr(unsigned int& index, unsigned int sz, std::string& msg);
114
};
115

  
116
#endif
include/AddressRangePool.h
82 82
     *    the reason.
83 83
     *    @return 0 on success
84 84
     */
85
    int update_ar(vector<VectorAttribute *> ars, bool keep_restricted, string& error_msg);
86

  
85
    int update_ar(vector<VectorAttribute *> ars, bool keep_restricted,
86
            string& error_msg);
87 87
    /**
88 88
     *  Allocates a new *empty* address range. It is not added to the pool as it
89 89
     *  needs to be initialized. Only the AR_ID is set.
90
     *    @param ipam_mad sets the type of AddressRange to be created: internal,
91
     *    IPAM...
90 92
     *    @return the new address range.
91 93
     */
92
    AddressRange * allocate_ar();
94
    AddressRange * allocate_ar(const string& ipam_mad);
93 95

  
94 96
    /**
95 97
     *  Adds a new address range to the pool. It should be allocated by the
......
369 371
     *  Used addresses
370 372
     */
371 373
    unsigned int used_addr;
374

  
375
    /**
376
     *  Allocates a new *empty* address range. It is not added to the pool as it
377
     *  needs to be initialized.
378
     *    @param ipam_mad sets the type of AddressRange to be created: internal,
379
     *    IPAM...
380
     *    @param ar_id for the AddressRange
381
     *    @return the new address range.
382
     */
383
    AddressRange * allocate_ar(const string& ipam_mad, unsigned int ar_id);
372 384
};
373 385

  
374 386
#endif
include/VirtualNetwork.h
158 158
     *  ar_pool
159 159
     *    @return pointer to the new address range
160 160
     */
161
    AddressRange * allocate_ar()
161
    AddressRange * allocate_ar(const string& ipam_mad)
162 162
    {
163
        return ar_pool.allocate_ar();
163
        return ar_pool.allocate_ar(ipam_mad);
164 164
    }
165 165

  
166 166
    /**
src/vnm/AddressRange.cc
70 70
/* ************************************************************************** */
71 71
/* ************************************************************************** */
72 72

  
73
int AddressRange::from_vattr(VectorAttribute *vattr, string& error_msg)
73
int AddressRange::from_attr(VectorAttribute *vattr, string& error_msg)
74 74
{
75 75
    string value;
76 76

  
......
293 293

  
294 294
            return -1;
295 295
        }
296

  
297
        next = 0;
298 296
    }
299 297
    else
300 298
    {
......
461 459
        }
462 460
    }
463 461

  
464
    oss << "<USED_LEASES>" << used_addr << "</USED_LEASES>";
462
    oss << "<USED_LEASES>" << get_used_addr() << "</USED_LEASES>";
465 463

  
466 464
    if (allocated.empty())
467 465
    {
......
749 747
/* ************************************************************************** */
750 748
/* ************************************************************************** */
751 749

  
750
bool AddressRange::is_valid_mac(unsigned int& index, const string& mac_s,
751
    bool check_free)
752
{
753
    unsigned int mac_i[2];
754

  
755
    if (mac_to_i(mac_s, mac_i) == -1)
756
    {
757
        return false;
758
    }
759

  
760
    if ((mac_i[1] != mac[1]) || (mac_i[0] < mac[0]))
761
    {
762
        return false;
763
    }
764

  
765
    index = mac_i[0] - mac[0];
766

  
767
    if ((check_free && allocated.count(index) != 0) || (index >= size))
768
    {
769
        return false;
770
    }
771

  
772
    return true;
773
}
774

  
775
/* -------------------------------------------------------------------------- */
776
/* -------------------------------------------------------------------------- */
777

  
778
bool AddressRange::is_valid_ip(unsigned int& index, const string& ip_s,
779
    bool check_free)
780
{
781
    if (!(type & 0x00000002))//Not of type IP4 or IP4_6
782
    {
783
        return false;
784
    }
785

  
786
    unsigned int ip_i;
787

  
788
    if (ip_to_i(ip_s, ip_i) == -1)
789
    {
790
        return false;
791
    }
792

  
793
    if (ip_i < ip)
794
    {
795
        return false;
796
    }
797

  
798
    index = ip_i - ip;
799

  
800
    if ((check_free && allocated.count(index) != 0) || (index >= size))
801
    {
802
        return false;
803
    }
804

  
805
    return true;
806
}
807

  
808
/* -------------------------------------------------------------------------- */
809
/* -------------------------------------------------------------------------- */
810

  
752 811
void AddressRange::set_mac(unsigned int addr_index, VectorAttribute * nic) const
753 812
{
754 813
    unsigned int new_mac[2];
......
895 954
        }
896 955

  
897 956
        allocated.insert(make_pair(addr_index,object_pack));
898

  
899
        used_addr++;
900 957
    }
901 958

  
902
    if ( used_addr > size )
959
    if ( get_used_addr() > size )
903 960
    {
904 961
        return -1;
905 962
    }
......
909 966

  
910 967
/* -------------------------------------------------------------------------- */
911 968

  
912
void AddressRange::allocate_addr(PoolObjectSQL::ObjectType ot, int obid,
969
void AddressRange::set_allocated_addr(PoolObjectSQL::ObjectType ot, int obid,
913 970
    unsigned int addr_index)
914 971
{
915 972
    long long lobid = obid & 0x00000000FFFFFFFFLL;
916 973

  
917 974
    allocated.insert(make_pair(addr_index,ot|lobid));
918 975

  
919
    used_addr++;
920

  
921 976
    allocated_to_attr();
922 977
}
923 978

  
924 979
/* -------------------------------------------------------------------------- */
925 980

  
926
int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid,
981
int AddressRange::free_allocated_addr(PoolObjectSQL::ObjectType ot, int obid,
927 982
    unsigned int addr_index)
928 983
{
929 984
    long long lobid = obid & 0x00000000FFFFFFFFLL;
......
937 992
        allocated.erase(it);
938 993
        allocated_to_attr();
939 994

  
940
        used_addr--;
941

  
942 995
        return 0;
943 996
    }
944 997

  
......
948 1001
/* ************************************************************************** */
949 1002
/* ************************************************************************** */
950 1003

  
951
int AddressRange::allocate_addr(
1004
void AddressRange::allocate_by_index(unsigned int index,
952 1005
    PoolObjectSQL::ObjectType ot,
953 1006
    int                       obid,
954 1007
    VectorAttribute*          nic,
955 1008
    const vector<string>&     inherit)
956 1009
{
957
    if ( used_addr >= size )
1010
    set_mac(index, nic);
1011

  
1012
    if (type & 0x00000002 )
958 1013
    {
959
        return -1;
1014
        set_ip(index, nic);
960 1015
    }
961 1016

  
962
    for ( unsigned int i=0; i<size; i++, next = (next+1)%size )
1017
    if (type & 0x00000004)
963 1018
    {
964
        if ( allocated.count(next) == 0 )
965
        {
966
            set_mac(next, nic);
967

  
968
            if (type & 0x00000002 )
969
            {
970
                set_ip(next, nic);
971
            }
972

  
973
            if (type & 0x00000004)
974
            {
975
                set_ip6(next, nic);
976
            }
977

  
978
            set_vnet(nic, inherit);
979

  
980
            allocate_addr(ot, obid, next);
981

  
982
            return 0;
983
        }
1019
        set_ip6(index, nic);
984 1020
    }
985 1021

  
986
    return -1;
1022
    set_vnet(nic, inherit);
1023

  
1024
    set_allocated_addr(ot, obid, index);
987 1025
}
988 1026

  
989 1027
/* -------------------------------------------------------------------------- */
990 1028
/* -------------------------------------------------------------------------- */
991 1029

  
992
int AddressRange::allocate_by_mac(
993
    const string&             mac_s,
1030
int AddressRange::allocate_addr(
994 1031
    PoolObjectSQL::ObjectType ot,
995 1032
    int                       obid,
996 1033
    VectorAttribute*          nic,
997 1034
    const vector<string>&     inherit)
998 1035
{
999
    unsigned int mac_i[2];
1036
    unsigned int index;
1037
    string       error_msg;
1000 1038

  
1001
    if (mac_to_i(mac_s, mac_i) == -1)
1039
    if ( get_used_addr() >= size )
1002 1040
    {
1003 1041
        return -1;
1004 1042
    }
1005 1043

  
1006
    if ((mac_i[1] != mac[1]) || (mac_i[0] < mac[0]))
1044
    if ( get_addr(index, 1, error_msg) != 0 )
1007 1045
    {
1008 1046
        return -1;
1009 1047
    }
1010 1048

  
1011
    unsigned int index = mac_i[0] - mac[0];
1049
    allocate_by_index(index, ot, obid, nic, inherit);
1012 1050

  
1013
    if ((allocated.count(index) != 0) || (index >= size))
1014
    {
1015
        return -1;
1016
    }
1051
    return 0;
1052
}
1017 1053

  
1018
    set_mac(index, nic);
1054
/* -------------------------------------------------------------------------- */
1055
/* -------------------------------------------------------------------------- */
1019 1056

  
1020
    if (type & 0x00000002 )
1057
int AddressRange::allocate_by_mac(
1058
    const string&             mac_s,
1059
    PoolObjectSQL::ObjectType ot,
1060
    int                       obid,
1061
    VectorAttribute*          nic,
1062
    const vector<string>&     inherit)
1063
{
1064
    string error_msg;
1065
    unsigned int index;
1066

  
1067
    if (!is_valid_mac(index, mac_s, true))
1021 1068
    {
1022
        set_ip(index, nic);
1069
        return -1;
1023 1070
    }
1024 1071

  
1025
    if (type & 0x00000004)
1072
    if (allocate_addr(index, 1, error_msg) != 0)
1026 1073
    {
1027
        set_ip6(index, nic);
1074
        return -1;
1028 1075
    }
1029 1076

  
1030
    set_vnet(nic, inherit);
1031

  
1032
    allocate_addr(ot, obid, index);
1077
    allocate_by_index(index, ot, obid, nic, inherit);
1033 1078

  
1034 1079
    return 0;
1035 1080
}
......
1044 1089
    VectorAttribute*          nic,
1045 1090
    const vector<string>&     inherit)
1046 1091
{
1047
    if (!(type & 0x00000002))//Not of type IP4 or IP4_6
1048
    {
1049
        return -1;
1050
    }
1051

  
1052
    unsigned int ip_i;
1092
    string error_msg;
1093
    unsigned int index;
1053 1094

  
1054
    if (ip_to_i(ip_s, ip_i) == -1)
1095
    if (!is_valid_ip(index, ip_s, true))
1055 1096
    {
1056 1097
        return -1;
1057 1098
    }
1058 1099

  
1059
    if (ip_i < ip)
1100
    if (allocate_addr(index, 1, error_msg) != 0)
1060 1101
    {
1061 1102
        return -1;
1062 1103
    }
1063 1104

  
1064
    unsigned int index = ip_i - ip;
1065

  
1066
    if (allocated.count(index) != 0 || index >= size )
1067
    {
1068
        return -1;
1069
    }
1070

  
1071
    set_mac(index, nic);
1072

  
1073
    if (type & 0x00000002 )
1074
    {
1075
        set_ip(index, nic);
1076
    }
1077

  
1078
    if (type & 0x00000004)
1079
    {
1080
        set_ip6(index, nic);
1081
    }
1082

  
1083
    set_vnet(nic, inherit);
1084

  
1085
    allocate_addr(ot, obid, index);
1105
    allocate_by_index(index, ot, obid, nic, inherit);
1086 1106

  
1087 1107
    return 0;
1088 1108
}
......
1093 1113
int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid,
1094 1114
    const string& mac_s)
1095 1115
{
1116
    string error_msg;
1096 1117
    unsigned int mac_i[2];
1097 1118

  
1098 1119
    mac_to_i(mac_s, mac_i);
1099 1120

  
1100 1121
    unsigned int index = mac_i[0] - mac[0];
1101 1122

  
1102
    if ( index < 0)
1123
    if (index < 0 || index >= size)
1103 1124
    {
1104 1125
        return -1;
1105 1126
    }
1106 1127

  
1107
    return free_addr(ot, obid, index);
1128
    if (free_addr(index, error_msg) != 0)
1129
    {
1130
        return -1;
1131
    }
1132

  
1133
    return free_allocated_addr(ot, obid, index);
1108 1134
}
1109 1135

  
1110 1136
/* -------------------------------------------------------------------------- */
......
1113 1139
int AddressRange::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid,
1114 1140
    const string& ip_s)
1115 1141
{
1142
    string error_msg;
1143

  
1116 1144
    if (!(type & 0x00000002))//Not of type IP4 or IP4_6
1117 1145
    {
1118 1146
        return -1;
......
1127 1155

  
1128 1156
    unsigned int index = ip_i - ip;
1129 1157

  
1130
    if ((0 <= index ) && (index < size))
1158
    if (index < 0 || index >= size)
1159
    {
1160
        return -1;
1161
    }
1162

  
1163
    if (free_addr(index, error_msg) != 0)
1131 1164
    {
1132
        return free_addr(ot, obid, index);
1165
        return -1;
1133 1166
    }
1134 1167

  
1135
    return -1;
1168
    return free_allocated_addr(ot, obid, index);
1136 1169
}
1137 1170

  
1138 1171
/* -------------------------------------------------------------------------- */
......
1146 1179

  
1147 1180
    int freed = 0;
1148 1181

  
1182
    string error_msg;
1183

  
1149 1184
    while (it != allocated.end())
1150 1185
    {
1151
        if (it->second == obj_pack)
1186
        if (it->second == obj_pack && free_addr(it->first, error_msg) == 0)
1152 1187
        {
1153 1188
            map<unsigned int, long long>::iterator prev_it = it++;
1154 1189

  
1155 1190
            allocated.erase(prev_it);
1156 1191

  
1157
            used_addr--;
1158

  
1159 1192
            freed++;
1160 1193
        }
1161 1194
        else
......
1183 1216

  
1184 1217
    unsigned int index = mac_i[0] - mac[0];
1185 1218

  
1219
    string error_msg;
1220

  
1186 1221
    if ((0 <= index) && (index < size))
1187 1222
    {
1188 1223
        map<unsigned int, long long>::iterator it = allocated.find(index);
......
1196 1231

  
1197 1232
        for (unsigned int i=0; i<rsize; i++)
1198 1233
        {
1199
            if (it != allocated.end() && it->second == obj_pack)
1234
            if (it != allocated.end() && it->second == obj_pack &&
1235
                     free_addr(it->first, error_msg) == 0)
1200 1236
            {
1201 1237
                map<unsigned int, long long>::iterator prev_it = it++;
1202 1238

  
1203 1239
                allocated.erase(prev_it);
1204 1240

  
1205
                used_addr--;
1206

  
1207 1241
                freed++;
1208 1242
            }
1209 1243
            else
......
1248 1282

  
1249 1283
int AddressRange::hold_by_ip(const string& ip_s)
1250 1284
{
1251
    if (!(type & 0x00000002))//Not of type IP4 or IP4_6
1252
    {
1253
        return -1;
1254
    }
1255

  
1256
    unsigned int ip_i;
1285
    string error_msg;
1286
    unsigned int index;
1257 1287

  
1258
    if (ip_to_i(ip_s, ip_i) == -1)
1288
    if (!is_valid_ip(index, ip_s, true))
1259 1289
    {
1260 1290
        return -1;
1261 1291
    }
1262 1292

  
1263
    if (ip_i < ip)
1264
    {
1265
        return -1;
1266
    }
1267

  
1268
    unsigned int index = ip_i - ip;
1269

  
1270
    if (allocated.count(index) != 0 || index >= size )
1293
    if (allocate_addr(index, 1, error_msg) != 0)
1271 1294
    {
1272 1295
        return -1;
1273 1296
    }
1274 1297

  
1275
    allocate_addr(PoolObjectSQL::VM, -1, index);
1298
    set_allocated_addr(PoolObjectSQL::VM, -1, index);
1276 1299

  
1277 1300
    return 0;
1278 1301
}
......
1282 1305

  
1283 1306
int AddressRange::hold_by_mac(const string& mac_s)
1284 1307
{
1285
    unsigned int mac_i[2];
1286

  
1287
    if (mac_to_i(mac_s, mac_i) == -1)
1288
    {
1289
        return -1;
1290
    }
1308
    unsigned int index;
1309
    string error_msg;
1291 1310

  
1292
    if ((mac_i[1] != mac[1]) || (mac_i[0] < mac[0]))
1311
    if (!is_valid_mac(index, mac_s, true))
1293 1312
    {
1294 1313
        return -1;
1295 1314
    }
1296 1315

  
1297
    unsigned int index = mac_i[0] - mac[0];
1298

  
1299
    if ((allocated.count(index) != 0) || (index >= size))
1316
    if (allocate_addr(index, 1, error_msg) != 0)
1300 1317
    {
1301 1318
        return -1;
1302 1319
    }
1303 1320

  
1304
    allocate_addr(PoolObjectSQL::VM, -1, index);
1321
    set_allocated_addr(PoolObjectSQL::VM, -1, index);
1305 1322

  
1306 1323
    return 0;
1307 1324
}
......
1312 1329
int AddressRange::reserve_addr(int vid, unsigned int rsize, AddressRange *rar)
1313 1330
{
1314 1331
    unsigned int first_index;
1332
    string error_msg;
1315 1333

  
1316
    if (rsize > (size - used_addr))
1334
    if (rsize > get_free_addr())
1317 1335
    {
1318
        return -1; //reservation dosen't fit
1336
        return -1;
1319 1337
    }
1320 1338

  
1321
    // --------------- Look for a continuos range of addresses -----------------
1322

  
1323
    bool valid = true;
1324

  
1325
    for (unsigned int i=0; i<size; i++)
1339
    if ( get_addr(first_index, rsize, error_msg) != 0 )
1326 1340
    {
1327
        if ( allocated.count(i) != 0 )
1328
        {
1329
            continue;
1330
        }
1331

  
1332
        valid = true;
1333

  
1334
        for (unsigned int j=0; j<rsize; j++, i++)
1335
        {
1336
            if ( allocated.count(i) != 0  || i >= size )
1337
            {
1338
                valid = false;
1339
                break;
1340
            }
1341
        }
1342

  
1343
        if (valid == true)
1344
        {
1345
            i -= rsize;
1346
            first_index = i;
1347

  
1348
            for (unsigned int j=0; j<rsize; j++, i++)
1349
            {
1350
                allocate_addr(PoolObjectSQL::NET, vid, i);
1351
            }
1352

  
1353
            break;
1354
        }
1341
        return -1;
1355 1342
    }
1356 1343

  
1357
    if (valid == false)
1344
    for (unsigned int j=0, i=first_index; j<rsize; j++, i++)
1358 1345
    {
1359
        return -1; //This address range has not a continuos range big enough
1346
        set_allocated_addr(PoolObjectSQL::NET, vid, i);
1360 1347
    }
1361 1348

  
1362 1349
    VectorAttribute * new_ar = attr->clone();
......
1384 1371
int AddressRange::reserve_addr_by_index(int vid, unsigned int rsize,
1385 1372
    unsigned int sindex, AddressRange *rar)
1386 1373
{
1374
    string error_msg;
1375

  
1387 1376
    /* ----------------- Allocate the new AR from sindex -------------------- */
1388 1377

  
1389 1378
    for (unsigned int j=sindex; j< (sindex+rsize) ; j++)
......
1394 1383
        }
1395 1384
    }
1396 1385

  
1386
    if (allocate_addr(sindex, rsize, error_msg) != 0)
1387
    {
1388
        return -1;
1389
    }
1390

  
1397 1391
    for (unsigned int j=sindex; j< (sindex+rsize); j++)
1398 1392
    {
1399
        allocate_addr(PoolObjectSQL::NET, vid, j);
1393
        set_allocated_addr(PoolObjectSQL::NET, vid, j);
1400 1394
    }
1401 1395

  
1402 1396
    /* ------------------------- Initialize the new AR ---------------------- */
......
1426 1420
int AddressRange::reserve_addr_by_ip(int vid, unsigned int rsize,
1427 1421
    const string& ip_s, AddressRange *rar)
1428 1422
{
1429
    if (!(type & 0x00000002))//Not of type IP4 or IP4_6
1430
    {
1431
        return -1;
1432
    }
1423
    unsigned int sindex;
1433 1424

  
1434
    unsigned int ip_i;
1435

  
1436
    if (ip_to_i(ip_s, ip_i) == -1)
1437
    {
1438
        return -1;
1439
    }
1440

  
1441
    if (ip_i < ip)
1442
    {
1443
        return -1;
1444
    }
1445

  
1446
    unsigned int sindex = ip_i - ip;
1447

  
1448
    if (sindex >= size )
1425
    if (!is_valid_ip(sindex, ip_s, false))
1449 1426
    {
1450 1427
        return -1;
1451 1428
    }
......
1459 1436
int AddressRange::reserve_addr_by_mac(int vid, unsigned int rsize,
1460 1437
    const string& mac_s, AddressRange *rar)
1461 1438
{
1462
    unsigned int mac_i[2];
1463

  
1464
    if (mac_to_i(mac_s, mac_i) == -1)
1465
    {
1466
        return -1;
1467
    }
1468

  
1469
    if ((mac_i[1] != mac[1]) || (mac_i[0] < mac[0]))
1470
    {
1471
        return -1;
1472
    }
1473

  
1474
    unsigned int sindex = mac_i[0] - mac[0];
1439
    unsigned int sindex;
1475 1440

  
1476
    if (sindex >= size)
1441
    if (!is_valid_mac(sindex, mac_s, false))
1477 1442
    {
1478 1443
        return -1;
1479 1444
    }
src/vnm/AddressRangeInternal.cc
1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems                */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

  
17
#include "AddressRangeInternal.h"
18

  
19
int AddressRangeInternal::get_single_addr(unsigned int& index, std::string& msg)
20
{
21
    unsigned int ar_size = get_size();
22

  
23
    for ( unsigned int i=0; i<ar_size; i++, next = (next+1)%ar_size )
24
    {
25
        if ( allocated.count(next) == 0 )
26
        {
27
            index = next;
28
            return 0;
29
        }
30
    }
31

  
32
    msg = "Not free addresses available";
33
    return -1;
34
}
35

  
36
int AddressRangeInternal::get_range_addr(unsigned int& index,
37
        unsigned int rsize, std::string& msg)
38
{
39
    unsigned int ar_size = get_size();
40
    bool valid;
41

  
42
    for (unsigned int i=0; i< ar_size; i++)
43
    {
44
        if ( allocated.count(i) != 0 )
45
        {
46
            continue;
47
        }
48

  
49
        valid = true;
50

  
51
        for (unsigned int j=0; j<rsize; j++, i++)
52
        {
53
            if ( allocated.count(i) != 0 || i >= ar_size )
54
            {
55
                valid = false;
56
                break;
57
            }
58
        }
59

  
60
        if (valid == true)
61
        {
62
            index = i - rsize;
63
            return 0;
64
        }
65
    }
66

  
67
    msg = "There isn't a continuous range big enough";
68
    return -1;
69
}
70

  
src/vnm/AddressRangePool.cc
16 16

  
17 17
#include "AddressRangePool.h"
18 18
#include "AddressRange.h"
19
#include "AddressRangeInternal.h"
20
#include "AddressRangeIPAM.h"
19 21

  
20 22
using namespace std;
21 23

  
......
37 39

  
38 40
int AddressRangePool::from_vattr(VectorAttribute* va, string& error_msg)
39 41
{
40
    AddressRange * ar = new AddressRange(next_ar);
42
    AddressRange * ar = allocate_ar(va->vector_value("IPAM_MAD"));
41 43

  
42 44
    if (ar->from_vattr(va, error_msg) != 0)
43 45
    {
46
        next_ar = next_ar - 1;
44 47
        delete ar;
48

  
45 49
        return -1;
46 50
    }
47 51

  
48
    ar_pool.insert(make_pair(next_ar++, ar));
52
    ar_pool.insert(make_pair(ar->ar_id(), ar));
49 53

  
50 54
    ar_template.set(va);
51 55

  
......
55 59
/* -------------------------------------------------------------------------- */
56 60
/* -------------------------------------------------------------------------- */
57 61

  
58
AddressRange * AddressRangePool::allocate_ar()
62
AddressRange * AddressRangePool::allocate_ar(const string& ipam_mad)
63
{
64
    return allocate_ar(ipam_mad, next_ar++);
65
}
66

  
67
/* -------------------------------------------------------------------------- */
68

  
69
AddressRange * AddressRangePool::allocate_ar(const string& ipam_mad,
70
        unsigned int na)
59 71
{
60
    return new AddressRange(next_ar++);
72
    if ( ipam_mad.empty() || ipam_mad == "internal" )
73
    {
74
        return new AddressRangeInternal(na);
75
    }
76
    else
77
    {
78
        return new AddressRangeIPAM(na);
79
    }
61 80
}
62 81

  
63 82
/* -------------------------------------------------------------------------- */
......
134 153

  
135 154
    for (int i = 0; i < num_ar; i++)
136 155
    {
137
        AddressRange * ar = new AddressRange(0);
156
        AddressRange * ar = allocate_ar((var[i])->vector_value("IPAM_MAD"), 0);
138 157

  
139
        if (ar->from_vattr_db(var[i])!= 0)
158
        if (ar->from_vattr_db(var[i]) != 0)
140 159
        {
141 160
            return -1;
142 161
        }
src/vnm/SConstruct
25 25
    'VirtualNetwork.cc',
26 26
    'VirtualNetworkPool.cc',
27 27
    'AddressRange.cc',
28
    'AddressRangeInternal.cc',
28 29
    'AddressRangePool.cc',
29 30
    'VirtualNetworkTemplate.cc'
30 31
]
src/vnm/VirtualNetworkPool.cc
498 498
        return 0;
499 499
    }
500 500

  
501
    AddressRange *ar = rvn->allocate_ar();
501
    AddressRange *ar = rvn->allocate_ar("internal");
502 502

  
503 503
    update(rvn);
504 504

  

Also available in: Unified diff