1*387f9dfdSAndroid Build Coastguard Worker /*
2*387f9dfdSAndroid Build Coastguard Worker * Copyright (c) 2016 PLUMgrid, Inc.
3*387f9dfdSAndroid Build Coastguard Worker *
4*387f9dfdSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*387f9dfdSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*387f9dfdSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*387f9dfdSAndroid Build Coastguard Worker *
8*387f9dfdSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*387f9dfdSAndroid Build Coastguard Worker *
10*387f9dfdSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*387f9dfdSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*387f9dfdSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*387f9dfdSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*387f9dfdSAndroid Build Coastguard Worker * limitations under the License.
15*387f9dfdSAndroid Build Coastguard Worker */
16*387f9dfdSAndroid Build Coastguard Worker
17*387f9dfdSAndroid Build Coastguard Worker #include <unistd.h>
18*387f9dfdSAndroid Build Coastguard Worker #include <iostream>
19*387f9dfdSAndroid Build Coastguard Worker
20*387f9dfdSAndroid Build Coastguard Worker #include "common.h"
21*387f9dfdSAndroid Build Coastguard Worker #include "linux/bpf.h"
22*387f9dfdSAndroid Build Coastguard Worker #include "table_storage.h"
23*387f9dfdSAndroid Build Coastguard Worker #include "table_storage_impl.h"
24*387f9dfdSAndroid Build Coastguard Worker
25*387f9dfdSAndroid Build Coastguard Worker namespace ebpf {
26*387f9dfdSAndroid Build Coastguard Worker
27*387f9dfdSAndroid Build Coastguard Worker using std::string;
28*387f9dfdSAndroid Build Coastguard Worker using std::unique_ptr;
29*387f9dfdSAndroid Build Coastguard Worker
30*387f9dfdSAndroid Build Coastguard Worker /// A process-wide singleton of shared tables
31*387f9dfdSAndroid Build Coastguard Worker class SharedTableStorage : public TableStorageImpl {
32*387f9dfdSAndroid Build Coastguard Worker public:
33*387f9dfdSAndroid Build Coastguard Worker class iterator : public TableStorageIteratorImpl {
34*387f9dfdSAndroid Build Coastguard Worker std::map<string, TableDesc>::iterator it_;
35*387f9dfdSAndroid Build Coastguard Worker
36*387f9dfdSAndroid Build Coastguard Worker public:
iterator(const std::map<string,TableDesc>::iterator & it)37*387f9dfdSAndroid Build Coastguard Worker explicit iterator(const std::map<string, TableDesc>::iterator &it) : it_(it) {}
~iterator()38*387f9dfdSAndroid Build Coastguard Worker virtual ~iterator() {}
clone() const39*387f9dfdSAndroid Build Coastguard Worker virtual unique_ptr<self_type> clone() const override { return make_unique<iterator>(it_); }
operator ++()40*387f9dfdSAndroid Build Coastguard Worker virtual self_type &operator++() override {
41*387f9dfdSAndroid Build Coastguard Worker ++it_;
42*387f9dfdSAndroid Build Coastguard Worker return *this;
43*387f9dfdSAndroid Build Coastguard Worker }
operator *() const44*387f9dfdSAndroid Build Coastguard Worker virtual value_type &operator*() const override { return *it_; }
operator ->() const45*387f9dfdSAndroid Build Coastguard Worker virtual pointer operator->() const override { return &*it_; }
46*387f9dfdSAndroid Build Coastguard Worker };
~SharedTableStorage()47*387f9dfdSAndroid Build Coastguard Worker virtual ~SharedTableStorage() {}
48*387f9dfdSAndroid Build Coastguard Worker virtual bool Find(const string &name, TableStorage::iterator &result) const override;
49*387f9dfdSAndroid Build Coastguard Worker virtual bool Insert(const string &name, TableDesc &&desc) override;
50*387f9dfdSAndroid Build Coastguard Worker virtual bool Delete(const string &name) override;
51*387f9dfdSAndroid Build Coastguard Worker virtual unique_ptr<TableStorageIteratorImpl> begin() override;
52*387f9dfdSAndroid Build Coastguard Worker virtual unique_ptr<TableStorageIteratorImpl> end() override;
53*387f9dfdSAndroid Build Coastguard Worker virtual unique_ptr<TableStorageIteratorImpl> lower_bound(const string &k) override;
54*387f9dfdSAndroid Build Coastguard Worker virtual unique_ptr<TableStorageIteratorImpl> upper_bound(const string &k) override;
55*387f9dfdSAndroid Build Coastguard Worker virtual unique_ptr<TableStorageIteratorImpl> erase(const TableStorageIteratorImpl &it) override;
56*387f9dfdSAndroid Build Coastguard Worker
57*387f9dfdSAndroid Build Coastguard Worker private:
58*387f9dfdSAndroid Build Coastguard Worker static std::map<string, TableDesc> tables_;
59*387f9dfdSAndroid Build Coastguard Worker };
60*387f9dfdSAndroid Build Coastguard Worker
Find(const string & name,TableStorage::iterator & result) const61*387f9dfdSAndroid Build Coastguard Worker bool SharedTableStorage::Find(const string &name, TableStorage::iterator &result) const {
62*387f9dfdSAndroid Build Coastguard Worker auto it = tables_.find(name);
63*387f9dfdSAndroid Build Coastguard Worker if (it == tables_.end())
64*387f9dfdSAndroid Build Coastguard Worker return false;
65*387f9dfdSAndroid Build Coastguard Worker result = TableStorage::iterator(make_unique<iterator>(it));
66*387f9dfdSAndroid Build Coastguard Worker return true;
67*387f9dfdSAndroid Build Coastguard Worker }
68*387f9dfdSAndroid Build Coastguard Worker
Insert(const string & name,TableDesc && desc)69*387f9dfdSAndroid Build Coastguard Worker bool SharedTableStorage::Insert(const string &name, TableDesc &&desc) {
70*387f9dfdSAndroid Build Coastguard Worker auto it = tables_.find(name);
71*387f9dfdSAndroid Build Coastguard Worker if (it != tables_.end())
72*387f9dfdSAndroid Build Coastguard Worker return false;
73*387f9dfdSAndroid Build Coastguard Worker tables_[name] = std::move(desc);
74*387f9dfdSAndroid Build Coastguard Worker return true;
75*387f9dfdSAndroid Build Coastguard Worker }
76*387f9dfdSAndroid Build Coastguard Worker
Delete(const string & name)77*387f9dfdSAndroid Build Coastguard Worker bool SharedTableStorage::Delete(const string &name) {
78*387f9dfdSAndroid Build Coastguard Worker auto it = tables_.find(name);
79*387f9dfdSAndroid Build Coastguard Worker if (it == tables_.end())
80*387f9dfdSAndroid Build Coastguard Worker return false;
81*387f9dfdSAndroid Build Coastguard Worker tables_.erase(it);
82*387f9dfdSAndroid Build Coastguard Worker return true;
83*387f9dfdSAndroid Build Coastguard Worker }
84*387f9dfdSAndroid Build Coastguard Worker
begin()85*387f9dfdSAndroid Build Coastguard Worker unique_ptr<TableStorageIteratorImpl> SharedTableStorage::begin() {
86*387f9dfdSAndroid Build Coastguard Worker return make_unique<iterator>(tables_.begin());
87*387f9dfdSAndroid Build Coastguard Worker }
end()88*387f9dfdSAndroid Build Coastguard Worker unique_ptr<TableStorageIteratorImpl> SharedTableStorage::end() {
89*387f9dfdSAndroid Build Coastguard Worker return make_unique<iterator>(tables_.end());
90*387f9dfdSAndroid Build Coastguard Worker }
91*387f9dfdSAndroid Build Coastguard Worker
lower_bound(const string & k)92*387f9dfdSAndroid Build Coastguard Worker unique_ptr<TableStorageIteratorImpl> SharedTableStorage::lower_bound(const string &k) {
93*387f9dfdSAndroid Build Coastguard Worker return make_unique<iterator>(tables_.lower_bound(k));
94*387f9dfdSAndroid Build Coastguard Worker }
upper_bound(const string & k)95*387f9dfdSAndroid Build Coastguard Worker unique_ptr<TableStorageIteratorImpl> SharedTableStorage::upper_bound(const string &k) {
96*387f9dfdSAndroid Build Coastguard Worker return make_unique<iterator>(tables_.upper_bound(k));
97*387f9dfdSAndroid Build Coastguard Worker }
erase(const TableStorageIteratorImpl & it)98*387f9dfdSAndroid Build Coastguard Worker unique_ptr<TableStorageIteratorImpl> SharedTableStorage::erase(const TableStorageIteratorImpl &it) {
99*387f9dfdSAndroid Build Coastguard Worker auto i = tables_.find((*it).first);
100*387f9dfdSAndroid Build Coastguard Worker if (i == tables_.end())
101*387f9dfdSAndroid Build Coastguard Worker return unique_ptr<iterator>();
102*387f9dfdSAndroid Build Coastguard Worker return make_unique<iterator>(tables_.erase(i));
103*387f9dfdSAndroid Build Coastguard Worker }
104*387f9dfdSAndroid Build Coastguard Worker
105*387f9dfdSAndroid Build Coastguard Worker // All maps for this process are kept in global static storage.
106*387f9dfdSAndroid Build Coastguard Worker std::map<string, TableDesc> SharedTableStorage::tables_;
107*387f9dfdSAndroid Build Coastguard Worker
createSharedTableStorage()108*387f9dfdSAndroid Build Coastguard Worker unique_ptr<TableStorage> createSharedTableStorage() {
109*387f9dfdSAndroid Build Coastguard Worker auto t = make_unique<TableStorage>();
110*387f9dfdSAndroid Build Coastguard Worker t->Init(make_unique<SharedTableStorage>());
111*387f9dfdSAndroid Build Coastguard Worker t->AddMapTypesVisitor(createJsonMapTypesVisitor());
112*387f9dfdSAndroid Build Coastguard Worker return t;
113*387f9dfdSAndroid Build Coastguard Worker }
114*387f9dfdSAndroid Build Coastguard Worker }
115