You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

xfer.h 7.8KB

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