Class: OsCtld::NetConfig

Inherits:
Object
  • Object
show all
Defined in:
lib/osctld/net_config.rb

Overview

Generate network configuration for a container and apply using netlink

NetConfig has to be created before switching to container user and attaching to the container. Call NetConfig.create while running as root and #setup while attached into a container.

Defined Under Namespace

Classes: Addr, NetIf, Route

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeNetConfig

Returns a new instance of NetConfig.



32
33
34
# File 'lib/osctld/net_config.rb', line 32

def initialize
  @netifs = []
end

Instance Attribute Details

#netifsObject (readonly)

Returns the value of attribute netifs.



17
18
19
# File 'lib/osctld/net_config.rb', line 17

def netifs
  @netifs
end

Class Method Details

.create(ct) ⇒ Object

Parameters:



20
21
22
23
24
# File 'lib/osctld/net_config.rb', line 20

def self.create(ct)
  cfg = new
  ct.netifs.each { |netif| cfg.add_netif(netif) }
  cfg
end

.import(data) ⇒ Object



26
27
28
29
30
# File 'lib/osctld/net_config.rb', line 26

def self.import(data)
  cfg = new
  cfg.import(data)
  cfg
end

Instance Method Details

#add_netif(netif) ⇒ Object

Parameters:



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/osctld/net_config.rb', line 37

def add_netif(netif)
  n = NetIf.new(netif.name, [], [])

  [4, 6].each do |ip_v|
    if netif.respond_to?(:ips)
      netif.ips(ip_v).each do |ip|
        n.ips << Addr.new(ip_v, ip.to_s, ip.prefix.to_i)
      end
    end

    case netif.type
    when :bridge
      if netif.has_gateway?(ip_v)
        n.routes << Route.new(ip_v, '0.0.0.0', 0, netif.gateway(ip_v))
      end

    when :routed
      begin
        via = netif.default_via(ip_v).to_s
        n.routes << Route.new(ip_v, via, ip_v == 4 ? 32 : 128, nil)
        n.routes << Route.new(ip_v, '0.0.0.0', 0, via)
      rescue RuntimeError
        # IPv6 is routed via link-local address on the host interface, which
        # is not known when the container is stopped.
        next if ip_v == 6
      end
    end
  end

  netifs << n
end

#exportObject



93
94
95
96
97
98
99
100
101
# File 'lib/osctld/net_config.rb', line 93

def export
  netifs.map do |netif|
    {
      name: netif.name,
      ips: netif.ips.map(&:to_h),
      routes: netif.routes.map(&:to_h)
    }
  end
end

#import(data) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/osctld/net_config.rb', line 103

def import(data)
  data.each do |netif_hash|
    netifs << NetIf.new(
      netif_hash[:name],
      netif_hash[:ips].map do |v|
        Addr.new(v[:version], v[:address], v[:prefix])
      end,
      netif_hash[:routes].map do |v|
        Route.new(v[:version], v[:address], v[:prefix], v[:via])
      end
    )
  end
end

#setupObject

Apply configuration using netlink



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/osctld/net_config.rb', line 70

def setup
  nl = Linux::Netlink::Route::Socket.new

  netifs.each do |netif|
    netif.ips.each do |ip|
      nl.addr.add(index: netif.name, local: ip.address, prefixlen: ip.prefix)
    rescue Errno::EEXIST
      next
    end

    netif.routes.each do |route|
      nl.route.add(
        oif: netif.name,
        dst: route.address,
        dst_len: route.prefix,
        gateway: route.via
      )
    rescue Errno::EEXIST
      next
    end
  end
end