Line data Source code
1 : #include "fd_netdev_tbl.h"
2 : #include "../../util/fd_util.h"
3 :
4 : struct fd_netdev_tbl_private {
5 : ulong magic;
6 : ulong dev_off;
7 : ulong bond_off;
8 : fd_netdev_tbl_hdr_t hdr;
9 : };
10 :
11 : FD_FN_CONST ulong
12 12 : fd_netdev_tbl_align( void ) {
13 12 : return FD_NETDEV_TBL_ALIGN;
14 12 : }
15 :
16 : FD_FN_CONST ulong
17 : fd_netdev_tbl_footprint( ulong dev_max,
18 12 : ulong bond_max ) {
19 12 : if( FD_UNLIKELY( dev_max ==0UL || dev_max >USHORT_MAX ) ) return 0UL;
20 12 : if( FD_UNLIKELY( bond_max==0UL || bond_max>USHORT_MAX ) ) return 0UL;
21 12 : return FD_LAYOUT_FINI( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_INIT, \
22 12 : alignof(fd_netdev_tbl_t), sizeof(fd_netdev_tbl_t) ), \
23 12 : alignof(fd_netdev_t), sizeof(fd_netdev_t) * dev_max ), \
24 12 : alignof(fd_netdev_bond_t), sizeof(fd_netdev_bond_t) * bond_max ), \
25 12 : FD_NETDEV_TBL_ALIGN );
26 12 : }
27 :
28 : void *
29 : fd_netdev_tbl_new( void * shmem,
30 : ulong dev_max,
31 9 : ulong bond_max ) {
32 :
33 9 : if( FD_UNLIKELY( !shmem ) ) {
34 0 : FD_LOG_WARNING(( "NULL shmem" ));
35 0 : return NULL;
36 0 : }
37 :
38 9 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, FD_NETDEV_TBL_ALIGN ) ) ) {
39 0 : FD_LOG_WARNING(( "misaligned shmem" ));
40 0 : return NULL;
41 0 : }
42 :
43 9 : if( FD_UNLIKELY( !dev_max || dev_max>USHORT_MAX ) ) {
44 0 : FD_LOG_WARNING(( "invalid dev_max" ));
45 0 : return NULL;
46 0 : }
47 :
48 9 : if( FD_UNLIKELY( !bond_max || bond_max>USHORT_MAX ) ) {
49 0 : FD_LOG_WARNING(( "invalid bond_max" ));
50 0 : return NULL;
51 0 : }
52 :
53 9 : FD_SCRATCH_ALLOC_INIT( l, shmem );
54 9 : fd_netdev_tbl_t * tbl = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_netdev_tbl_t), sizeof(fd_netdev_tbl_t) );
55 9 : fd_netdev_t * dev = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_netdev_t), sizeof(fd_netdev_t) * dev_max );
56 9 : fd_netdev_bond_t * bond = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_netdev_bond_t), sizeof(fd_netdev_bond_t) * bond_max );
57 9 : FD_SCRATCH_ALLOC_FINI( l, FD_NETDEV_TBL_ALIGN );
58 :
59 9 : *tbl = (fd_netdev_tbl_t) {
60 9 : .magic = FD_NETDEV_TBL_MAGIC,
61 9 : .dev_off = (ulong)dev - (ulong)tbl,
62 9 : .bond_off = (ulong)bond - (ulong)tbl,
63 9 : .hdr = {
64 9 : .dev_max = (ushort)dev_max,
65 9 : .bond_max = (ushort)bond_max,
66 9 : .dev_cnt = 0,
67 9 : .bond_cnt = 0,
68 9 : }
69 9 : };
70 :
71 9 : fd_netdev_tbl_join_t join[1];
72 9 : fd_netdev_tbl_join( join, shmem );
73 9 : fd_netdev_tbl_reset( join );
74 9 : fd_netdev_tbl_leave( join );
75 :
76 9 : return tbl;
77 9 : }
78 :
79 : fd_netdev_tbl_join_t *
80 : fd_netdev_tbl_join( void * ljoin,
81 18 : void * shtbl ) {
82 :
83 18 : if( FD_UNLIKELY( !shtbl ) ) {
84 0 : FD_LOG_WARNING(( "NULL shtbl" ));
85 0 : return NULL;
86 0 : }
87 :
88 18 : fd_netdev_tbl_join_t * join = ljoin;
89 18 : fd_netdev_tbl_t * tbl = shtbl;
90 :
91 18 : if( FD_UNLIKELY( tbl->magic!=FD_NETDEV_TBL_MAGIC ) ) {
92 0 : FD_LOG_WARNING(( "bad magic" ));
93 0 : return NULL;
94 0 : }
95 :
96 18 : *join = (fd_netdev_tbl_join_t) {
97 18 : .hdr = &tbl->hdr,
98 18 : .dev_tbl = (fd_netdev_t *)( (ulong)tbl + tbl->dev_off ),
99 18 : .bond_tbl = (fd_netdev_bond_t *)( (ulong)tbl + tbl->bond_off ),
100 18 : };
101 :
102 18 : return join;
103 18 : }
104 :
105 : void *
106 12 : fd_netdev_tbl_leave( fd_netdev_tbl_join_t * join ) {
107 12 : return join;
108 12 : }
109 :
110 : void *
111 3 : fd_netdev_tbl_delete( void * shtbl ) {
112 :
113 3 : if( FD_UNLIKELY( !shtbl ) ) {
114 0 : FD_LOG_WARNING(( "NULL shtbl" ));
115 0 : return NULL;
116 0 : }
117 :
118 3 : fd_netdev_tbl_t * tbl = shtbl;
119 3 : tbl->magic = 0UL;
120 3 : return tbl;
121 3 : }
122 :
123 : void
124 9 : fd_netdev_tbl_reset( fd_netdev_tbl_join_t * tbl ) {
125 9 : tbl->hdr->dev_cnt = 0;
126 9 : tbl->hdr->bond_cnt = 0;
127 1554 : for( ulong j=0UL; j<(tbl->hdr->dev_max); j++ ) {
128 1545 : tbl->dev_tbl[j] = (fd_netdev_t) {
129 1545 : .master_idx = -1,
130 1545 : .slave_tbl_idx = -1
131 1545 : };
132 1545 : }
133 9 : fd_memset( tbl->bond_tbl, 0, sizeof(fd_netdev_bond_t) * tbl->hdr->bond_max );
134 9 : }
135 :
136 : void
137 : fd_netdev_tbl_copy( fd_netdev_tbl_join_t * dst,
138 0 : fd_netdev_tbl_join_t const * src ) {
139 0 : ushort dev_max = dst->hdr->dev_max;
140 0 : ushort bond_max = dst->hdr->bond_max;
141 0 : for(;;) {
142 0 : ulong seq = fd_seqlock_read_try( &src->hdr->seqlock );
143 0 : dst->hdr->dev_cnt = src->hdr->dev_cnt;
144 0 : dst->hdr->bond_cnt = src->hdr->bond_cnt;
145 0 : fd_memcpy( dst->dev_tbl, src->dev_tbl, sizeof(fd_netdev_t) * dev_max );
146 0 : fd_memcpy( dst->bond_tbl, src->bond_tbl, sizeof(fd_netdev_bond_t) * bond_max );
147 0 : if( FD_LIKELY( fd_seqlock_read_test( &src->hdr->seqlock, seq ) ) ) return;
148 0 : FD_SPIN_PAUSE();
149 0 : }
150 0 : }
151 :
152 : #if FD_HAS_HOSTED
153 :
154 : #include <errno.h>
155 : #include <stdio.h>
156 : #include "../../util/net/fd_eth.h"
157 :
158 6 : #define WRAP_PRINT(file,str) if( FD_UNLIKELY( fputs( (str), (file) )<0 ) ) return errno
159 12 : #define WRAP_PRINTF(file,...) if( FD_UNLIKELY( fprintf( (file), __VA_ARGS__ )<0 ) ) return errno
160 :
161 : int
162 : fd_netdev_tbl_fprintf( fd_netdev_tbl_join_t const * tbl,
163 3 : void * file_ ) {
164 3 : FILE * file = file_;
165 12 : for( ulong j=0UL; j<(tbl->hdr->dev_cnt); j++ ) {
166 9 : fd_netdev_t const * dev = &tbl->dev_tbl[j];
167 9 : if( !dev->oper_status ) continue;
168 6 : WRAP_PRINTF( file,
169 6 : "%u: %s: mtu %u state (%i-%s)",
170 6 : dev->if_idx, dev->name, dev->mtu,
171 6 : dev->oper_status, fd_oper_status_cstr( dev->oper_status ) );
172 6 : if( dev->slave_tbl_idx>=0 ) {
173 6 : WRAP_PRINT( file, " master" );
174 6 : }
175 6 : WRAP_PRINTF( file,
176 6 : "\n link " FD_ETH_MAC_FMT "\n",
177 6 : FD_ETH_MAC_FMT_ARGS( dev->mac_addr ) );
178 6 : if( dev->slave_tbl_idx>=0 && tbl->bond_tbl[ dev->slave_tbl_idx ].slave_cnt ) {
179 0 : fd_netdev_bond_t * bond = &tbl->bond_tbl[ dev->slave_tbl_idx ];
180 0 : WRAP_PRINTF( file, " slaves (%u):", bond->slave_cnt );
181 0 : for( ulong k=0UL; k<(bond->slave_cnt); k++ ) {
182 0 : WRAP_PRINTF( file, " %u-%s", bond->slave_idx[k], tbl->dev_tbl[ bond->slave_idx[k] ].name );
183 0 : }
184 0 : WRAP_PRINT( file, "\n" );
185 0 : }
186 6 : }
187 3 : return 0;
188 3 : }
189 :
190 : #undef WRAP_PRINT
191 : #undef WRAP_PRINTF
192 :
193 : #endif /* FD_HAS_HOSTED */
194 :
195 : char const *
196 6 : fd_oper_status_cstr( uint oper_status ) {
197 6 : switch( oper_status ) {
198 3 : case FD_OPER_STATUS_UP: return "up";
199 3 : case FD_OPER_STATUS_DOWN: return "down";
200 0 : case FD_OPER_STATUS_TESTING: return "testing";
201 0 : case FD_OPER_STATUS_DORMANT: return "dormant";
202 0 : case FD_OPER_STATUS_NOT_PRESENT: return "not present";
203 0 : case FD_OPER_STATUS_LOWER_LAYER_DOWN: return "lower layer down";
204 0 : case FD_OPER_STATUS_UNKNOWN: /* fallthrough */
205 0 : default:
206 0 : return "unknown";
207 6 : }
208 6 : }
|