Line data Source code
1 : #include "configure.h"
2 : #include "../../../platform/fd_file_util.h"
3 : #include "../../../../disco/net/fd_linux_bond.h"
4 :
5 : #include <errno.h>
6 :
7 0 : #define NAME "bonding"
8 :
9 0 : #define TARGET_DELAY_MS (5000UL)
10 :
11 : static int
12 0 : enabled( fd_config_t const * config ) {
13 0 : return 0==strcmp( config->net.provider, "xdp" ) &&
14 0 : config->net.xdp.native_bond &&
15 0 : fd_bonding_is_master( config->net.interface );
16 0 : }
17 :
18 : static void
19 : init_perm( fd_cap_chk_t * chk,
20 0 : fd_config_t const * config FD_PARAM_UNUSED ) {
21 0 : fd_cap_chk_root( chk, NAME, "modify bond network device configuration with sysfs" );
22 0 : }
23 :
24 : static void
25 0 : init( fd_config_t const * config ) {
26 :
27 0 : if( FD_UNLIKELY( !fd_bonding_is_master( config->net.interface ) ) ) {
28 0 : return;
29 0 : }
30 :
31 0 : char path[ PATH_MAX ];
32 0 : char * end = path+sizeof(path);
33 0 : char * p = fd_cstr_init( path );
34 0 : p = fd_cstr_append_cstr( p, "/sys/class/net/" );
35 0 : FD_TEST( p+strlen( config->net.interface )<end );
36 0 : p = fd_cstr_append_cstr( p, config->net.interface );
37 0 : FD_TEST( p+strlen( "/bonding/" )+32<end );
38 0 : p = fd_cstr_append_cstr( p, "/bonding/" );
39 :
40 : /* Raise bonding driver action delays to prevent XDP config changes
41 : from bringing down bond slaves. */
42 :
43 0 : fd_cstr_fini( fd_cstr_append_cstr( p, "miimon" ) );
44 0 : FD_LOG_NOTICE(( "RUN: `echo %lu | sudo tee %s`", TARGET_DELAY_MS, path ));
45 0 : fd_file_util_write_ulong( path, TARGET_DELAY_MS );
46 :
47 0 : fd_cstr_fini( fd_cstr_append_cstr( p, "downdelay" ) );
48 0 : FD_LOG_NOTICE(( "RUN: `echo %lu | sudo tee %s`", TARGET_DELAY_MS, path ));
49 0 : fd_file_util_write_ulong( path, TARGET_DELAY_MS );
50 :
51 0 : fd_cstr_fini( fd_cstr_append_cstr( p, "peer_notif_delay" ) );
52 0 : FD_LOG_NOTICE(( "RUN: `echo %lu | sudo tee %s`", TARGET_DELAY_MS, path ));
53 0 : fd_file_util_write_ulong( path, TARGET_DELAY_MS );
54 0 : }
55 :
56 : static configure_result_t
57 : check( fd_config_t const * config,
58 0 : int check_type ) {
59 0 : (void)check_type;
60 :
61 0 : if( FD_UNLIKELY( !fd_bonding_is_master( config->net.interface ) ) ) {
62 0 : CONFIGURE_OK();
63 0 : }
64 :
65 0 : char path[ PATH_MAX ];
66 0 : char * end = path+sizeof(path);
67 0 : char * p = fd_cstr_init( path );
68 0 : p = fd_cstr_append_cstr( p, "/sys/class/net/" );
69 0 : FD_TEST( p+strlen( config->net.interface )<end );
70 0 : p = fd_cstr_append_cstr( p, config->net.interface );
71 0 : FD_TEST( p+strlen( "/bonding/" )+32<end );
72 0 : p = fd_cstr_append_cstr( p, "/bonding/" );
73 :
74 0 : ulong value;
75 0 : # define READ_NODE( name ) __extension__({ \
76 0 : fd_cstr_fini( fd_cstr_append_cstr( p, name ) ); \
77 0 : int res = fd_file_util_read_ulong( path, &value ); \
78 0 : if( FD_UNLIKELY( res ) ) { \
79 0 : FD_LOG_ERR(( "Failed to read %s%s (%i-%s)", \
80 0 : path, name, errno, fd_io_strerror( errno ) )); \
81 0 : } \
82 0 : value; \
83 0 : })
84 0 : ulong miimon = READ_NODE( "miimon" );
85 0 : ulong downdelay = READ_NODE( "downdelay" );
86 0 : ulong peer_notif_delay = READ_NODE( "peer_notif_delay" );
87 0 : # undef READ_NODE
88 :
89 0 : if( miimon<TARGET_DELAY_MS ) {
90 0 : NOT_CONFIGURED( "/sys/class/net/%s/bonding/miimon is %lums, want at least %lums",
91 0 : config->net.interface, miimon, TARGET_DELAY_MS );
92 0 : }
93 0 : if( downdelay<TARGET_DELAY_MS ) {
94 0 : NOT_CONFIGURED( "/sys/class/net/%s/bonding/downdelay is %lums, want at least %lums",
95 0 : config->net.interface, downdelay, TARGET_DELAY_MS );
96 0 : }
97 0 : if( peer_notif_delay<TARGET_DELAY_MS ) {
98 0 : NOT_CONFIGURED( "/sys/class/net/%s/bonding/peer_notif_delay is %lums, want at least %lums",
99 0 : config->net.interface, peer_notif_delay, TARGET_DELAY_MS );
100 0 : }
101 :
102 0 : CONFIGURE_OK();
103 0 : }
104 :
105 : configure_stage_t fd_cfg_stage_bonding = {
106 : .name = NAME,
107 : .always_recreate = 0,
108 : .enabled = enabled,
109 : .init_perm = init_perm,
110 : .init = init,
111 : .check = check,
112 : };
113 :
114 : #undef NAME
|