From e74c568b07b50b97873fb4ee1d776dedefbd54d6 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 1 Oct 2021 23:05:04 +0200 Subject: New upstream version 1.32.12 --- src/nm-initrd-generator/meson.build | 47 + src/nm-initrd-generator/nm-initrd-generator.c | 236 ++ src/nm-initrd-generator/nm-initrd-generator.h | 46 + src/nm-initrd-generator/nmi-cmdline-reader.c | 1416 +++++++++++ src/nm-initrd-generator/nmi-dt-reader.c | 372 +++ src/nm-initrd-generator/nmi-ibft-reader.c | 465 ++++ src/nm-initrd-generator/tests/meson.build | 43 + .../tests/sysfs-bad-dns1/class/net/eth0/address | 1 + .../sysfs-bad-dns1/firmware/ibft/ethernet0/gateway | 1 + .../sysfs-bad-dns1/firmware/ibft/ethernet0/index | 1 + .../sysfs-bad-dns1/firmware/ibft/ethernet0/ip-addr | 1 + .../sysfs-bad-dns1/firmware/ibft/ethernet0/mac | 1 + .../sysfs-bad-dns1/firmware/ibft/ethernet0/origin | 1 + .../firmware/ibft/ethernet0/prefix-len | 1 + .../firmware/ibft/ethernet0/primary-dns | 1 + .../firmware/ibft/ethernet0/secondary-dns | 1 + .../firmware/ibft/ethernet0/subnet-mask | 1 + .../sysfs-bad-dns1/firmware/ibft/ethernet0/vlan | 1 + .../firmware/ibft/initiator/initiator-name | 1 + .../sysfs-bad-dns1/firmware/ibft/target0/index | 1 + .../sysfs-bad-dns1/firmware/ibft/target0/ip-addr | 1 + .../tests/sysfs-bad-dns1/firmware/ibft/target0/lun | 1 + .../sysfs-bad-dns1/firmware/ibft/target0/port | 1 + .../firmware/ibft/target0/target-name | 1 + .../tests/sysfs-bad-dns2/class/net/eth0/address | 1 + .../sysfs-bad-dns2/firmware/ibft/ethernet0/gateway | 1 + .../sysfs-bad-dns2/firmware/ibft/ethernet0/index | 1 + .../sysfs-bad-dns2/firmware/ibft/ethernet0/ip-addr | 1 + .../sysfs-bad-dns2/firmware/ibft/ethernet0/mac | 1 + .../sysfs-bad-dns2/firmware/ibft/ethernet0/origin | 1 + .../firmware/ibft/ethernet0/prefix-len | 1 + .../firmware/ibft/ethernet0/primary-dns | 1 + .../firmware/ibft/ethernet0/secondary-dns | 1 + .../firmware/ibft/ethernet0/subnet-mask | 1 + .../sysfs-bad-dns2/firmware/ibft/ethernet0/vlan | 1 + .../firmware/ibft/initiator/initiator-name | 1 + .../sysfs-bad-dns2/firmware/ibft/target0/index | 1 + .../sysfs-bad-dns2/firmware/ibft/target0/ip-addr | 1 + .../tests/sysfs-bad-dns2/firmware/ibft/target0/lun | 1 + .../sysfs-bad-dns2/firmware/ibft/target0/port | 1 + .../firmware/ibft/target0/target-name | 1 + .../tests/sysfs-bad-gateway/class/net/eth0/address | 1 + .../firmware/ibft/ethernet0/gateway | 1 + .../firmware/ibft/ethernet0/index | 1 + .../firmware/ibft/ethernet0/ip-addr | 1 + .../sysfs-bad-gateway/firmware/ibft/ethernet0/mac | 1 + .../firmware/ibft/ethernet0/origin | 1 + .../firmware/ibft/ethernet0/prefix-len | 1 + .../firmware/ibft/ethernet0/primary-dns | 1 + .../firmware/ibft/ethernet0/secondary-dns | 1 + .../firmware/ibft/ethernet0/subnet-mask | 1 + .../sysfs-bad-gateway/firmware/ibft/ethernet0/vlan | 1 + .../firmware/ibft/initiator/initiator-name | 1 + .../sysfs-bad-gateway/firmware/ibft/target0/index | 1 + .../firmware/ibft/target0/ip-addr | 1 + .../sysfs-bad-gateway/firmware/ibft/target0/lun | 1 + .../sysfs-bad-gateway/firmware/ibft/target0/port | 1 + .../firmware/ibft/target0/target-name | 1 + .../tests/sysfs-bad-ipaddr/class/net/eth0/address | 1 + .../firmware/ibft/ethernet0/gateway | 1 + .../sysfs-bad-ipaddr/firmware/ibft/ethernet0/index | 1 + .../firmware/ibft/ethernet0/ip-addr | 1 + .../sysfs-bad-ipaddr/firmware/ibft/ethernet0/mac | 1 + .../firmware/ibft/ethernet0/origin | 1 + .../firmware/ibft/ethernet0/prefix-len | 1 + .../firmware/ibft/ethernet0/primary-dns | 1 + .../firmware/ibft/ethernet0/secondary-dns | 1 + .../firmware/ibft/ethernet0/subnet-mask | 1 + .../sysfs-bad-ipaddr/firmware/ibft/ethernet0/vlan | 1 + .../firmware/ibft/initiator/initiator-name | 1 + .../sysfs-bad-ipaddr/firmware/ibft/target0/index | 1 + .../sysfs-bad-ipaddr/firmware/ibft/target0/ip-addr | 1 + .../sysfs-bad-ipaddr/firmware/ibft/target0/lun | 1 + .../sysfs-bad-ipaddr/firmware/ibft/target0/port | 1 + .../firmware/ibft/target0/target-name | 1 + .../tests/sysfs-dhcp/class/net/eth0/address | 1 + .../tests/sysfs-dhcp/class/net/eth1/address | 1 + .../sysfs-dhcp/firmware/ibft/ethernet0/gateway | 1 + .../tests/sysfs-dhcp/firmware/ibft/ethernet0/index | 1 + .../tests/sysfs-dhcp/firmware/ibft/ethernet0/mac | 1 + .../sysfs-dhcp/firmware/ibft/ethernet0/origin | 1 + .../sysfs-dhcp/firmware/ibft/ethernet0/primary-dns | 1 + .../firmware/ibft/ethernet0/secondary-dns | 1 + .../tests/sysfs-dhcp/firmware/ibft/ethernet0/vlan | 1 + .../sysfs-dhcp/firmware/ibft/ethernet1/gateway | 1 + .../tests/sysfs-dhcp/firmware/ibft/ethernet1/index | 1 + .../tests/sysfs-dhcp/firmware/ibft/ethernet1/mac | 1 + .../sysfs-dhcp/firmware/ibft/ethernet1/origin | 1 + .../sysfs-dhcp/firmware/ibft/ethernet1/primary-dns | 1 + .../firmware/ibft/ethernet1/secondary-dns | 1 + .../tests/sysfs-dhcp/firmware/ibft/ethernet1/vlan | 1 + .../firmware/ibft/initiator/initiator-name | 1 + .../tests/sysfs-dhcp/firmware/ibft/target0/index | 1 + .../tests/sysfs-dhcp/firmware/ibft/target0/ip-addr | 1 + .../tests/sysfs-dhcp/firmware/ibft/target0/lun | 1 + .../tests/sysfs-dhcp/firmware/ibft/target0/port | 1 + .../sysfs-dhcp/firmware/ibft/target0/target-name | 1 + .../tests/sysfs-dhcp/firmware/ibft/target1/index | 1 + .../tests/sysfs-dhcp/firmware/ibft/target1/ip-addr | 1 + .../tests/sysfs-dhcp/firmware/ibft/target1/lun | 1 + .../tests/sysfs-dhcp/firmware/ibft/target1/port | 1 + .../sysfs-dhcp/firmware/ibft/target1/target-name | 1 + .../firmware/devicetree/base/chosen/bootpath | Bin 0 -> 108 bytes .../firmware/devicetree/base/chosen/bootp-request | Bin 0 -> 273 bytes .../firmware/devicetree/base/chosen/bootp-response | Bin 0 -> 300 bytes .../firmware/devicetree/base/chosen/bootpath | Bin 0 -> 37 bytes .../firmware/devicetree/base/chosen/broadcast-ip | 1 + .../firmware/devicetree/base/chosen/client-ip | 2 + .../firmware/devicetree/base/chosen/client-name | Bin 0 -> 9 bytes .../firmware/devicetree/base/chosen/domain-name | Bin 0 -> 15 bytes .../firmware/devicetree/base/chosen/gateway-ip | 2 + .../sysfs-dt/firmware/devicetree/base/chosen/name | Bin 0 -> 7 bytes .../firmware/devicetree/base/chosen/netmask-ip | Bin 0 -> 4 bytes .../firmware/devicetree/base/chosen/root-path | Bin 0 -> 1 bytes .../firmware/devicetree/base/chosen/server-ip | 2 + .../firmware/devicetree/base/chosen/tftp-file | Bin 0 -> 11 bytes .../firmware/devicetree/base/chosen/vendor-options | Bin 0 -> 1 bytes .../firmware/devicetree/base/ethernet/device_type | Bin 0 -> 8 bytes .../devicetree/base/ethernet/local-mac-address | 1 + .../firmware/devicetree/base/ethernet/mac-address | 1 + .../firmware/devicetree/base/ethernet/name | Bin 0 -> 9 bytes .../tests/sysfs-static/class/net/eth0/address | 1 + .../tests/sysfs-static/class/net/eth1/address | 1 + .../sysfs-static/firmware/ibft/ethernet0/gateway | 1 + .../sysfs-static/firmware/ibft/ethernet0/index | 1 + .../sysfs-static/firmware/ibft/ethernet0/ip-addr | 1 + .../tests/sysfs-static/firmware/ibft/ethernet0/mac | 1 + .../sysfs-static/firmware/ibft/ethernet0/origin | 1 + .../firmware/ibft/ethernet0/prefix-len | 1 + .../firmware/ibft/ethernet0/primary-dns | 1 + .../firmware/ibft/ethernet0/secondary-dns | 1 + .../firmware/ibft/ethernet0/subnet-mask | 1 + .../sysfs-static/firmware/ibft/ethernet0/vlan | 1 + .../sysfs-static/firmware/ibft/ethernet1/gateway | 1 + .../sysfs-static/firmware/ibft/ethernet1/index | 1 + .../tests/sysfs-static/firmware/ibft/ethernet1/mac | 1 + .../sysfs-static/firmware/ibft/ethernet1/origin | 1 + .../firmware/ibft/ethernet1/primary-dns | 1 + .../firmware/ibft/ethernet1/secondary-dns | 1 + .../sysfs-static/firmware/ibft/ethernet1/vlan | 1 + .../firmware/ibft/initiator/initiator-name | 1 + .../tests/sysfs-static/firmware/ibft/target0/index | 1 + .../sysfs-static/firmware/ibft/target0/ip-addr | 1 + .../tests/sysfs-static/firmware/ibft/target0/lun | 1 + .../tests/sysfs-static/firmware/ibft/target0/port | 1 + .../sysfs-static/firmware/ibft/target0/target-name | 1 + .../tests/sysfs-static/firmware/ibft/target1/index | 1 + .../sysfs-static/firmware/ibft/target1/ip-addr | 1 + .../tests/sysfs-static/firmware/ibft/target1/lun | 1 + .../tests/sysfs-static/firmware/ibft/target1/port | 1 + .../sysfs-static/firmware/ibft/target1/target-name | 1 + .../tests/sysfs-vlan/class/net/eth0/address | 1 + .../tests/sysfs-vlan/firmware/ibft/ethernet0/index | 1 + .../sysfs-vlan/firmware/ibft/ethernet0/ip-addr | 1 + .../tests/sysfs-vlan/firmware/ibft/ethernet0/mac | 1 + .../sysfs-vlan/firmware/ibft/ethernet0/origin | 1 + .../sysfs-vlan/firmware/ibft/ethernet0/prefix-len | 1 + .../sysfs-vlan/firmware/ibft/ethernet0/subnet-mask | 1 + .../tests/sysfs-vlan/firmware/ibft/ethernet0/vlan | 1 + .../firmware/ibft/initiator/initiator-name | 1 + .../tests/sysfs-vlan/firmware/ibft/target0/index | 1 + .../tests/sysfs-vlan/firmware/ibft/target0/ip-addr | 1 + .../tests/sysfs-vlan/firmware/ibft/target0/lun | 1 + .../tests/sysfs-vlan/firmware/ibft/target0/port | 1 + .../sysfs-vlan/firmware/ibft/target0/target-name | 1 + .../tests/sysfs/class/net/eth0/address | 1 + .../tests/sysfs/class/net/eth2/address | 1 + .../tests/sysfs/firmware/ibft/acpi_header/oem_id | 1 + .../sysfs/firmware/ibft/acpi_header/oem_table_id | 1 + .../sysfs/firmware/ibft/acpi_header/signature | 1 + .../tests/sysfs/firmware/ibft/ethernet0/dhcp | 1 + .../tests/sysfs/firmware/ibft/ethernet0/flags | 1 + .../tests/sysfs/firmware/ibft/ethernet0/gateway | 1 + .../tests/sysfs/firmware/ibft/ethernet0/hostname | 1 + .../tests/sysfs/firmware/ibft/ethernet0/index | 1 + .../tests/sysfs/firmware/ibft/ethernet0/ip-addr | 1 + .../tests/sysfs/firmware/ibft/ethernet0/mac | 1 + .../tests/sysfs/firmware/ibft/ethernet0/origin | 1 + .../tests/sysfs/firmware/ibft/ethernet0/prefix-len | 1 + .../sysfs/firmware/ibft/ethernet0/primary-dns | 1 + .../sysfs/firmware/ibft/ethernet0/secondary-dns | 1 + .../sysfs/firmware/ibft/ethernet0/subnet-mask | 1 + .../tests/sysfs/firmware/ibft/ethernet0/vlan | 1 + .../tests/sysfs/firmware/ibft/ethernet2/dhcp | 1 + .../tests/sysfs/firmware/ibft/ethernet2/flags | 1 + .../tests/sysfs/firmware/ibft/ethernet2/gateway | 1 + .../tests/sysfs/firmware/ibft/ethernet2/hostname | 1 + .../tests/sysfs/firmware/ibft/ethernet2/index | 1 + .../tests/sysfs/firmware/ibft/ethernet2/ip-addr | 1 + .../tests/sysfs/firmware/ibft/ethernet2/mac | 1 + .../tests/sysfs/firmware/ibft/ethernet2/origin | 1 + .../tests/sysfs/firmware/ibft/ethernet2/prefix-len | 1 + .../sysfs/firmware/ibft/ethernet2/primary-dns | 1 + .../sysfs/firmware/ibft/ethernet2/secondary-dns | 1 + .../sysfs/firmware/ibft/ethernet2/subnet-mask | 1 + .../tests/sysfs/firmware/ibft/ethernet2/vlan | 1 + .../tests/sysfs/firmware/ibft/initiator/flags | 1 + .../tests/sysfs/firmware/ibft/initiator/index | 1 + .../sysfs/firmware/ibft/initiator/initiator-name | 1 + .../sysfs/firmware/ibft/initiator/isns-server | 1 + .../firmware/ibft/initiator/pri-radius-server | 1 + .../firmware/ibft/initiator/sec-radius-server | 1 + .../tests/sysfs/firmware/ibft/initiator/slp-server | 1 + .../tests/sysfs/firmware/ibft/target0/chap-type | 1 + .../tests/sysfs/firmware/ibft/target0/flags | 1 + .../tests/sysfs/firmware/ibft/target0/index | 1 + .../tests/sysfs/firmware/ibft/target0/ip-addr | 1 + .../tests/sysfs/firmware/ibft/target0/lun | 1 + .../tests/sysfs/firmware/ibft/target0/nic-assoc | 1 + .../tests/sysfs/firmware/ibft/target0/port | 1 + .../tests/sysfs/firmware/ibft/target2/chap-type | 1 + .../tests/sysfs/firmware/ibft/target2/flags | 1 + .../tests/sysfs/firmware/ibft/target2/index | 1 + .../tests/sysfs/firmware/ibft/target2/ip-addr | 1 + .../tests/sysfs/firmware/ibft/target2/lun | 1 + .../tests/sysfs/firmware/ibft/target2/nic-assoc | 1 + .../tests/sysfs/firmware/ibft/target2/port | 1 + .../tests/sysfs/firmware/ibft/target2/target-name | 1 + .../tests/test-cmdline-reader.c | 2552 ++++++++++++++++++++ src/nm-initrd-generator/tests/test-dt-reader.c | 143 ++ src/nm-initrd-generator/tests/test-ibft-reader.c | 302 +++ 221 files changed, 5823 insertions(+) create mode 100644 src/nm-initrd-generator/meson.build create mode 100644 src/nm-initrd-generator/nm-initrd-generator.c create mode 100644 src/nm-initrd-generator/nm-initrd-generator.h create mode 100644 src/nm-initrd-generator/nmi-cmdline-reader.c create mode 100644 src/nm-initrd-generator/nmi-dt-reader.c create mode 100644 src/nm-initrd-generator/nmi-ibft-reader.c create mode 100644 src/nm-initrd-generator/tests/meson.build create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/class/net/eth0/address create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/mac create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/origin create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/prefix-len create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/subnet-mask create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/initiator/initiator-name create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/lun create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/port create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/target-name create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/class/net/eth0/address create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/mac create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/origin create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/prefix-len create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/subnet-mask create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/initiator/initiator-name create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/lun create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/port create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/target-name create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/class/net/eth0/address create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/mac create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/origin create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/prefix-len create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/subnet-mask create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/initiator/initiator-name create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/lun create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/port create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/target-name create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/class/net/eth0/address create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/mac create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/origin create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/prefix-len create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/subnet-mask create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/initiator/initiator-name create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/lun create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/port create mode 100644 src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/target-name create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/class/net/eth0/address create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/class/net/eth1/address create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/mac create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/origin create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/index create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/mac create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/origin create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/initiator/initiator-name create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/lun create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/port create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/target-name create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/index create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/lun create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/port create mode 100644 src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/target-name create mode 100644 src/nm-initrd-generator/tests/sysfs-dt-tftp/firmware/devicetree/base/chosen/bootpath create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-request create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-response create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/bootpath create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/broadcast-ip create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/client-ip create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/client-name create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/domain-name create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/gateway-ip create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/name create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/netmask-ip create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/root-path create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/server-ip create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/tftp-file create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/vendor-options create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/device_type create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/local-mac-address create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/mac-address create mode 100644 src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/name create mode 100644 src/nm-initrd-generator/tests/sysfs-static/class/net/eth0/address create mode 100644 src/nm-initrd-generator/tests/sysfs-static/class/net/eth1/address create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/mac create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/origin create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/prefix-len create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/subnet-mask create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/index create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/mac create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/origin create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/initiator/initiator-name create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/lun create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/port create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/target-name create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/index create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/lun create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/port create mode 100644 src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/target-name create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/class/net/eth0/address create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/mac create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/origin create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/prefix-len create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/subnet-mask create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/initiator/initiator-name create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/index create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/lun create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/port create mode 100644 src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/target-name create mode 100644 src/nm-initrd-generator/tests/sysfs/class/net/eth0/address create mode 100644 src/nm-initrd-generator/tests/sysfs/class/net/eth2/address create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/acpi_header/oem_id create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/acpi_header/oem_table_id create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/acpi_header/signature create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/dhcp create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/flags create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/hostname create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/index create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/mac create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/origin create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/prefix-len create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/subnet-mask create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/dhcp create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/flags create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/gateway create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/hostname create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/index create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/mac create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/origin create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/prefix-len create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/primary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/secondary-dns create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/subnet-mask create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/vlan create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/flags create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/index create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/initiator-name create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/isns-server create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/pri-radius-server create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/sec-radius-server create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/slp-server create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/chap-type create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/flags create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/index create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/lun create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/nic-assoc create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/port create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/chap-type create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/flags create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/index create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/ip-addr create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/lun create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/nic-assoc create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/port create mode 100644 src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/target-name create mode 100644 src/nm-initrd-generator/tests/test-cmdline-reader.c create mode 100644 src/nm-initrd-generator/tests/test-dt-reader.c create mode 100644 src/nm-initrd-generator/tests/test-ibft-reader.c (limited to 'src/nm-initrd-generator') diff --git a/src/nm-initrd-generator/meson.build b/src/nm-initrd-generator/meson.build new file mode 100644 index 00000000..080fe7e4 --- /dev/null +++ b/src/nm-initrd-generator/meson.build @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnmi_core = static_library( + 'nmi-core', + sources: files( + 'nmi-cmdline-reader.c', + 'nmi-dt-reader.c', + 'nmi-ibft-reader.c', + ), + include_directories: [ + src_inc, + top_inc, + ], + dependencies: [ + libnm_core_public_dep, + ], +) + +executable( + 'nm-initrd-generator', + 'nm-initrd-generator.c', + include_directories: [ + src_inc, + top_inc, + ], + dependencies: [ + libnm_core_public_dep, + ], + link_with: [ + libnmi_core, + libnm_core_aux_intern, + libnm_core_impl, + libnm_crypto, + libnm_platform, + libnm_base, + libnm_systemd_shared, + libnm_udev_aux, + libnm_log_core, + libnm_glib_aux, + libnm_std_aux, + libc_siphash, + ], + link_args: ldflags_linker_script_binary, + link_depends: linker_script_binary, + install: true, + install_dir: nm_libexecdir, +) diff --git a/src/nm-initrd-generator/nm-initrd-generator.c b/src/nm-initrd-generator/nm-initrd-generator.c new file mode 100644 index 00000000..b78808b2 --- /dev/null +++ b/src/nm-initrd-generator/nm-initrd-generator.c @@ -0,0 +1,236 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-initrd-generator.h" + +#include "libnm-base/nm-config-base.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-log-core/nm-logging.h" + +/*****************************************************************************/ + +#define _NMLOG(level, domain, ...) \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "initrd-generator: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ + +static void +output_conn(gpointer key, gpointer value, gpointer user_data) +{ + const char * basename = key; + NMConnection * connection = value; + char * connections_dir = user_data; + nm_auto_unref_keyfile GKeyFile *file = NULL; + gs_free char * data = NULL; + gs_free_error GError *error = NULL; + gsize len; + NMSetting * setting; + + setting = nm_setting_user_new(); + nm_connection_add_setting(connection, setting); + nm_setting_user_set_data(NM_SETTING_USER(setting), + NM_USER_TAG_ORIGIN, + "nm-initrd-generator", + NULL); + + if (!nm_connection_normalize(connection, NULL, NULL, &error)) + goto err_out; + + file = nm_keyfile_write(connection, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + if (file == NULL) + goto err_out; + + data = g_key_file_to_data(file, &len, &error); + if (!data) + goto err_out; + + if (connections_dir) { + gs_free char *filename = NULL; + gs_free char *full_filename = NULL; + + filename = nm_keyfile_utils_create_filename(basename, TRUE); + full_filename = g_build_filename(connections_dir, filename, NULL); + + if (!nm_utils_file_set_contents(full_filename, data, len, 0600, NULL, NULL, &error)) + goto err_out; + } else + g_print("\n*** Connection '%s' ***\n\n%s", basename, data); + + return; +err_out: + g_print("%s\n", error->message); +} + +#define DEFAULT_SYSFS_DIR "/sys" +#define DEFAULT_INITRD_DATA_DIR NMRUNDIR "/initrd" +#define DEFAULT_RUN_CONFIG_DIR NMRUNDIR "/conf.d" + +int +main(int argc, char *argv[]) +{ + GHashTable * connections; + gs_free char * connections_dir = NULL; + gs_free char * initrd_dir = NULL; + gs_free char * sysfs_dir = NULL; + gs_free char * run_config_dir = NULL; + gboolean dump_to_stdout = FALSE; + gs_strfreev char **remaining = NULL; + GOptionEntry option_entries[] = { + {"connections-dir", + 'c', + 0, + G_OPTION_ARG_FILENAME, + &connections_dir, + "Output connection directory", + NM_KEYFILE_PATH_NAME_RUN}, + {"initrd-data-dir", + 'i', + 0, + G_OPTION_ARG_FILENAME, + &initrd_dir, + "Output initrd data directory", + DEFAULT_INITRD_DATA_DIR}, + {"sysfs-dir", + 'd', + 0, + G_OPTION_ARG_FILENAME, + &sysfs_dir, + "The sysfs mount point", + DEFAULT_SYSFS_DIR}, + {"run-config-dir", + 'r', + 0, + G_OPTION_ARG_FILENAME, + &run_config_dir, + "Output config directory", + DEFAULT_RUN_CONFIG_DIR}, + {"stdout", + 's', + 0, + G_OPTION_ARG_NONE, + &dump_to_stdout, + "Dump connections to standard output", + NULL}, + {G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &remaining, NULL, NULL}, + {NULL}}; + nm_auto_free_option_context GOptionContext *option_context = NULL; + gs_free_error GError *error = NULL; + gs_free char * hostname = NULL; + int errsv; + gint64 carrier_timeout_sec = 0; + + option_context = g_option_context_new( + "-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] " + "[bootdev=...] [nameserver=...] [rd.peerdns=...] [rd.bootif=...] [BOOTIF=...] " + "[rd.znet=...] [rd.net.timeout.carrier=...] ... "); + + g_option_context_set_summary(option_context, "Generate early NetworkManager configuration."); + g_option_context_set_description( + option_context, + "This tool scans the command line for options relevant to network\n" + "configuration and creates configuration files for an early instance\n" + "of NetworkManager run from the initial ramdisk during early boot."); + g_option_context_add_main_entries(option_context, option_entries, GETTEXT_PACKAGE); + + if (!g_option_context_parse(option_context, &argc, &argv, &error)) { + _LOGW(LOGD_CORE, "%s", error->message); + return 1; + } + + if (!remaining) { + /* No arguments, no networking. Don't bother. */ + return 0; + } + + if (!connections_dir) + connections_dir = g_strdup(NM_KEYFILE_PATH_NAME_RUN); + if (!sysfs_dir) + sysfs_dir = g_strdup(DEFAULT_SYSFS_DIR); + if (!initrd_dir) + initrd_dir = g_strdup(DEFAULT_INITRD_DATA_DIR); + if (!run_config_dir) + run_config_dir = g_strdup(DEFAULT_RUN_CONFIG_DIR); + + connections = nmi_cmdline_reader_parse(sysfs_dir, + (const char *const *) remaining, + &hostname, + &carrier_timeout_sec); + + if (dump_to_stdout) { + nm_clear_g_free(&connections_dir); + nm_clear_g_free(&initrd_dir); + nm_clear_g_free(&run_config_dir); + if (hostname) + g_print("\n*** Hostname '%s' ***\n", hostname); + if (carrier_timeout_sec != 0) + g_print("\n*** Carrier Wait Timeout %" G_GINT64_FORMAT " sec ***\n", + carrier_timeout_sec); + } else { + if (g_mkdir_with_parents(connections_dir, 0755) != 0) { + errsv = errno; + _LOGW(LOGD_CORE, "%s: %s", connections_dir, nm_strerror_native(errsv)); + return 1; + } + if (g_mkdir_with_parents(initrd_dir, 0755) != 0) { + errsv = errno; + _LOGW(LOGD_CORE, "%s: %s", initrd_dir, nm_strerror_native(errsv)); + return 1; + } + if (g_mkdir_with_parents(run_config_dir, 0755) != 0) { + errsv = errno; + _LOGW(LOGD_CORE, "%s: %s", run_config_dir, nm_strerror_native(errsv)); + return 1; + } + + if (hostname) { + gs_free char *hostname_file = NULL; + gs_free char *data = NULL; + + hostname_file = g_strdup_printf("%s/hostname", initrd_dir); + data = g_strdup_printf("%s\n", hostname); + + if (!g_file_set_contents(hostname_file, data, strlen(data), &error)) { + _LOGW(LOGD_CORE, "%s: %s", hostname_file, error->message); + return 1; + } + } + if (carrier_timeout_sec != 0) { + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gs_free char * filename = NULL; + + keyfile = g_key_file_new(); + g_key_file_set_list_separator(keyfile, NM_CONFIG_KEYFILE_LIST_SEPARATOR); + filename = g_strdup_printf("%s/15-carrier-timeout.conf", run_config_dir); + + g_key_file_set_value(keyfile, + NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "-15-carrier-timeout", + NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE, + "*"); + g_key_file_set_int64(keyfile, + NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "-15-carrier-timeout", + NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT, + carrier_timeout_sec * 1000); + + if (!g_key_file_save_to_file(keyfile, filename, &error)) { + _LOGW(LOGD_CORE, "%s: %s", filename, error->message); + return 1; + } + } + } + + g_hash_table_foreach(connections, output_conn, connections_dir); + g_hash_table_destroy(connections); + + return 0; +} diff --git a/src/nm-initrd-generator/nm-initrd-generator.h b/src/nm-initrd-generator/nm-initrd-generator.h new file mode 100644 index 00000000..2ec52a01 --- /dev/null +++ b/src/nm-initrd-generator/nm-initrd-generator.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014, 2018 Red Hat, Inc. + */ + +#ifndef __NM_INITRD_GENERATOR_H__ +#define __NM_INITRD_GENERATOR_H__ + +#include "nm-connection.h" +#include "nm-utils.h" + +#define NMI_WAIT_DEVICE_TIMEOUT_MSEC 60000 +#define NMI_IP_REQUIRED_TIMEOUT_MSEC 20000 + +static inline int +get_ip_address_family(const char *str, gboolean with_prefix) +{ + int addr_family; + + if (!str) + return AF_UNSPEC; + + if (with_prefix) { + if (nm_utils_parse_inaddr_prefix_bin(AF_UNSPEC, str, &addr_family, NULL, NULL)) + return addr_family; + } else { + if (nm_utils_parse_inaddr_bin(AF_UNSPEC, str, &addr_family, NULL)) + return addr_family; + } + + return AF_UNSPEC; +} + +GHashTable *nmi_ibft_read(const char *sysfs_dir); + +gboolean +nmi_ibft_update_connection_from_nic(NMConnection *connection, GHashTable *nic, GError **error); + +NMConnection *nmi_dt_reader_parse(const char *sysfs_dir); + +GHashTable *nmi_cmdline_reader_parse(const char * sysfs_dir, + const char *const *argv, + char ** hostname, + gint64 * carrier_timeout_sec); + +#endif /* __NM_INITRD_GENERATOR_H__ */ diff --git a/src/nm-initrd-generator/nmi-cmdline-reader.c b/src/nm-initrd-generator/nmi-cmdline-reader.c new file mode 100644 index 00000000..a8501336 --- /dev/null +++ b/src/nm-initrd-generator/nmi-cmdline-reader.c @@ -0,0 +1,1416 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include +#include + +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-log-core/nm-logging.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-initrd-generator.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" + +/*****************************************************************************/ + +#define _NMLOG(level, domain, ...) \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "cmdline-reader: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ + +typedef struct { + GHashTable * hash; + GPtrArray * array; + GPtrArray * vlan_parents; + GHashTable * explicit_ip_connections; + NMConnection *bootdev_connection; /* connection for bootdev=$ifname */ + NMConnection *default_connection; /* connection not bound to any ifname */ + char * hostname; + + /* Parameters to be set for all connections */ + gboolean ignore_auto_dns; + int dhcp_timeout; + char * dhcp4_vci; + + gint64 carrier_timeout_sec; +} Reader; + +static Reader * +reader_new(void) +{ + Reader *reader; + + reader = g_slice_new(Reader); + *reader = (Reader){ + .hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref), + .explicit_ip_connections = + g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL), + .vlan_parents = g_ptr_array_new_with_free_func(g_free), + .array = g_ptr_array_new(), + }; + + return reader; +} + +static GHashTable * +reader_destroy(Reader *reader, gboolean free_hash) +{ + gs_unref_hashtable GHashTable *hash = NULL; + + g_ptr_array_unref(reader->array); + g_ptr_array_unref(reader->vlan_parents); + g_hash_table_unref(reader->explicit_ip_connections); + hash = g_steal_pointer(&reader->hash); + nm_clear_g_free(&reader->hostname); + nm_clear_g_free(&reader->dhcp4_vci); + nm_g_slice_free(reader); + if (!free_hash) + return g_steal_pointer(&hash); + return NULL; +} + +static NMConnection * +reader_add_connection(Reader *reader, const char *name, NMConnection *connection_take) +{ + char *name_dup; + + name_dup = g_strdup(name); + if (g_hash_table_insert(reader->hash, name_dup, connection_take)) + g_ptr_array_add(reader->array, name_dup); + + return connection_take; +} + +/* Returns a new connection owned by the reader */ +static NMConnection * +reader_create_connection(Reader * reader, + const char * basename, + const char * id, + const char * ifname, + const char * mac, + const char * type_name, + NMConnectionMultiConnect multi_connect) +{ + NMConnection *connection; + NMSetting * setting; + + connection = reader_add_connection(reader, basename, nm_simple_connection_new()); + + /* Start off assuming dynamic IP configurations. */ + + setting = nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + reader->ignore_auto_dns, + NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, + reader->dhcp_timeout, + NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, + reader->dhcp4_vci, + NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, + NMI_IP_REQUIRED_TIMEOUT_MSEC, + NULL); + + setting = nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, + (int) NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + reader->ignore_auto_dns, + NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, + reader->dhcp_timeout, + NULL); + + setting = nm_setting_connection_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, + NM_SETTING_CONNECTION_ID, + id, + NM_SETTING_CONNECTION_UUID, + nm_uuid_generate_random_str_a(), + NM_SETTING_CONNECTION_INTERFACE_NAME, + ifname, + NM_SETTING_CONNECTION_TYPE, + type_name, + NM_SETTING_CONNECTION_MULTI_CONNECT, + multi_connect, + NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, + 1, + NULL); + + if (nm_streq0(type_name, NM_SETTING_INFINIBAND_SETTING_NAME)) { + setting = nm_setting_infiniband_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); + } + + if (mac) { + if (nm_streq0(type_name, NM_SETTING_INFINIBAND_SETTING_NAME)) { + setting = (NMSetting *) nm_connection_get_setting_infiniband(connection); + g_object_set(setting, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); + } else { + setting = nm_setting_wired_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); + } + } + + return connection; +} + +static NMConnection * +reader_get_default_connection(Reader *reader) +{ + NMConnection *con; + + if (!reader->default_connection) { + con = reader_create_connection(reader, + "default_connection", + "Wired Connection", + NULL, + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NM_CONNECTION_MULTI_CONNECT_MULTIPLE); + nm_connection_add_setting(con, nm_setting_wired_new()); + reader->default_connection = con; + } + return reader->default_connection; +} + +static NMConnection * +reader_get_connection(Reader * reader, + const char *iface_spec, + const char *type_name, + gboolean create_if_missing) +{ + NMConnection *connection = NULL; + NMSetting * setting; + const char * ifname = NULL; + gs_free char *mac = NULL; + + if (iface_spec) { + if (nm_utils_is_valid_iface_name(iface_spec, NULL)) + ifname = iface_spec; + else { + mac = nm_utils_hwaddr_canonical(iface_spec, -1); + if (!mac) + _LOGW(LOGD_CORE, "invalid interface '%s'", iface_spec); + } + } + + if (!ifname && !mac) { + NMConnection * candidate; + NMSettingConnection *s_con; + guint i; + + /* + * If ifname was not given, we'll match the connection by type. + * If the type was not given either, then we're happy with any connection but slaves. + * This is so that things like "bond=bond0:eth1,eth2 nameserver=1.3.3.7 end up + * slapping the nameserver to the most reasonable connection (bond0). + */ + for (i = 0; i < reader->array->len; i++) { + candidate = g_hash_table_lookup(reader->hash, reader->array->pdata[i]); + s_con = nm_connection_get_setting_connection(candidate); + + if (type_name == NULL && nm_setting_connection_get_master(s_con) == NULL) { + connection = candidate; + break; + } + + if (type_name != NULL + && nm_streq(nm_setting_connection_get_connection_type(s_con), type_name)) { + connection = candidate; + break; + } + } + } else + connection = g_hash_table_lookup(reader->hash, (gpointer) ifname ?: mac); + + if (!connection) { + if (!create_if_missing) + return NULL; + + if (!type_name) { + if (NM_STR_HAS_PREFIX(ifname, "ib") + || (mac && nm_utils_hwaddr_valid(mac, INFINIBAND_ALEN))) + type_name = NM_SETTING_INFINIBAND_SETTING_NAME; + else + type_name = NM_SETTING_WIRED_SETTING_NAME; + } + + connection = reader_create_connection(reader, + ifname ?: mac, + ifname ?: (mac ?: "Wired Connection"), + ifname, + mac, + type_name, + NM_CONNECTION_MULTI_CONNECT_SINGLE); + } + setting = (NMSetting *) nm_connection_get_setting_connection(connection); + + if (type_name) { + g_object_set(setting, NM_SETTING_CONNECTION_TYPE, type_name, NULL); + if (!nm_connection_get_setting_by_name(connection, type_name)) { + setting = g_object_new(nm_setting_lookup_type(type_name), NULL); + nm_connection_add_setting(connection, setting); + } + } + + return connection; +} + +static char * +get_word(char **argument, const char separator) +{ + char *word; + int nest = 0; + + if (*argument == NULL) + return NULL; + + if (**argument == '[') { + nest++; + (*argument)++; + } + + word = *argument; + + while (**argument != '\0') { + if (nest && **argument == ']') { + **argument = '\0'; + (*argument)++; + nest--; + continue; + } + + if (nest == 0 && **argument == separator) { + **argument = '\0'; + (*argument)++; + break; + } + (*argument)++; + } + + return *word ? word : NULL; +} + +static void +connection_set(NMConnection *connection, + const char * setting_name, + const char * property, + const char * value) +{ + NMSetting * setting; + GType setting_type; + nm_auto_unref_gtypeclass GObjectClass *object_class = NULL; + GParamSpec * spec; + + setting_type = nm_setting_lookup_type(setting_name); + object_class = g_type_class_ref(setting_type); + spec = g_object_class_find_property(object_class, property); + nm_assert(spec); + + setting = nm_connection_get_setting_by_name(connection, setting_name); + if (!setting) { + setting = g_object_new(setting_type, NULL); + nm_connection_add_setting(connection, setting); + } + + if (G_IS_PARAM_SPEC_UINT(spec)) { + guint v; + + v = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT, 0); + if (errno || !nm_g_object_set_property_uint(G_OBJECT(setting), property, v, NULL)) { + _LOGW(LOGD_CORE, + "Could not set property '%s.%s' to '%s'", + setting_name, + property, + value); + } + } else if (G_IS_PARAM_SPEC_STRING(spec)) + g_object_set(setting, property, value, NULL); + else + _LOGW(LOGD_CORE, "Don't know how to set '%s' of %s", property, setting_name); +} + +static void +reader_read_all_connections_from_fw(Reader *reader, const char *sysfs_dir) +{ + gs_unref_hashtable GHashTable *ibft = NULL; + NMConnection * dt_connection; + const char * mac; + GHashTable * nic; + const char * index; + GError * error = NULL; + guint i, length; + gs_free const char ** keys = NULL; + + ibft = nmi_ibft_read(sysfs_dir); + keys = nm_utils_strdict_get_keys(ibft, TRUE, &length); + + for (i = 0; i < length; i++) { + gs_unref_object NMConnection *connection = NULL; + gs_free char * name = NULL; + + mac = keys[i]; + nic = g_hash_table_lookup(ibft, mac); + connection = nm_simple_connection_new(); + index = g_hash_table_lookup(nic, "index"); + if (!index) { + _LOGW(LOGD_CORE, "Ignoring an iBFT entry without an index"); + continue; + } + + if (!nmi_ibft_update_connection_from_nic(connection, nic, &error)) { + _LOGW(LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message); + g_error_free(error); + continue; + } + + name = g_strdup_printf("ibft%s", index); + reader_add_connection(reader, name, g_steal_pointer(&connection)); + } + + dt_connection = nmi_dt_reader_parse(sysfs_dir); + if (dt_connection) + reader_add_connection(reader, "ofw", dt_connection); +} + +static void +reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4 = NULL, *s_ip6 = NULL; + gs_unref_hashtable GHashTable *ibft = NULL; + const char * tmp; + const char * tmp2; + const char * kind = NULL; + const char * client_ip = NULL; + const char * peer = NULL; + const char * gateway_ip = NULL; + const char * netmask = NULL; + const char * client_hostname = NULL; + const char * iface_spec = NULL; + const char * mtu = NULL; + const char * macaddr = NULL; + int client_ip_family = AF_UNSPEC; + int client_ip_prefix = -1; + gboolean clear_ip4_required_timeout = TRUE; + const char * dns[2] = { + NULL, + NULL, + }; + int dns_addr_family[2] = { + AF_UNSPEC, + AF_UNSPEC, + }; + int i; + GError *error = NULL; + + if (!*argument) + return; + + tmp = get_word(&argument, ':'); + if (!*argument) { + /* ip={dhcp|on|any|dhcp6|auto6|link6|ibft} */ + kind = tmp; + } else { + tmp2 = get_word(&argument, ':'); + if (NM_IN_STRSET(tmp2, + "none", + "off", + "dhcp", + "single-dhcp", + "on" + "any", + "dhcp6", + "auto", + "auto6", + "link6", + "ibft")) { + /* :{none|off|dhcp|on|any|dhcp6|auto|auto6|link6|ibft} */ + iface_spec = tmp; + kind = tmp2; + } else { + /* :[]:::: */ + client_ip = tmp; + if (client_ip) { + client_ip_family = get_ip_address_family(client_ip, TRUE); + if (client_ip_family == AF_UNSPEC) { + _LOGW(LOGD_CORE, "Invalid IP address '%s'.", client_ip); + return; + } + } + + peer = tmp2; + gateway_ip = get_word(&argument, ':'); + netmask = get_word(&argument, ':'); + client_hostname = get_word(&argument, ':'); + iface_spec = get_word(&argument, ':'); + kind = get_word(&argument, ':'); + } + + if (client_hostname && !nm_sd_hostname_is_valid(client_hostname, FALSE)) + client_hostname = NULL; + + if (client_hostname) { + g_free(reader->hostname); + reader->hostname = g_strdup(client_hostname); + } + + tmp = get_word(&argument, ':'); + dns_addr_family[0] = get_ip_address_family(tmp, FALSE); + if (dns_addr_family[0] != AF_UNSPEC) { + dns[0] = tmp; + dns[1] = get_word(&argument, ':'); + if (dns[1]) { + dns_addr_family[1] = get_ip_address_family(dns[1], FALSE); + if (dns_addr_family[1] == AF_UNSPEC) + _LOGW(LOGD_CORE, "Ignoring invalid DNS server: '%s'.", dns[1]); + if (*argument) + _LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument); + } + } else { + mtu = tmp; + macaddr = argument; + } + } + + if (iface_spec == NULL && NM_IN_STRSET(kind, "fw", "ibft")) { + reader_read_all_connections_from_fw(reader, sysfs_dir); + return; + } + + /* Parsing done, construct the NMConnection. */ + if (iface_spec) + connection = reader_get_connection(reader, iface_spec, NULL, TRUE); + else + connection = reader_get_default_connection(reader); + + g_hash_table_add(reader->explicit_ip_connections, g_object_ref(connection)); + + s_con = nm_connection_get_setting_connection(connection); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + + if (netmask && *netmask) { + gboolean is_ipv4 = client_ip_family == AF_INET; + NMIPAddr addr; + + if (is_ipv4 && nm_utils_parse_inaddr_bin(AF_INET, netmask, NULL, &addr)) + client_ip_prefix = nm_utils_ip4_netmask_to_prefix(addr.addr4); + else + client_ip_prefix = _nm_utils_ascii_str_to_int64(netmask, 10, 0, is_ipv4 ? 32 : 128, -1); + + if (client_ip_prefix == -1) + _LOGW(LOGD_CORE, "Invalid IP mask: %s", netmask); + } + + /* Static IP configuration might be present. */ + if (client_ip && *client_ip) { + NMIPAddress *address = NULL; + NMIPAddr addr; + + if (nm_utils_parse_inaddr_prefix_bin(client_ip_family, + client_ip, + NULL, + &addr, + client_ip_prefix == -1 ? &client_ip_prefix : NULL)) { + if (client_ip_prefix == -1) { + switch (client_ip_family) { + case AF_INET: + client_ip_prefix = _nm_utils_ip4_get_default_prefix(addr.addr4); + break; + case AF_INET6: + client_ip_prefix = 64; + break; + } + } + + address = nm_ip_address_new_binary(client_ip_family, + &addr.addr_ptr, + client_ip_prefix, + &error); + if (!address) { + _LOGW(LOGD_CORE, "Invalid address '%s': %s", client_ip, error->message); + g_clear_error(&error); + } + } else + nm_assert_not_reached(); + + if (address) { + /* We don't want to have multiple devices up with the + * same static address. */ + g_object_set(s_con, + NM_SETTING_CONNECTION_MULTI_CONNECT, + NM_CONNECTION_MULTI_CONNECT_SINGLE, + NULL); + switch (client_ip_family) { + case AF_INET: + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + nm_setting_ip_config_add_address(s_ip4, address); + break; + case AF_INET6: + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + nm_setting_ip_config_add_address(s_ip6, address); + break; + default: + nm_assert_not_reached(); + break; + } + nm_ip_address_unref(address); + } + } + + /* Dynamic IP configuration configured explicitly. */ + if (NM_IN_STRSET(kind, "none", "off")) { + if (nm_setting_ip_config_get_num_addresses(s_ip6) == 0) { + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED, + NULL); + } + if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + } + } else if (NM_IN_STRSET(kind, "dhcp", "single-dhcp")) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + if (nm_setting_ip_config_get_num_addresses(s_ip6) == 0) { + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NULL); + } + } else if (NM_IN_STRSET(kind, "auto6", "dhcp6")) { + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + } + } else if (nm_streq0(kind, "link6")) { + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + } + } else if (nm_streq0(kind, "ibft")) { + NMSettingWired *s_wired; + const char * mac = NULL; + const char * ifname; + gs_free char * mac_free = NULL; + gs_free char * address_path = NULL; + GHashTable * nic = NULL; + + if ((s_wired = nm_connection_get_setting_wired(connection)) + && (mac = nm_setting_wired_get_mac_address(s_wired))) { + /* got mac from the connection */ + } else if ((ifname = nm_connection_get_interface_name(connection))) { + /* read it from sysfs */ + address_path = g_build_filename(sysfs_dir, "class", "net", ifname, "address", NULL); + if (g_file_get_contents(address_path, &mac_free, NULL, &error)) { + g_strchomp(mac_free); + mac = mac_free; + } else { + _LOGW(LOGD_CORE, "Can't get a MAC address for %s: %s", ifname, error->message); + g_clear_error(&error); + } + } + + if (mac) { + gs_free char *mac_up = NULL; + + mac_up = g_ascii_strup(mac, -1); + ibft = nmi_ibft_read(sysfs_dir); + nic = g_hash_table_lookup(ibft, mac_up); + if (!nic) + _LOGW(LOGD_CORE, "No iBFT NIC for %s (%s)", iface_spec, mac_up); + } + + if (nic) { + if (!nmi_ibft_update_connection_from_nic(connection, nic, &error)) { + _LOGW(LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message); + g_clear_error(&error); + } + } + } else { + clear_ip4_required_timeout = FALSE; + } + + if (clear_ip4_required_timeout) + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, -1, NULL); + + if (peer && *peer) + _LOGW(LOGD_CORE, "Ignoring peer: %s (not implemented)\n", peer); + + if (gateway_ip && *gateway_ip) { + switch (get_ip_address_family(gateway_ip, FALSE)) { + case AF_INET: + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL); + break; + case AF_INET6: + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL); + break; + default: + _LOGW(LOGD_CORE, "Invalid gateway: %s", gateway_ip); + break; + } + } + + if (client_hostname && *client_hostname) { + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, client_hostname, NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, client_hostname, NULL); + } + + for (i = 0; i < 2; i++) { + if (dns_addr_family[i] == AF_UNSPEC) + break; + nm_assert(nm_utils_ipaddr_is_valid(dns_addr_family[i], dns[i])); + nm_setting_ip_config_add_dns(NM_IS_IPv4(dns_addr_family[i]) ? s_ip4 : s_ip6, dns[i]); + } + + if (mtu && *mtu) + connection_set(connection, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, mtu); + + if (macaddr && *macaddr) + connection_set(connection, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + macaddr); +} + +static void +reader_parse_master(Reader *reader, char *argument, const char *type_name, const char *default_name) +{ + NMConnection * connection; + NMSettingConnection *s_con; + gs_free char * master_to_free = NULL; + const char * master; + char * slaves; + const char * slave; + char * opts; + const char * mtu = NULL; + + master = get_word(&argument, ':'); + if (!master) + master = master_to_free = g_strdup_printf("%s0", default_name ?: type_name); + slaves = get_word(&argument, ':'); + + connection = reader_get_connection(reader, master, type_name, TRUE); + s_con = nm_connection_get_setting_connection(connection); + master = nm_setting_connection_get_uuid(s_con); + + if (nm_streq(type_name, NM_SETTING_BRIDGE_SETTING_NAME)) { + NMSettingBridge *s_bridge = nm_connection_get_setting_bridge(connection); + + /* Avoid the forwarding delay */ + g_object_set(s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL); + } else if (nm_streq(type_name, NM_SETTING_BOND_SETTING_NAME)) { + NMSettingBond *s_bond = nm_connection_get_setting_bond(connection); + + opts = get_word(&argument, ':'); + while (opts && *opts) { + gs_free_error GError *error = NULL; + char * opt; + const char * opt_name; + + opt = get_word(&opts, ','); + opt_name = get_word(&opt, '='); + + if (!_nm_setting_bond_validate_option(opt_name, opt, &error)) { + _LOGW(LOGD_CORE, + "Ignoring invalid bond option: %s%s%s = %s%s%s: %s", + NM_PRINT_FMT_QUOTE_STRING(opt_name), + NM_PRINT_FMT_QUOTE_STRING(opt), + error->message); + continue; + } + nm_setting_bond_add_option(s_bond, opt_name, opt); + } + + mtu = get_word(&argument, ':'); + } + + if (mtu) + connection_set(connection, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, mtu); + + do { + slave = get_word(&slaves, ','); + if (slave == NULL) + slave = "eth0"; + + connection = reader_get_connection(reader, slave, NULL, TRUE); + s_con = nm_connection_get_setting_connection(connection); + g_object_set(s_con, + NM_SETTING_CONNECTION_SLAVE_TYPE, + type_name, + NM_SETTING_CONNECTION_MASTER, + master, + NULL); + } while (slaves && *slaves != '\0'); + + if (argument && *argument) + _LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument); +} + +static void +reader_add_routes(Reader *reader, GPtrArray *array) +{ + guint i; + + for (i = 0; i < array->len; i++) { + NMConnection * connection = NULL; + const char * net; + const char * gateway; + const char * interface; + int family = AF_UNSPEC; + NMIPAddr net_addr = {}; + NMIPAddr gateway_addr = {}; + int net_prefix = -1; + NMIPRoute * route; + NMSettingIPConfig *s_ip; + char * argument; + gs_free_error GError *error = NULL; + + argument = array->pdata[i]; + net = get_word(&argument, ':'); + gateway = get_word(&argument, ':'); + interface = get_word(&argument, ':'); + + if (interface) + connection = reader_get_connection(reader, interface, NULL, TRUE); + if (!connection) + connection = reader->bootdev_connection; + if (!connection) + connection = reader_get_connection(reader, interface, NULL, FALSE); + if (!connection) + connection = reader_get_default_connection(reader); + + if (net && *net) { + if (!nm_utils_parse_inaddr_prefix_bin(family, net, &family, &net_addr, &net_prefix)) { + _LOGW(LOGD_CORE, "Unrecognized address: %s", net); + continue; + } + } + + if (gateway && *gateway) { + if (!nm_utils_parse_inaddr_bin(family, gateway, &family, &gateway_addr)) { + _LOGW(LOGD_CORE, "Unrecognized address: %s", gateway); + continue; + } + } + + switch (family) { + case AF_INET: + s_ip = nm_connection_get_setting_ip4_config(connection); + if (net_prefix == -1) + net_prefix = 32; + break; + case AF_INET6: + s_ip = nm_connection_get_setting_ip6_config(connection); + if (net_prefix == -1) + net_prefix = 128; + break; + default: + _LOGW(LOGD_CORE, "Unknown address family: %s", net); + continue; + } + + route = nm_ip_route_new_binary(family, + &net_addr.addr_ptr, + net_prefix, + &gateway_addr.addr_ptr, + -1, + &error); + if (!route) { + g_warning("Invalid route '%s via %s': %s\n", net, gateway, error->message); + continue; + } + + nm_setting_ip_config_add_route(s_ip, route); + nm_ip_route_unref(route); + } +} + +static void +reader_parse_vlan(Reader *reader, char *argument) +{ + NMConnection * connection; + NMSettingVlan *s_vlan; + const char * vlan; + const char * phy; + const char * vlanid; + + vlan = get_word(&argument, ':'); + phy = get_word(&argument, ':'); + + for (vlanid = vlan + strlen(vlan); vlanid > vlan; vlanid--) { + if (!g_ascii_isdigit(*(vlanid - 1))) + break; + } + + connection = reader_get_connection(reader, vlan, NM_SETTING_VLAN_SETTING_NAME, TRUE); + + s_vlan = nm_connection_get_setting_vlan(connection); + g_object_set(s_vlan, + NM_SETTING_VLAN_PARENT, + phy, + NM_SETTING_VLAN_ID, + (guint) _nm_utils_ascii_str_to_int64(vlanid, 10, 0, G_MAXUINT, G_MAXUINT), + NULL); + + if (argument && *argument) + _LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument); + + if (!nm_strv_ptrarray_contains(reader->vlan_parents, phy)) + g_ptr_array_add(reader->vlan_parents, g_strdup(phy)); +} + +static void +reader_parse_ib_pkey(Reader *reader, char *argument) +{ + NMConnection * connection; + NMSettingInfiniband *s_ib; + char * ifname; + gs_free char * parent = NULL; + char * pkey; + gint64 pkey_int; + + /* At the moment we only support ib.pkey=.; + * in the future we want to possibly support other options: + * ib.pkey=.: