mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-30 12:33:02 +02:00
+1
-1
Submodule buildroot updated: c32a08efd2...a8bc73ddbd
@@ -38,6 +38,7 @@ BR2_PACKAGE_STRESS_NG=y
|
|||||||
BR2_PACKAGE_JQ=y
|
BR2_PACKAGE_JQ=y
|
||||||
BR2_PACKAGE_E2FSPROGS=y
|
BR2_PACKAGE_E2FSPROGS=y
|
||||||
BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y
|
BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y
|
||||||
|
BR2_PACKAGE_LINUX_FIRMWARE_INSIDE_SECURE_MINIFW=y
|
||||||
BR2_PACKAGE_LINUX_FIRMWARE_RTL_8169=y
|
BR2_PACKAGE_LINUX_FIRMWARE_RTL_8169=y
|
||||||
BR2_PACKAGE_DBUS_CXX=y
|
BR2_PACKAGE_DBUS_CXX=y
|
||||||
BR2_PACKAGE_DBUS_GLIB=y
|
BR2_PACKAGE_DBUS_GLIB=y
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ BR2_PACKAGE_STRESS_NG=y
|
|||||||
BR2_PACKAGE_SYSREPO_GROUP="sys-cli"
|
BR2_PACKAGE_SYSREPO_GROUP="sys-cli"
|
||||||
BR2_PACKAGE_JQ=y
|
BR2_PACKAGE_JQ=y
|
||||||
BR2_PACKAGE_E2FSPROGS=y
|
BR2_PACKAGE_E2FSPROGS=y
|
||||||
|
BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y
|
||||||
|
BR2_PACKAGE_LINUX_FIRMWARE_INSIDE_SECURE_MINIFW=y
|
||||||
|
BR2_PACKAGE_LINUX_FIRMWARE_RTL_8169=y
|
||||||
BR2_PACKAGE_DBUS_CXX=y
|
BR2_PACKAGE_DBUS_CXX=y
|
||||||
BR2_PACKAGE_DBUS_GLIB=y
|
BR2_PACKAGE_DBUS_GLIB=y
|
||||||
BR2_PACKAGE_DBUS_TRIGGERD=y
|
BR2_PACKAGE_DBUS_TRIGGERD=y
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ All notable changes to the project are documented in this file.
|
|||||||
### Changes
|
### Changes
|
||||||
|
|
||||||
- Upgrade Linux kernel to 6.12.58 (LTS)
|
- Upgrade Linux kernel to 6.12.58 (LTS)
|
||||||
|
- Enable MVEBU SafeXcel Crypto Engine firmware for Marvell Armada SOCs (37xx,
|
||||||
|
7k, 8k, and CN913x series). Fixes kernel warnings about firmware load failures
|
||||||
|
and crypto-safexcel probe errors on affected boards
|
||||||
- Major improvements to OSPF and BFD operational data and CLI commands:
|
- Major improvements to OSPF and BFD operational data and CLI commands:
|
||||||
- CLI commands now use data from the operational datastore instead of
|
- CLI commands now use data from the operational datastore instead of
|
||||||
calling vtysh directly, providing better integration and consistency
|
calling vtysh directly, providing better integration and consistency
|
||||||
@@ -38,6 +41,9 @@ All notable changes to the project are documented in this file.
|
|||||||
kernel default (*inherit*), which in turn fixes reported issues with dropped
|
kernel default (*inherit*), which in turn fixes reported issues with dropped
|
||||||
OSPF Hello frames in GRE tunnels
|
OSPF Hello frames in GRE tunnels
|
||||||
- [Document][bpi-r3-emmc-documentation] how to go from SD card to eMMC on bpi-r3
|
- [Document][bpi-r3-emmc-documentation] how to go from SD card to eMMC on bpi-r3
|
||||||
|
- Add CLI commands for managing boot partition order: `show boot-order` and
|
||||||
|
`set boot-order` allow viewing and changing the boot order from the CLI,
|
||||||
|
complementing the existing YANG RPC support, issue #1032
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
@@ -47,6 +53,7 @@ All notable changes to the project are documented in this file.
|
|||||||
existing invalid configurations are automatically corrected during upgrade
|
existing invalid configurations are automatically corrected during upgrade
|
||||||
- Fix serious regression in boot time, introduced in v25.10, delays the
|
- Fix serious regression in boot time, introduced in v25.10, delays the
|
||||||
boot step "Mounting filesystems ..." with up to 30 seconds!
|
boot step "Mounting filesystems ..." with up to 30 seconds!
|
||||||
|
- Fix broken intra-document links in container and tunnel documentation
|
||||||
|
|
||||||
[lastest-boot]: https://github.com/kernelkit/infix/releases/latest-boot
|
[lastest-boot]: https://github.com/kernelkit/infix/releases/latest-boot
|
||||||
[bpi-r3-emmc-documentation]: https://github.com/kernelkit/infix/blob/main/board/aarch64/bananapi-bpi-r3/README.md
|
[bpi-r3-emmc-documentation]: https://github.com/kernelkit/infix/blob/main/board/aarch64/bananapi-bpi-r3/README.md
|
||||||
|
|||||||
+1
-2
@@ -1053,8 +1053,7 @@ tarballs with SHA256 checksums for integrity checking.
|
|||||||
|
|
||||||
Finally, if you build your own version of Infix, and embed OCI tarballs
|
Finally, if you build your own version of Infix, and embed OCI tarballs
|
||||||
in the system image, then see the tip at the end of [Upgrading a
|
in the system image, then see the tip at the end of [Upgrading a
|
||||||
Container Image](#upgrading-a-container-image) (above).
|
Container Image](#embedded-container-images) (above).
|
||||||
|
|
||||||
|
|
||||||
[0]: networking.md
|
[0]: networking.md
|
||||||
[1]: https://github.com/kernelkit/infix/blob/main/src/confd/yang/infix-containers.yang
|
[1]: https://github.com/kernelkit/infix/blob/main/src/confd/yang/infix-containers.yang
|
||||||
|
|||||||
+3
-3
@@ -55,7 +55,7 @@ admin@example:/>
|
|||||||
```
|
```
|
||||||
|
|
||||||
GRETAP interfaces can be added to a bridge, bridging local and remote Ethernet
|
GRETAP interfaces can be added to a bridge, bridging local and remote Ethernet
|
||||||
segments. See the [Bridge Configuration](networking.md#bridge-configuration)
|
segments. See the [Bridge Configuration](networking.md#bridging)
|
||||||
for more on bridges.
|
for more on bridges.
|
||||||
|
|
||||||
### OSPF over GRE
|
### OSPF over GRE
|
||||||
@@ -98,8 +98,8 @@ admin@siteB:/>
|
|||||||
```
|
```
|
||||||
|
|
||||||
Once configured, OSPF will establish a neighbor relationship through the
|
Once configured, OSPF will establish a neighbor relationship through the
|
||||||
tunnel and exchange routes between the sites. For more on OSPF
|
tunnel and exchange routes between the sites. For more info on OSPF
|
||||||
configuration, see [Routing Configuration](routing.md).
|
configuration, see [OSPFv2 Routing](networking.md#ospfv2-routing).
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Consider adjusting MTU on the tunnel interface to account for GRE
|
> Consider adjusting MTU on the tunnel interface to account for GRE
|
||||||
|
|||||||
@@ -23,6 +23,79 @@ YANG support for upgrading Infix, inspecting and _modifying_ the
|
|||||||
boot-order, is defined in [infix-system-software][2].
|
boot-order, is defined in [infix-system-software][2].
|
||||||
|
|
||||||
|
|
||||||
|
## Changing Boot Order
|
||||||
|
|
||||||
|
The boot order can be manually changed using the `set boot-order` command.
|
||||||
|
This is useful for rolling back to a previous version or changing the
|
||||||
|
preferred boot source.
|
||||||
|
|
||||||
|
The command accepts one to three boot targets as separate arguments, in the
|
||||||
|
desired boot order. Valid boot targets are:
|
||||||
|
|
||||||
|
- `primary` - The primary partition
|
||||||
|
- `secondary` - The secondary partition
|
||||||
|
- `net` - Network boot (if supported by bootloader)
|
||||||
|
|
||||||
|
The CLI provides tab-completion for boot targets, making it easy to enter
|
||||||
|
valid values.
|
||||||
|
|
||||||
|
Example: View current boot order and change it:
|
||||||
|
|
||||||
|
```
|
||||||
|
admin@example:/> show boot-order
|
||||||
|
primary secondary net
|
||||||
|
admin@example:/> set boot-order secondary primary net
|
||||||
|
admin@example:/> show boot-order
|
||||||
|
secondary primary net
|
||||||
|
admin@example:/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Example: Set boot order to only try primary partition:
|
||||||
|
|
||||||
|
```
|
||||||
|
admin@example:/> show boot-order
|
||||||
|
secondary primary net
|
||||||
|
admin@example:/> set boot-order primary
|
||||||
|
admin@example:/> show boot-order
|
||||||
|
primary
|
||||||
|
admin@example:/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Example: Using tab-completion (press TAB to see available options):
|
||||||
|
|
||||||
|
```
|
||||||
|
admin@example:/> set boot-order <TAB>
|
||||||
|
net primary secondary
|
||||||
|
admin@example:/> set boot-order secondary <TAB>
|
||||||
|
net primary secondary
|
||||||
|
admin@example:/> set boot-order secondary primary
|
||||||
|
admin@example:/> show boot-order
|
||||||
|
secondary primary
|
||||||
|
admin@example:/>
|
||||||
|
```
|
||||||
|
|
||||||
|
The new boot order takes effect on the next reboot and can be verified
|
||||||
|
with `show boot-order` or `show software`:
|
||||||
|
|
||||||
|
```
|
||||||
|
admin@example:/> show software
|
||||||
|
BOOT ORDER
|
||||||
|
secondary primary
|
||||||
|
|
||||||
|
NAME STATE VERSION DATE
|
||||||
|
primary booted v25.01.0 2025-04-25T10:15:00+00:00
|
||||||
|
secondary inactive v25.01.0 2025-04-25T10:07:20+00:00
|
||||||
|
admin@example:/>
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The boot order is automatically updated when performing an upgrade.
|
||||||
|
> The newly installed image will be set as the first boot target.
|
||||||
|
>
|
||||||
|
> Duplicate boot targets are not allowed. The CLI will reject attempts to
|
||||||
|
> specify the same target multiple times.
|
||||||
|
|
||||||
|
|
||||||
## Upgrading
|
## Upgrading
|
||||||
|
|
||||||
Upgrading Infix is done one partition at a time. If the system has
|
Upgrading Infix is done one partition at a time. If the system has
|
||||||
|
|||||||
@@ -263,6 +263,89 @@ int infix_shell(kcontext_t *ctx)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *boot_targets[] = {
|
||||||
|
"primary",
|
||||||
|
"secondary",
|
||||||
|
"net",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
int infix_boot_targets(kcontext_t *ctx)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
(void)ctx;
|
||||||
|
|
||||||
|
for (i = 0; boot_targets[i]; i++)
|
||||||
|
puts(boot_targets[i]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *valid_boot_target(const kparg_t *parg)
|
||||||
|
{
|
||||||
|
const char *target;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!parg)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
target = kparg_value(parg);
|
||||||
|
for (i = 0; boot_targets[i]; i++) {
|
||||||
|
if (!strcmp(target, boot_targets[i]))
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int infix_set_boot_order(kcontext_t *ctx)
|
||||||
|
{
|
||||||
|
char tmpfile[] = "/tmp/boot-order-XXXXXX";
|
||||||
|
kpargv_t *pargv = kcontext_pargv(ctx);
|
||||||
|
const char *targets[3];
|
||||||
|
int fd, rc = 0;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
targets[0] = valid_boot_target(kpargv_find(pargv, "first"));
|
||||||
|
targets[1] = valid_boot_target(kpargv_find(pargv, "second"));
|
||||||
|
targets[2] = valid_boot_target(kpargv_find(pargv, "third"));
|
||||||
|
|
||||||
|
if (!targets[0]) {
|
||||||
|
fprintf(stderr, ERRMSG "missing boot target\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = mkstemp(tmpfile);
|
||||||
|
if (fd == -1)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
fp = fdopen(fd, "w");
|
||||||
|
if (!fp) {
|
||||||
|
close(fd);
|
||||||
|
unlink(tmpfile);
|
||||||
|
fail:
|
||||||
|
fprintf(stderr, ERRMSG "failed creating temporary file\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("{\"infix-system:set-boot-order\":{\"boot-order\":[", fp);
|
||||||
|
for (size_t i = 0; i < NELEMS(targets); i++) {
|
||||||
|
if (!targets[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fprintf(fp, "%s\"%s\"", i > 0 ? "," : "", targets[i]);
|
||||||
|
}
|
||||||
|
fputs("]}}", fp);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
rc = systemf("sysrepocfg -R %s -fjson 2>&1", tmpfile);
|
||||||
|
unlink(tmpfile);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int kplugin_infix_fini(kcontext_t *ctx)
|
int kplugin_infix_fini(kcontext_t *ctx)
|
||||||
{
|
{
|
||||||
(void)ctx;
|
(void)ctx;
|
||||||
@@ -274,6 +357,7 @@ int kplugin_infix_init(kcontext_t *ctx)
|
|||||||
{
|
{
|
||||||
kplugin_t *plugin = kcontext_plugin(ctx);
|
kplugin_t *plugin = kcontext_plugin(ctx);
|
||||||
|
|
||||||
|
kplugin_add_syms(plugin, ksym_new("boot_targets", infix_boot_targets));
|
||||||
kplugin_add_syms(plugin, ksym_new("copy", infix_copy));
|
kplugin_add_syms(plugin, ksym_new("copy", infix_copy));
|
||||||
kplugin_add_syms(plugin, ksym_new("datastore", infix_datastore));
|
kplugin_add_syms(plugin, ksym_new("datastore", infix_datastore));
|
||||||
kplugin_add_syms(plugin, ksym_new("erase", infix_erase));
|
kplugin_add_syms(plugin, ksym_new("erase", infix_erase));
|
||||||
@@ -282,6 +366,7 @@ int kplugin_infix_init(kcontext_t *ctx)
|
|||||||
kplugin_add_syms(plugin, ksym_new("firewall_zones", infix_firewall_zones));
|
kplugin_add_syms(plugin, ksym_new("firewall_zones", infix_firewall_zones));
|
||||||
kplugin_add_syms(plugin, ksym_new("firewall_policies", infix_firewall_policies));
|
kplugin_add_syms(plugin, ksym_new("firewall_policies", infix_firewall_policies));
|
||||||
kplugin_add_syms(plugin, ksym_new("firewall_services", infix_firewall_services));
|
kplugin_add_syms(plugin, ksym_new("firewall_services", infix_firewall_services));
|
||||||
|
kplugin_add_syms(plugin, ksym_new("set_boot_order", infix_set_boot_order));
|
||||||
kplugin_add_syms(plugin, ksym_new("shell", infix_shell));
|
kplugin_add_syms(plugin, ksym_new("shell", infix_shell));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -134,6 +134,13 @@
|
|||||||
<ACTION sym="STRING"/>
|
<ACTION sym="STRING"/>
|
||||||
</PTYPE>
|
</PTYPE>
|
||||||
|
|
||||||
|
<PTYPE name="BOOT_TARGET">
|
||||||
|
<COMPL>
|
||||||
|
<ACTION sym="boot_targets@infix"/>
|
||||||
|
</COMPL>
|
||||||
|
<ACTION sym="STRING"/>
|
||||||
|
</PTYPE>
|
||||||
|
|
||||||
<VIEW name="main">
|
<VIEW name="main">
|
||||||
<HOTKEY key="^D" cmd="exit"/>
|
<HOTKEY key="^D" cmd="exit"/>
|
||||||
|
|
||||||
@@ -243,6 +250,13 @@
|
|||||||
<PARAM name="current-datetime" ptype="/STRING" help="yyyy-mm-ddThh:mm:ss(Z|+/-hh:mm)"/>
|
<PARAM name="current-datetime" ptype="/STRING" help="yyyy-mm-ddThh:mm:ss(Z|+/-hh:mm)"/>
|
||||||
<ACTION sym="srp_rpc@sysrepo">/ietf-system:set-current-datetime</ACTION>
|
<ACTION sym="srp_rpc@sysrepo">/ietf-system:set-current-datetime</ACTION>
|
||||||
</COMMAND>
|
</COMMAND>
|
||||||
|
|
||||||
|
<COMMAND name="boot-order" help="Set boot partition order">
|
||||||
|
<PARAM name="first" ptype="/BOOT_TARGET" help="First boot target"/>
|
||||||
|
<PARAM name="second" ptype="/BOOT_TARGET" help="Second boot target" min="0"/>
|
||||||
|
<PARAM name="third" ptype="/BOOT_TARGET" help="Third boot target" min="0"/>
|
||||||
|
<ACTION sym="set_boot_order@infix"/>
|
||||||
|
</COMMAND>
|
||||||
</COMMAND>
|
</COMMAND>
|
||||||
|
|
||||||
<COMMAND name="dhcp-server" help="DHCP server tools" mode="switch">
|
<COMMAND name="dhcp-server" help="DHCP server tools" mode="switch">
|
||||||
@@ -353,6 +367,12 @@
|
|||||||
</ACTION>
|
</ACTION>
|
||||||
</COMMAND>
|
</COMMAND>
|
||||||
|
|
||||||
|
<COMMAND name="boot-order" help="Show boot partition order">
|
||||||
|
<ACTION sym="script">
|
||||||
|
show boot-order
|
||||||
|
</ACTION>
|
||||||
|
</COMMAND>
|
||||||
|
|
||||||
<COMMAND name="system" help="Show system overview">
|
<COMMAND name="system" help="Show system overview">
|
||||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
<ACTION sym="script" in="tty" out="tty" interrupt="true">
|
||||||
show system |pager
|
show system |pager
|
||||||
|
|||||||
@@ -142,6 +142,19 @@ def software(args: List[str]) -> None:
|
|||||||
else:
|
else:
|
||||||
print("Too many arguments provided. Only one name is expected.")
|
print("Too many arguments provided. Only one name is expected.")
|
||||||
|
|
||||||
|
def boot_order(args: List[str]) -> None:
|
||||||
|
data = run_sysrepocfg("/ietf-system:system-state/infix-system:software")
|
||||||
|
if not data:
|
||||||
|
print("No software data retrieved.")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
boot_order_list = data.get("ietf-system:system-state", {}).get("infix-system:software", {}).get("boot-order", [])
|
||||||
|
if boot_order_list:
|
||||||
|
print(" ".join(boot_order_list))
|
||||||
|
except (KeyError, TypeError):
|
||||||
|
print("No boot order data available.")
|
||||||
|
|
||||||
def services(args: List[str]) -> None:
|
def services(args: List[str]) -> None:
|
||||||
data = run_sysrepocfg("/ietf-system:system-state/infix-system:services")
|
data = run_sysrepocfg("/ietf-system:system-state/infix-system:services")
|
||||||
if not data:
|
if not data:
|
||||||
@@ -425,6 +438,7 @@ def system(args: List[str]) -> None:
|
|||||||
def execute_command(command: str, args: List[str]):
|
def execute_command(command: str, args: List[str]):
|
||||||
command_mapping = {
|
command_mapping = {
|
||||||
'bfd': bfd,
|
'bfd': bfd,
|
||||||
|
'boot-order': boot_order,
|
||||||
'dhcp': dhcp,
|
'dhcp': dhcp,
|
||||||
'hardware': hardware,
|
'hardware': hardware,
|
||||||
'interface': interface,
|
'interface': interface,
|
||||||
|
|||||||
@@ -247,14 +247,14 @@ with infamy.Test() as test:
|
|||||||
west_ns.addip(PC_WEST_HOST)
|
west_ns.addip(PC_WEST_HOST)
|
||||||
west_ns.addroute("default", PC_WEST_R1)
|
west_ns.addroute("default", PC_WEST_R1)
|
||||||
|
|
||||||
# Send 3 pings with TTL=3, TTL is decremented before each
|
# Send 10 pings with TTL=3, TTL is decremented before each
|
||||||
# router hop. So at PC:west (TTL=3) -> R1 routed to GRE
|
# router hop. So at PC:west (TTL=3) -> R1 routed to GRE
|
||||||
# tunnel (TTL=2) -> frame egresses tunnel -> R3 where it
|
# tunnel (TTL=2) -> frame egresses tunnel -> R3 where it
|
||||||
# is routed to PC:east (TTL=1).
|
# is routed to PC:east (TTL=1).
|
||||||
#
|
#
|
||||||
# If outer TTL was inherited (TTL=2), packet would be
|
# If outer TTL was inherited (TTL=2), packet would be
|
||||||
# dropped at R3.
|
# dropped at R3.
|
||||||
west_ns.runsh(f"ping -c 3 -t {TEST_TTL} {PC_EAST_HOST}")
|
west_ns.runsh(f"ping -c 10 -t {TEST_TTL} {PC_EAST_HOST}")
|
||||||
|
|
||||||
with test.step("Verify packets arrived at PC:east"):
|
with test.step("Verify packets arrived at PC:east"):
|
||||||
packets = pcap.tcpdump()
|
packets = pcap.tcpdump()
|
||||||
|
|||||||
Reference in New Issue
Block a user