blob: 3fc3e99263ad1df058ff1464635aa249369bfd97 [file] [log] [blame]
David K. Bainbridgedf9df632016-07-07 18:47:46 -07001// Copyright 2016 Open Networking Laboratory
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070014package main
15
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070016import (
17 "math"
18 "net"
19 "strconv"
20 "strings"
21)
22
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070023type Storage interface {
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070024 Init(networkIn string, skip int) error
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070025 Get(mac string) (string, error)
26 GetAll() map[string]string
27 Put(mac, ip string) error
28 Remove(mac string) (string, error)
29 Dequeue() (string, error)
30 Enqueue(ip string) error
31}
32
33type MemoryStorage struct {
34 allocated map[string]IPv4
35 available []IPv4
36 readIdx, writeIdx, size uint
37}
38
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070039func (s *MemoryStorage) Init(networkIn string, skip int) error {
40 _, network, err := net.ParseCIDR(networkIn)
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070041 if err != nil {
42 return err
43 }
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070044 start, _, err := net.ParseCIDR(network.String())
45 if err != nil {
46 return err
47 }
48
49 parts := strings.Split(network.String(), "/")
50 ip, err := ParseIP(start.String())
51 if err != nil {
52 return err
53 }
54 bits, err := strconv.Atoi(parts[1])
55 if err != nil {
56 return err
57 }
58 hostCount := int(math.Pow(2, float64(32-bits))) - skip
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070059 s.readIdx = 0
60 s.writeIdx = 0
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070061 s.size = uint(hostCount)
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070062 s.allocated = make(map[string]IPv4)
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070063 s.available = make([]IPv4, hostCount)
64 for i := 0; i < skip; i += 1 {
65 ip, err = ip.Next()
66 if err != nil {
67 return err
68 }
69 }
70 for i := 0; i < hostCount; i += 1 {
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070071 s.available[i] = ip
72 ip, err = ip.Next()
73 if err != nil {
74 return err
75 }
76 }
77 return nil
78}
79
80func (s *MemoryStorage) Get(mac string) (string, error) {
81 ip, ok := s.allocated[mac]
82 if !ok {
83 return "", nil
84 }
85 return ip.String(), nil
86}
87
88func (s *MemoryStorage) GetAll() map[string]string {
89 all := make(map[string]string)
90 for k, v := range s.allocated {
91 all[k] = v.String()
92 }
93 return all
94}
95
96func (s *MemoryStorage) Put(mac, ip string) error {
97 data, err := ParseIP(ip)
98 if err != nil {
99 return err
100 }
101 s.allocated[mac] = data
102 return nil
103}
104
105func (s *MemoryStorage) Remove(mac string) (string, error) {
106 ip, ok := s.allocated[mac]
107 if !ok {
108 return "", nil
109 }
110 delete(s.allocated, mac)
111 return ip.String(), nil
112}
113
114func (s *MemoryStorage) Dequeue() (string, error) {
115 ip := s.available[s.readIdx]
116 s.readIdx = (s.readIdx + 1) % s.size
117 return ip.String(), nil
118}
119
120func (s *MemoryStorage) Enqueue(ip string) error {
121 data, err := ParseIP(ip)
122 if err != nil {
123 return err
124 }
125 s.available[s.writeIdx] = data
126 s.writeIdx = (s.writeIdx + 1) % s.size
127 return nil
128}