1  #ifndef _PROTO_ROUTE_TABLE
2 #define _PROTO_ROUTE_TABLE
3 
4 #include "protoAddress.h"
5 #include "protoTree.h"
6 
7 /**
8  * @class ProtoRouteTable
9  *
10  * @brief Class based on the ProtoTree Patricia tree to
11  * store routing table information. Uses the
12  * ProtoAddress class to store network routing
13  * addresses.
14  *
15  * It's a pretty dumbed-down routing
16  * table at the moment, but may be enhanced in
17  * the future.  Example use of the ProtoTree.
18  *
19  * Notes:
20  *
21  * 1) Only one entry per destination/prefixLen is currently allowed.
22  *   (Only one route per unique destination is maintained)
23  *   (We may support multiple routes per dest in the future)
24  *
25  * 2) (ifIndex == 0) and (metric < 0) are "wildcards"
26  */
27 class ProtoRouteTable
28 {
29     public:
30         ProtoRouteTable();
31         ~ProtoRouteTable();
32 
Init()33         void Init() {Destroy();}
34         void Destroy();
35 
IsEmpty()36         bool IsEmpty() {return (tree.IsEmpty() && !default_entry.IsValid());}
37 
38         // For "GetRoute()" to work there _must_ be
39         // an exact match (dst and prefixLen) route entry in the table.
40         bool GetRoute(const ProtoAddress&   dst,        // input
41                       unsigned int          prefixLen,  // input
42                       ProtoAddress&         gw,         // output
43                       unsigned int&         ifIndex,    // output
44                       int&                  metric);    // output
45 
46         bool SetRoute(const ProtoAddress&   dst,
47                       unsigned int          maskLen,
48                       const ProtoAddress&   gw,
49                       unsigned int          ifIndex = 0,
50                       int                   metric = -1);
51 
52         // Note gateway is optional here
53         bool DeleteRoute(const ProtoAddress&    dst,
54                          unsigned int           maskLen,
55                          const ProtoAddress*    gw = NULL,
56                          unsigned int           ifIndex = 0);
57 
58         // Find the "best" route to the given destination
59         // (Finds route entry with longest matching prefix (or default))
60         bool FindRoute(const ProtoAddress&  dstAddr,
61                        unsigned int         prefixLen,
62                        ProtoAddress&        gwAddr,
63                        unsigned int&        ifIndex,
64                        int&                 metric);
65 
66         class Entry : public ProtoTree::Item
67         {
68             friend class ProtoRouteTable;
69 
70             public:
IsValid()71                 bool IsValid() const
72                     {return destination.IsValid();}
IsGatewayRoute()73                 bool IsGatewayRoute() const
74                     {return gateway.IsValid();}
IsDirectRoute()75                 bool IsDirectRoute() const
76                     {return (!gateway.IsValid() && iface_index > 0);}
SetGateway(const ProtoAddress & gwAddr)77                 void SetGateway(const ProtoAddress& gwAddr)
78                     {gateway = gwAddr;}
ClearGateway()79                 void ClearGateway()
80                     {gateway.Invalidate();}
SetInterface(unsigned int ifaceIndex)81                 void SetInterface(unsigned int ifaceIndex)
82                     {iface_index = ifaceIndex;}
ClearInterface()83                 void ClearInterface()
84                     {iface_index = 0;}
SetMetric(int value)85                 void SetMetric(int value)
86                     {metric = value;}
87 
GetDestination()88                 const ProtoAddress& GetDestination() const {return destination;}
GetPrefixSize()89                 unsigned int GetPrefixSize() const {return prefix_size;}  // in bits
GetGateway()90                 const ProtoAddress& GetGateway() const {return gateway;}
GetInterfaceIndex()91                 unsigned int GetInterfaceIndex() const {return iface_index;}
GetMetric()92                 int GetMetric() const {return metric;}
93 
Clear()94                 void Clear()
95                 {
96                     destination.Invalidate();
97                     prefix_size = 0;
98                     gateway.Invalidate();
99                     iface_index = 0;
100                     metric = -1;
101                 }
102 
103                 // Required ProtoTree::Item overrides
GetKey()104                 const char* GetKey() const {return destination.GetRawHostAddress();}
GetKeysize()105                 unsigned int GetKeysize() const {return prefix_size;}
106 
107             private:
108                 Entry();
109                 Entry(const ProtoAddress& dstAddr, unsigned int prefixSize);
110                 ~Entry();
111 
112                 void Init(const ProtoAddress& dstAddr, unsigned int prefixSize);
113 
114                 ProtoAddress        destination;
115                 unsigned int        prefix_size;  // in bits
116                 ProtoAddress        gateway;
117                 unsigned int        iface_index;
118                 int                 metric;
119         };  // end class ProtoRouteTable::Entry
120 
121         class Iterator
122         {
123             public:
124                 Iterator(ProtoRouteTable& table);
Reset()125                 void Reset()
126                 {
127                     iterator.Reset();
128                     default_pending = true;
129                 }
130                 Entry* GetNextEntry();
131 
132             private:
133                 const ProtoRouteTable&  table;
134                 ProtoTree::Iterator     iterator;
135                 bool                    default_pending;
136         };  // end class ProtoRouteTable::Iterator
137         friend class ProtoRouteTable::Iterator;
138 
139         ProtoRouteTable::Entry* CreateEntry(const ProtoAddress& dstAddr,
140                                             unsigned int          prefixLen);
141 
142         // Get entry exactly matching dstAddr/prefixLen
143         ProtoRouteTable::Entry* GetEntry(const ProtoAddress& dstAddr,
144                                          unsigned int          prefixLen) const;
145 
146         // Find best matching route entry
147         ProtoRouteTable::Entry* FindRouteEntry(const ProtoAddress& dstAddr,
148                                                unsigned int          prefixLen) const;
149 
GetDefaultEntry()150         ProtoRouteTable::Entry* GetDefaultEntry() const
151             {return (default_entry.IsValid() ? (Entry*)&default_entry : NULL);}
152 
153         void DeleteEntry(ProtoRouteTable::Entry* entry);
154 
155     private:
156         ProtoTree  tree;
157         Entry      default_entry;
158 };  // end class ProtoRouteTable
159 
160 #endif // _PROTO_ROUTE_TABLE
161