Skip to content

Commit dd44698

Browse files
committed
inet: rudimentary support for virutal IPs
1 parent d31d97b commit dd44698

2 files changed

Lines changed: 77 additions & 10 deletions

File tree

api/net/inet.hpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define NET_INET_HPP
2020

2121
#include <chrono>
22+
#include <unordered_set>
2223

2324
#include <net/inet_common.hpp>
2425
#include <hw/mac_addr.hpp>
@@ -46,6 +47,8 @@ namespace net {
4647
template <typename IPv>
4748
using resolve_func = delegate<void(typename IPv::addr)>;
4849

50+
using Vip_list = std::unordered_set<typename IPV::addr>;
51+
4952

5053
///
5154
/// NETWORK CONFIGURATION
@@ -80,19 +83,37 @@ namespace net {
8083
/** Use DHCP to configure this interface */
8184
virtual void negotiate_dhcp(double timeout = 10.0, dhcp_timeout_func = nullptr) = 0;
8285

86+
/** Get a list of virtual IP4 addresses assigned to this interface */
87+
virtual const Vip_list virtual_ips() const = 0;
88+
89+
/** Check if an IP is a (possibly virtual) loopback address */
90+
virtual bool is_loopback(typename IPV::addr a) const = 0;
91+
92+
/** Add an IP address as a virtual loopback IP */
93+
virtual void add_vip(typename IPV::addr a) = 0;
94+
95+
/** Remove an IP address from the virtual loopback IP list */
96+
virtual void remove_vip(typename IPV::addr a) = 0;
97+
98+
/** Determine the appropriate source address for a destination. */
99+
virtual typename IPV::addr get_source_addr(typename IPV::addr dest) = 0;
100+
101+
/** Determine if an IP address is a valid source address for this stack */
102+
virtual bool is_valid_source(typename IPV::addr) = 0;
103+
83104

84105
///
85106
/// PROTOCOL OBJECTS
86107
///
87108

88109
/** Get the IP protocol object for this interface */
89-
virtual IPV& ip_obj() = 0;
110+
virtual IPV& ip_obj() = 0;
90111

91112
/** Get the TCP protocol object for this interface */
92-
virtual TCP& tcp() = 0;
113+
virtual TCP& tcp() = 0;
93114

94115
/** Get the UDP protocol object for this interface */
95-
virtual UDP& udp() = 0;
116+
virtual UDP& udp() = 0;
96117

97118

98119
///
@@ -108,13 +129,13 @@ namespace net {
108129
///
109130

110131
/** Get the network interface device */
111-
virtual hw::Nic& nic() = 0;
132+
virtual hw::Nic& nic() = 0;
112133

113134
/** Get interface name for this interface **/
114-
virtual std::string ifname() const = 0;
135+
virtual std::string ifname() const = 0;
115136

116137
/** Get linklayer address for this interface **/
117-
virtual MAC::Addr link_addr() = 0;
138+
virtual MAC::Addr link_addr() = 0;
118139

119140
/** Add cache entry to the link / IP address cache */
120141
virtual void cache_link_addr(typename IPV::addr, MAC::Addr) = 0;
@@ -123,7 +144,7 @@ namespace net {
123144
virtual void flush_link_cache() = 0;
124145

125146
/** Set the regular interval for link address cache flushing */
126-
virtual void set_link_cache_flush_interval(std::chrono::minutes);
147+
virtual void set_link_cache_flush_interval(std::chrono::minutes) = 0;
127148

128149

129150
///

api/net/inet4.hpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@
1818
#ifndef NET_INET4_HPP
1919
#define NET_INET4_HPP
2020

21+
#include <vector>
22+
#include <unordered_set>
23+
2124
#include "inet.hpp"
2225
#include "ip4/arp.hpp"
2326
#include "ip4/ip4.hpp"
2427
#include "ip4/udp.hpp"
2528
#include "ip4/icmpv4.hpp"
2629
#include "dns/client.hpp"
2730
#include "tcp/tcp.hpp"
28-
#include <vector>
2931
#include "super_stack.hpp"
3032

3133
namespace net {
@@ -35,6 +37,9 @@ namespace net {
3537
/** A complete IP4 network stack */
3638
class Inet4 : public Inet<IP4>{
3739
public:
40+
41+
using Vip4_list = std::unordered_set<IP4::addr>;
42+
3843
std::string ifname() const override
3944
{ return nic_.device_name(); }
4045

@@ -110,7 +115,6 @@ namespace net {
110115
return ip_packet;
111116
}
112117

113-
114118
IP_packet_factory ip_packet_factory() override
115119
{ return IP_packet_factory{this, &Inet4::create_ip_packet}; }
116120

@@ -231,10 +235,50 @@ namespace net {
231235
return stack<N>();
232236
}
233237

234-
private:
238+
/** Add virtual IP4 address as loopback */
239+
const Vip4_list virtual_ips() const noexcept override
240+
{ return vip4s_; }
241+
242+
/** Check if IP4 address is virtual loopback */
243+
bool is_loopback(IP4::addr a) const override
244+
{
245+
return a.is_loopback()
246+
or vip4s_.find(a) != vip4s_.end();
247+
}
248+
249+
/** Add IP4 address as virtual loopback */
250+
void add_vip(IP4::addr a) override
251+
{
252+
if (not is_loopback(a)) {
253+
INFO("Inet4", "Adding virtual IP address %s", a.to_string().c_str());
254+
vip4s_.emplace(a);
255+
}
256+
}
257+
258+
/** Add IP4 address as virtual loopback */
259+
void remove_vip(IP4::addr a) override
260+
{ vip4s_.erase(a); }
261+
262+
IP4::addr get_source_addr(IP4::addr dest) override
263+
{
264+
265+
if (dest.is_loopback())
266+
return {127,0,0,1};
267+
268+
if (is_loopback(dest))
269+
return dest;
270+
271+
return ip_addr();
272+
}
273+
274+
bool is_valid_source(IP4::addr src) override
275+
{ return is_loopback(src) or src == ip_addr(); }
276+
235277
/** Initialize with ANY_ADDR */
236278
Inet4(hw::Nic& nic);
237279

280+
private:
281+
238282
void process_sendq(size_t);
239283
// delegates registered to get signalled about free packets
240284
std::vector<transmit_avail_delg> tqa;
@@ -244,6 +288,8 @@ namespace net {
244288
IP4::addr gateway_;
245289
IP4::addr dns_server;
246290

291+
Vip4_list vip4s_ = {{127,0,0,1}};
292+
247293
// This is the actual stack
248294
hw::Nic& nic_;
249295
Arp arp_;

0 commit comments

Comments
 (0)