1
#pragma once
2

            
3
#include <cstdint>
4
#include <memory>
5
#include <vector>
6

            
7
#include "envoy/config/core/v3/socket_option.pb.h"
8
#include "envoy/network/address.h"
9
#include "envoy/network/socket.h"
10

            
11
#include "source/common/common/logger.h"
12

            
13
#include "absl/types/optional.h"
14
#include "cilium/filter_state_cilium_destination.h"
15
#include "cilium/filter_state_cilium_policy.h"
16

            
17
namespace Envoy {
18
namespace Cilium {
19

            
20
// Socket Option that restores the local address of the socket with the relevant
21
// source address which is either the original source address or a configured
22
// source address (used for Ingress - N/S load balancing).
23
// In addition, its hashKey implementation is also responsible to introduce Envoy
24
// to separate upstream connection pools per source address or source security ID.
25
class SourceAddressSocketOption : public Network::Socket::Option,
26
                                  public Logger::Loggable<Logger::Id::filter> {
27
public:
28
  SourceAddressSocketOption(
29
      uint32_t source_identity, int linger_time = -1,
30
      Network::Address::InstanceConstSharedPtr original_source_address = nullptr,
31
      Network::Address::InstanceConstSharedPtr ipv4_source_address = nullptr,
32
      Network::Address::InstanceConstSharedPtr ipv6_source_address = nullptr,
33
      std::shared_ptr<CiliumDestinationFilterState> dest_fs = nullptr,
34
      std::shared_ptr<CiliumPolicyFilterState> policy_fs = nullptr);
35

            
36
  absl::optional<Network::Socket::Option::Details>
37
  getOptionDetails(const Network::Socket&,
38
                   envoy::config::core::v3::SocketOption::SocketState) const override {
39
    return absl::nullopt;
40
  }
41

            
42
  bool setOption(Network::Socket& socket,
43
                 envoy::config::core::v3::SocketOption::SocketState state) const override;
44

            
45
  void hashKey(std::vector<uint8_t>& key) const override;
46

            
47
  bool isSupported() const override { return true; }
48

            
49
  uint32_t source_identity_;
50
  int linger_time_;
51

            
52
  Network::Address::InstanceConstSharedPtr original_source_address_;
53
  // Version specific source addresses are only used if original source address is not used.
54
  // Selection is made based on the socket domain, which is selected based on the destination
55
  // address. This makes sure we don't try to bind IPv4 or IPv6 source address to a socket
56
  // connecting to IPv6 or IPv4 address, respectively.
57
  Network::Address::InstanceConstSharedPtr ipv4_source_address_;
58
  Network::Address::InstanceConstSharedPtr ipv6_source_address_;
59
  std::shared_ptr<CiliumDestinationFilterState> dest_fs_;
60
  std::shared_ptr<CiliumPolicyFilterState> policy_fs_;
61
};
62

            
63
} // namespace Cilium
64
} // namespace Envoy