1 #ifndef _GPXE_XFER_H 2 #define _GPXE_XFER_H 3 4 /** @file 5 * 6 * Data transfer interfaces 7 * 8 */ 9 10 FILE_LICENCE ( GPL2_OR_LATER ); 11 12 #include <stddef.h> 13 #include <stdarg.h> 14 #include <gpxe/interface.h> 15 #include <gpxe/iobuf.h> 16 17 struct xfer_interface; 18 struct xfer_metadata; 19 20 /** Data transfer interface operations */ 21 struct xfer_interface_operations { 22 /** Close interface 23 * 24 * @v xfer Data transfer interface 25 * @v rc Reason for close 26 */ 27 void ( * close ) ( struct xfer_interface *xfer, int rc ); 28 /** Redirect to new location 29 * 30 * @v xfer Data transfer interface 31 * @v type New location type 32 * @v args Remaining arguments depend upon location type 33 * @ret rc Return status code 34 */ 35 int ( * vredirect ) ( struct xfer_interface *xfer, int type, 36 va_list args ); 37 /** Check flow control window 38 * 39 * @v xfer Data transfer interface 40 * @ret len Length of window 41 * 42 * Flow control is regarded as advisory but not mandatory. 43 * Users who have control over their own rate of data 44 * generation should perform a flow control check before 45 * generating new data. Users who have no control (such as 46 * NIC drivers or filter layers) are not obliged to check. 47 * 48 * Data transfer interfaces must be prepared to accept 49 * datagrams even if they are advertising a window of zero 50 * bytes. 51 */ 52 size_t ( * window ) ( struct xfer_interface *xfer ); 53 /** Allocate I/O buffer 54 * 55 * @v xfer Data transfer interface 56 * @v len I/O buffer payload length 57 * @ret iobuf I/O buffer 58 */ 59 struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer, 60 size_t len ); 61 /** Deliver datagram as I/O buffer with metadata 62 * 63 * @v xfer Data transfer interface 64 * @v iobuf Datagram I/O buffer 65 * @v meta Data transfer metadata 66 * @ret rc Return status code 67 * 68 * A data transfer interface that wishes to support only raw 69 * data delivery should set this method to 70 * xfer_deliver_as_raw(). 71 */ 72 int ( * deliver_iob ) ( struct xfer_interface *xfer, 73 struct io_buffer *iobuf, 74 struct xfer_metadata *meta ); 75 /** Deliver datagram as raw data 76 * 77 * @v xfer Data transfer interface 78 * @v data Data buffer 79 * @v len Length of data buffer 80 * @ret rc Return status code 81 * 82 * A data transfer interface that wishes to support only I/O 83 * buffer delivery should set this method to 84 * xfer_deliver_as_iob(). 85 */ 86 int ( * deliver_raw ) ( struct xfer_interface *xfer, 87 const void *data, size_t len ); 88 }; 89 90 /** A data transfer interface */ 91 struct xfer_interface { 92 /** Generic object communication interface */ 93 struct interface intf; 94 /** Operations for received messages */ 95 struct xfer_interface_operations *op; 96 }; 97 98 /** Basis positions for seek() events */ 99 enum seek_whence { 100 SEEK_CUR = 0, 101 SEEK_SET, 102 }; 103 104 /** Data transfer metadata */ 105 struct xfer_metadata { 106 /** Position of data within stream */ 107 off_t offset; 108 /** Basis for data position 109 * 110 * Must be one of @c SEEK_CUR or @c SEEK_SET. 111 */ 112 int whence; 113 /** Source socket address, or NULL */ 114 struct sockaddr *src; 115 /** Destination socket address, or NULL */ 116 struct sockaddr *dest; 117 /** Network device, or NULL */ 118 struct net_device *netdev; 119 }; 120 121 /** 122 * Describe seek basis 123 * 124 * @v whence Basis for new position 125 */ 126 static inline __attribute__ (( always_inline )) const char * 127 whence_text ( int whence ) { 128 switch ( whence ) { 129 case SEEK_CUR: return "CUR"; 130 case SEEK_SET: return "SET"; 131 default: return "INVALID"; 132 } 133 } 134 135 extern struct xfer_interface null_xfer; 136 extern struct xfer_interface_operations null_xfer_ops; 137 138 extern void xfer_close ( struct xfer_interface *xfer, int rc ); 139 extern int xfer_vredirect ( struct xfer_interface *xfer, int type, 140 va_list args ); 141 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... ); 142 extern size_t xfer_window ( struct xfer_interface *xfer ); 143 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, 144 size_t len ); 145 extern int xfer_deliver_iob ( struct xfer_interface *xfer, 146 struct io_buffer *iobuf ); 147 extern int xfer_deliver_iob_meta ( struct xfer_interface *xfer, 148 struct io_buffer *iobuf, 149 struct xfer_metadata *meta ); 150 extern int xfer_deliver_raw ( struct xfer_interface *xfer, 151 const void *data, size_t len ); 152 extern int xfer_vprintf ( struct xfer_interface *xfer, 153 const char *format, va_list args ); 154 extern int __attribute__ (( format ( printf, 2, 3 ) )) 155 xfer_printf ( struct xfer_interface *xfer, const char *format, ... ); 156 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ); 157 158 extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc ); 159 extern int ignore_xfer_vredirect ( struct xfer_interface *xfer, 160 int type, va_list args ); 161 extern size_t unlimited_xfer_window ( struct xfer_interface *xfer ); 162 extern size_t no_xfer_window ( struct xfer_interface *xfer ); 163 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer, 164 size_t len ); 165 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer, 166 struct io_buffer *iobuf, 167 struct xfer_metadata *meta ); 168 extern int xfer_deliver_as_iob ( struct xfer_interface *xfer, 169 const void *data, size_t len ); 170 extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer, 171 const void *data __unused, size_t len ); 172 173 /** 174 * Initialise a data transfer interface 175 * 176 * @v xfer Data transfer interface 177 * @v op Data transfer interface operations 178 * @v refcnt Containing object reference counter, or NULL 179 */ 180 static inline void xfer_init ( struct xfer_interface *xfer, 181 struct xfer_interface_operations *op, 182 struct refcnt *refcnt ) { 183 xfer->intf.dest = &null_xfer.intf; 184 xfer->intf.refcnt = refcnt; 185 xfer->op = op; 186 } 187 188 /** 189 * Initialise a static data transfer interface 190 * 191 * @v operations Data transfer interface operations 192 */ 193 #define XFER_INIT( operations ) { \ 194 .intf = { \ 195 .dest = &null_xfer.intf, \ 196 .refcnt = NULL, \ 197 }, \ 198 .op = operations, \ 199 } 200 201 /** 202 * Get data transfer interface from generic object communication interface 203 * 204 * @v intf Generic object communication interface 205 * @ret xfer Data transfer interface 206 */ 207 static inline __attribute__ (( always_inline )) struct xfer_interface * 208 intf_to_xfer ( struct interface *intf ) { 209 return container_of ( intf, struct xfer_interface, intf ); 210 } 211 212 /** 213 * Get reference to destination data transfer interface 214 * 215 * @v xfer Data transfer interface 216 * @ret dest Destination interface 217 */ 218 static inline __attribute__ (( always_inline )) struct xfer_interface * 219 xfer_get_dest ( struct xfer_interface *xfer ) { 220 return intf_to_xfer ( intf_get ( xfer->intf.dest ) ); 221 } 222 223 /** 224 * Drop reference to data transfer interface 225 * 226 * @v xfer Data transfer interface 227 */ 228 static inline __attribute__ (( always_inline )) void 229 xfer_put ( struct xfer_interface *xfer ) { 230 intf_put ( &xfer->intf ); 231 } 232 233 /** 234 * Plug a data transfer interface into a new destination interface 235 * 236 * @v xfer Data transfer interface 237 * @v dest New destination interface 238 */ 239 static inline __attribute__ (( always_inline )) void 240 xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) { 241 plug ( &xfer->intf, &dest->intf ); 242 } 243 244 /** 245 * Plug two data transfer interfaces together 246 * 247 * @v a Data transfer interface A 248 * @v b Data transfer interface B 249 */ 250 static inline __attribute__ (( always_inline )) void 251 xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) { 252 plug_plug ( &a->intf, &b->intf ); 253 } 254 255 /** 256 * Unplug a data transfer interface 257 * 258 * @v xfer Data transfer interface 259 */ 260 static inline __attribute__ (( always_inline )) void 261 xfer_unplug ( struct xfer_interface *xfer ) { 262 plug ( &xfer->intf, &null_xfer.intf ); 263 } 264 265 /** 266 * Stop using a data transfer interface 267 * 268 * @v xfer Data transfer interface 269 * 270 * After calling this method, no further messages will be received via 271 * the interface. 272 */ 273 static inline void xfer_nullify ( struct xfer_interface *xfer ) { 274 xfer->op = &null_xfer_ops; 275 }; 276 277 #endif /* _GPXE_XFER_H */ 278