]> git.openstreetmap.org Git - chef.git/blobdiff - cookbooks/networking/recipes/default.rb
Work around lack of "onlink" route flag for IPv6 routes
[chef.git] / cookbooks / networking / recipes / default.rb
index 068e0edf23496052bbb5085f1b323cf005c42d06..f56689d46d4929c49c6256b806ef97a293c4be44 100644 (file)
@@ -56,20 +56,34 @@ node[:networking][:interfaces].each do |name, interface|
     node.normal[:networking][:interfaces][name][:network] = IPAddr.new(interface[:address]).mask(prefix)
 
     if node[:networking][:netplan]
-      if interface[:interface] =~ /^(.*)\.(\d+)$/
-        deviceplan = netplan["network"]["vlans"][interface[:interface]] = {
-          "id" => Regexp.last_match(2).to_i,
-          "link" => Regexp.last_match(1),
-          "accept-ra" => false,
-          "addresses" => [],
-          "routes" => []
-        }
-      elsif interface[:bond]
-        deviceplan = netplan["network"]["bonds"][interface[:interface]] = {
-          "accept-ra" => false,
-          "addresses" => [],
-          "routes" => [],
-          "interfaces" => interface[:bond][:slaves].to_a,
+      deviceplan = if interface[:interface] =~ /^(.*)\.(\d+)$/
+                     netplan["network"]["vlans"][interface[:interface]] ||= {
+                       "id" => Regexp.last_match(2).to_i,
+                       "link" => Regexp.last_match(1),
+                       "accept-ra" => false,
+                       "addresses" => [],
+                       "routes" => []
+                     }
+                   elsif interface[:interface] =~ /^bond\d+$/
+                     netplan["network"]["bonds"][interface[:interface]] ||= {
+                       "accept-ra" => false,
+                       "addresses" => [],
+                       "routes" => []
+                     }
+                   else
+                     netplan["network"]["ethernets"][interface[:interface]] ||= {
+                       "accept-ra" => false,
+                       "addresses" => [],
+                       "routes" => []
+                     }
+                   end
+
+      deviceplan["addresses"].push("#{interface[:address]}/#{prefix}")
+
+      if interface[:bond]
+        deviceplan["interfaces"] = interface[:bond][:slaves].to_a
+
+        deviceplan["parameters"] = {
           "mode" => interface[:bond][:mode] || "active-backup",
           "primary" => interface[:bond][:slaves].first,
           "mii-monitor-interval" => interface[:bond][:miimon] || 100,
@@ -77,18 +91,10 @@ node[:networking][:interfaces].each do |name, interface|
           "up-delay" => interface[:bond][:updelay] || 200
         }
 
-        deviceplan["transmit-hash-policy"] = interface[:bond][:xmithashpolicy] if interface[:bond][:xmithashpolicy]
-        deviceplan["lacp-rate"] = interface[:bond][:lacprate] if interface[:bond][:lacprate]
-      else
-        deviceplan = netplan["network"]["ethernets"][interface[:interface]] = {
-          "accept-ra" => false,
-          "addresses" => [],
-          "routes" => []
-        }
+        deviceplan["parameters"]["transmit-hash-policy"] = interface[:bond][:xmithashpolicy] if interface[:bond][:xmithashpolicy]
+        deviceplan["parameters"]["lacp-rate"] = interface[:bond][:lacprate] if interface[:bond][:lacprate]
       end
 
-      deviceplan["addresses"].push("#{interface[:address]}/#{prefix}")
-
       if interface[:gateway]
         if interface[:family] == "inet"
           default_route = "0.0.0.0/0"
@@ -102,6 +108,21 @@ node[:networking][:interfaces].each do |name, interface|
           "metric" => interface[:metric],
           "on-link" => true
         )
+
+        # This ordering relies on systemd-networkd adding routes
+        # in reverse order and will need moving before the previous
+        # route once that is fixed:
+        #
+        # https://github.com/systemd/systemd/issues/5430
+        # https://github.com/systemd/systemd/pull/10938
+        if interface[:family] == "inet6" &&
+           !interface[:network].include?(interface[:gateway]) &&
+           !IPAddr.new("fe80::/64").include?(interface[:gateway])
+          deviceplan["routes"].push(
+            "to" => interface[:gateway],
+            "scope" => "link"
+          )
+        end
       end
     end
   else
@@ -123,7 +144,9 @@ if node[:networking][:netplan]
   end
 
   netplan["network"]["vlans"].each_value do |vlan|
-    netplan["network"]["ethernets"][vlan["link"]] ||= { "accept-ra" => false }
+    unless vlan["link"] =~ /^bond\d+$/
+      netplan["network"]["ethernets"][vlan["link"]] ||= { "accept-ra" => false }
+    end
   end
 
   file "/etc/netplan/99-chef.yaml" do