Skip to content

Commit e4a81b2

Browse files
committed
router: a little more functionality
1 parent a4bd1fc commit e4a81b2

1 file changed

Lines changed: 62 additions & 19 deletions

File tree

api/net/router.hpp

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,27 +31,41 @@ namespace net {
3131
using Addr = typename IPV::addr;
3232
using Netmask = typename IPV::addr;
3333

34-
Addr dest_net()
35-
{ return dest_net_; }
34+
Addr net() const noexcept
35+
{ return net_; }
3636

37-
Netmask netmask()
37+
Netmask netmask() const noexcept
3838
{ return netmask_; }
3939

40-
Addr gateway()
40+
Addr gateway() const noexcept
4141
{ return gateway_; }
4242

43-
int cost()
43+
int cost() const noexcept
4444
{ return cost_; }
4545

46-
Stack_ptr interface()
46+
Stack_ptr interface() const noexcept
4747
{ return iface_; };
4848

49-
Route(Addr dest_net, Netmask mask, Addr gateway, Stack& iface, int cost)
50-
: dest_net_{dest_net}, netmask_{mask}, gateway_{gateway}, iface_{&iface}, cost_{cost}
49+
Stack_ptr match(typename IPV::addr dest) const noexcept
50+
{ return (dest & netmask_) == net_ ? iface_ : nullptr; }
51+
52+
bool operator<(const Route& b) const
53+
{ return cost() < b.cost(); }
54+
55+
bool operator==(const Route& b) const
56+
{
57+
return net_ == b.net() and
58+
netmask_ == b.netmask() and
59+
cost_ == b.cost() and
60+
iface_ == b.interface();
61+
}
62+
63+
Route(Addr net, Netmask mask, Addr gateway, Stack& iface, int cost)
64+
: net_{net}, netmask_{mask}, gateway_{gateway}, iface_{&iface}, cost_{cost}
5165
{}
5266

5367
private:
54-
Addr dest_net_;
68+
Addr net_;
5569
Netmask netmask_;
5670
Addr gateway_;
5771
Stack_ptr iface_;
@@ -82,33 +96,62 @@ namespace net {
8296
{ return Forward_delg(*this, forward); }
8397

8498

85-
/** Get the interface route for a certain IP **/
86-
virtual Stack_ptr get_interface(typename IPV::addr dest) {
99+
/** Get any interface route for a certain IP **/
100+
Route<IPV>* get_first_route(typename IPV::addr dest) {
87101

88102
for (auto&& route : routing_table_) {
89-
if ((dest & route.netmask()) == route.dest_net())
90-
return route.interface();
103+
Stack_ptr match = route.match(dest);
104+
if (match) return &route;
91105
}
92106

93107
return nullptr;
108+
};
94109

110+
/** Get any interface route for a certain IP **/
111+
Stack_ptr get_first_interface(typename IPV::addr dest) {
112+
auto route = get_first_route(dest);
113+
if (route) return route->interface();
114+
return nullptr;
95115
};
96116

117+
/** Check if there exists a route for a given IP **/
97118
bool route_check(typename IPV::addr dest){
98-
return get_interface(dest);
119+
return get_first_interface(dest) != nullptr;
99120
}
100121

101122

123+
/**
124+
* Get all routes for a certain IP
125+
* @todo : Optimize!
126+
**/
127+
Routing_table get_all_routes(typename IPV::addr dest) {
128+
129+
Routing_table t;
130+
std::copy_if(routing_table_.begin(),
131+
routing_table_.end(),
132+
std::back_inserter(t), [dest](const Route<IPV>& route) {
133+
return route.match(dest);
134+
});
135+
return t;
136+
}
137+
138+
/**
139+
* Get cheapest route for a certain IP
140+
* @todo : Optimize!
141+
**/
142+
Route<IPV>* get_cheapest_route(typename IPV::addr dest) {
143+
Routing_table all = get_all_routes(dest);
144+
std::sort(all.begin(), all.end());
145+
if (not all.empty()) return &all.front();
146+
return nullptr;
147+
};
148+
102149

103150
/** Construct a router over a set of interfaces **/
104-
Router(Interfaces& ifaces, Routing_table&& tbl = {})
151+
Router(Interfaces& ifaces, Routing_table tbl = {})
105152
: networks_{ifaces}, routing_table_{tbl}
106153
{ }
107154

108-
void set_routing_table(Routing_table&& tbl) {
109-
routing_table_ = std::forward(tbl);
110-
};
111-
112155
void set_routing_table(Routing_table tbl) {
113156
routing_table_ = tbl;
114157
};

0 commit comments

Comments
 (0)