1 /*
2 * Copyright (c) 2016 PLUMgrid, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain 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 <unistd.h>
18 #include <iostream>
19
20 #include "common.h"
21 #include "compat/linux/bpf.h"
22 #include "table_storage.h"
23 #include "table_storage_impl.h"
24
25 namespace ebpf {
26
27 using std::string;
28 using std::unique_ptr;
29
30 /// A process-wide singleton of shared tables
31 class SharedTableStorage : public TableStorageImpl {
32 public:
33 class iterator : public TableStorageIteratorImpl {
34 std::map<string, TableDesc>::iterator it_;
35
36 public:
iterator(const std::map<string,TableDesc>::iterator & it)37 explicit iterator(const std::map<string, TableDesc>::iterator &it) : it_(it) {}
~iterator()38 virtual ~iterator() {}
clone() const39 virtual unique_ptr<self_type> clone() const override { return make_unique<iterator>(it_); }
operator ++()40 virtual self_type &operator++() override {
41 ++it_;
42 return *this;
43 }
operator *() const44 virtual value_type &operator*() const override { return *it_; }
operator ->() const45 virtual pointer operator->() const override { return &*it_; }
46 };
~SharedTableStorage()47 virtual ~SharedTableStorage() {}
48 virtual bool Find(const string &name, TableStorage::iterator &result) const override;
49 virtual bool Insert(const string &name, TableDesc &&desc) override;
50 virtual bool Delete(const string &name) override;
51 virtual unique_ptr<TableStorageIteratorImpl> begin() override;
52 virtual unique_ptr<TableStorageIteratorImpl> end() override;
53 virtual unique_ptr<TableStorageIteratorImpl> lower_bound(const string &k) override;
54 virtual unique_ptr<TableStorageIteratorImpl> upper_bound(const string &k) override;
55 virtual unique_ptr<TableStorageIteratorImpl> erase(const TableStorageIteratorImpl &it) override;
56
57 private:
58 static std::map<string, TableDesc> tables_;
59 };
60
Find(const string & name,TableStorage::iterator & result) const61 bool SharedTableStorage::Find(const string &name, TableStorage::iterator &result) const {
62 auto it = tables_.find(name);
63 if (it == tables_.end())
64 return false;
65 result = TableStorage::iterator(make_unique<iterator>(it));
66 return true;
67 }
68
Insert(const string & name,TableDesc && desc)69 bool SharedTableStorage::Insert(const string &name, TableDesc &&desc) {
70 auto it = tables_.find(name);
71 if (it != tables_.end())
72 return false;
73 tables_[name] = std::move(desc);
74 return true;
75 }
76
Delete(const string & name)77 bool SharedTableStorage::Delete(const string &name) {
78 auto it = tables_.find(name);
79 if (it == tables_.end())
80 return false;
81 tables_.erase(it);
82 return true;
83 }
84
begin()85 unique_ptr<TableStorageIteratorImpl> SharedTableStorage::begin() {
86 return make_unique<iterator>(tables_.begin());
87 }
end()88 unique_ptr<TableStorageIteratorImpl> SharedTableStorage::end() {
89 return make_unique<iterator>(tables_.end());
90 }
91
lower_bound(const string & k)92 unique_ptr<TableStorageIteratorImpl> SharedTableStorage::lower_bound(const string &k) {
93 return make_unique<iterator>(tables_.lower_bound(k));
94 }
upper_bound(const string & k)95 unique_ptr<TableStorageIteratorImpl> SharedTableStorage::upper_bound(const string &k) {
96 return make_unique<iterator>(tables_.upper_bound(k));
97 }
erase(const TableStorageIteratorImpl & it)98 unique_ptr<TableStorageIteratorImpl> SharedTableStorage::erase(const TableStorageIteratorImpl &it) {
99 auto i = tables_.find((*it).first);
100 if (i == tables_.end())
101 return unique_ptr<iterator>();
102 return make_unique<iterator>(tables_.erase(i));
103 }
104
105 // All maps for this process are kept in global static storage.
106 std::map<string, TableDesc> SharedTableStorage::tables_;
107
createSharedTableStorage()108 unique_ptr<TableStorage> createSharedTableStorage() {
109 auto t = make_unique<TableStorage>();
110 t->Init(make_unique<SharedTableStorage>());
111 t->AddMapTypesVisitor(createJsonMapTypesVisitor());
112 return t;
113 }
114 }
115