@@ -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