Source code of Windows XP (NT5)
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.

575 lines
16 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. pktsched.h
  5. Abstract:
  6. defines for packet scheduler component interface
  7. Author:
  8. Revision History:
  9. --*/
  10. #ifndef _PKTSCHED_H_
  11. #define _PKTSCHED_H_
  12. //
  13. // forwards
  14. //
  15. /*
  16. typedef struct _PSI_INFO;
  17. typedef struct _PS_PROFILE;
  18. typedef struct _PS_PIPE_CONTEXT;
  19. typedef struct _PS_FLOW_CONTEXT;
  20. typedef struct _PS_DEBUG_INFO;
  21. */
  22. //
  23. // Component registration function exported by PSched
  24. //
  25. //
  26. // Context info passed to each component during pipe initialization. The PS
  27. // allocates one PS_PIPE_CONTEXT struct for each component. The size of an
  28. // individual component's struct is indicated by the component during registration,
  29. // and must be at least as large as sizeof(PS_PIPE_CONTEXT).
  30. // Each component's context area begins with the struct defined below, and the
  31. // component-specific data follows.
  32. //
  33. // Note : This structure has to be word aligned.
  34. //
  35. typedef struct _PS_PIPE_CONTEXT {
  36. // NextComponentContext - Pointer to next component's pipe-specific data
  37. // PrevComponentContext - Pointer to previous component's pipe-specific data
  38. // NextComponent - Function info about next component in pipeline
  39. // PacketReservedOffset - Offset to packet reserved bytes for this component
  40. struct _PS_PIPE_CONTEXT *NextComponentContext;
  41. struct _PS_PIPE_CONTEXT *PrevComponentContext;
  42. struct _PSI_INFO *NextComponent;
  43. ULONG PacketReservedOffset;
  44. } PS_PIPE_CONTEXT, *PPS_PIPE_CONTEXT;
  45. //
  46. // Context info passed to each component during flow initialization. The PS
  47. // allocates one PS_FLOW_CONTEXT struct for each component. The size of an
  48. // individual component's struct is indicated by the component during registration,
  49. // and must be at least as large as sizeof(PS_FLOW_CONTEXT).
  50. // Each component's context area begins with the struct defined below, and the
  51. // component-specific data follows.
  52. //
  53. typedef struct _PS_FLOW_CONTEXT {
  54. // NextComponentContext - Pointer to next component's flow-specific data
  55. // PrevComponentContext - Pointer to previous component's flow-specific data
  56. struct _PS_FLOW_CONTEXT *NextComponentContext;
  57. struct _PS_FLOW_CONTEXT *PrevComponentContext;
  58. } PS_FLOW_CONTEXT, *PPS_FLOW_CONTEXT, PS_CLASS_MAP_CONTEXT, *PPS_CLASS_MAP_CONTEXT;
  59. //
  60. // Packet Information Block. This structure can be found
  61. // at offset zero from the packet's ProtocolReserved area.
  62. //
  63. typedef struct _PACKET_INFO_BLOCK {
  64. // SchedulerLinks - Linkage in scheduling component list
  65. // PacketLength - Length of packet, non including MAC header
  66. // ConformanceTime - Token Bucket Conformance Time
  67. // DelayTime - Time at which packet is eligible for sending
  68. // FlowContext - Flow context area for the convenience of the scheduling
  69. // components. May be used by the scheduling component
  70. // while the packet is being processed by that component.
  71. // ClassMapContext - Class Map context area for convenience of scheduling
  72. // components. May be used by the scheduling component
  73. // when the packet is being processed by that component.
  74. // IpHdr - points to the IP transport header. This is used by the
  75. // sequencer to stamp the IP packet with the non conforming
  76. // TOS byte. We store a pointer here because we have already
  77. // done the dirty work of getting to the buffer in MpSend.
  78. // This will be 0 for non IP packets, in which case the
  79. // sequencer need not do anything.
  80. // IPPrecedenceByteNonConforming - The TOS setting for non conforming packets.
  81. // UserPriorityNonConforming - 802.1p setting for non conforming packets.
  82. LIST_ENTRY SchedulerLinks;
  83. ULONG PacketLength;
  84. LARGE_INTEGER ConformanceTime;
  85. LARGE_INTEGER DelayTime;
  86. HANDLE FlowContext;
  87. HANDLE ClassMapContext;
  88. ULONG IPHeaderOffset;
  89. IPHeader *IPHdr;
  90. PNDIS_PACKET NdisPacket;
  91. UCHAR TOSNonConforming;
  92. UCHAR UserPriorityNonConforming;
  93. } PACKET_INFO_BLOCK, *PPACKET_INFO_BLOCK;
  94. //
  95. // Prototypes for PS routines made available to scheduling components.
  96. //
  97. typedef VOID
  98. (*PS_DROP_PACKET)(
  99. IN HANDLE PsPipeContext,
  100. IN HANDLE PsFlowContext,
  101. IN PNDIS_PACKET Packet,
  102. IN NDIS_STATUS Status
  103. );
  104. typedef HANDLE
  105. (*PS_NDIS_PIPE_HANDLE)(
  106. IN HANDLE PsPipeContext
  107. );
  108. typedef HANDLE
  109. (*PS_NDIS_FLOW_HANDLE)(
  110. IN HANDLE PsFlowContext
  111. );
  112. typedef VOID
  113. (*PS_GET_TIMER_INFO)(
  114. OUT PULONG TimerResolution // Timer resolution in system time units
  115. );
  116. typedef struct _PS_PROCS {
  117. PS_DROP_PACKET DropPacket;
  118. PS_NDIS_PIPE_HANDLE NdisPipeHandle;
  119. PS_GET_TIMER_INFO GetTimerInfo;
  120. } PS_PROCS, *PPS_PROCS;
  121. //
  122. // Upcall information passed to next component
  123. //
  124. typedef VOID
  125. (*PSU_SEND_COMPLETE)(
  126. IN PPS_PIPE_CONTEXT PipeContext,
  127. IN PNDIS_PACKET Packet
  128. );
  129. typedef struct _PS_UPCALLS {
  130. PSU_SEND_COMPLETE SendComplete;
  131. PPS_PIPE_CONTEXT PipeContext;
  132. } PS_UPCALLS, *PPS_UPCALLS;
  133. //
  134. // Pipe parameters
  135. //
  136. typedef struct _PS_PIPE_PARAMETERS {
  137. // Bandwidth - In bytes/sec
  138. // MTUSize - Maximum frame size
  139. // HeaderSize - Number of bytes in header
  140. // Flags - See below
  141. // MaxOutstandingSends - Maximum sends that can be pending concurrently
  142. // SDModeControlledLoad - Default handling of non-conforming controlled load traffic
  143. // SDModeGuaranteed - Default handling of non-conforming guaranteed service traffic
  144. // SDModeNetworkControl - Default handling of non-conforming NetworkControl service traffic
  145. // SDModeQualitative - Default handling of non-conforming Qualitative service traffic
  146. // RegistryPath - Pointer to the registry path of that interface. Can be used to read reg params.
  147. ULONG Bandwidth;
  148. ULONG MTUSize;
  149. ULONG HeaderSize;
  150. ULONG Flags;
  151. ULONG MaxOutstandingSends;
  152. ULONG SDModeControlledLoad;
  153. ULONG SDModeGuaranteed;
  154. ULONG SDModeNetworkControl;
  155. ULONG SDModeQualitative;
  156. PNDIS_STRING RegistryPath;
  157. // Need this to let the scheduling components to know what kind of medium it is //
  158. NDIS_MEDIUM MediaType; // Wan Or anything else
  159. } PS_PIPE_PARAMETERS, *PPS_PIPE_PARAMETERS;
  160. // Pipe flags
  161. #define PS_DISABLE_DRR 2
  162. #define PS_INTERMEDIATE_SYS 4
  163. //
  164. // function typedefs for the scheduler entry points
  165. //
  166. typedef NDIS_STATUS
  167. (*PS_INITIALIZE_PIPE)(
  168. IN HANDLE PsPipeContext,
  169. IN PPS_PIPE_PARAMETERS PipeParameters,
  170. IN PPS_PIPE_CONTEXT ComponentPipeContext,
  171. IN PPS_PROCS PsProcs,
  172. IN PPS_UPCALLS Upcalls
  173. );
  174. typedef NDIS_STATUS
  175. (*PS_MODIFY_PIPE)(
  176. IN PPS_PIPE_CONTEXT PipeContext,
  177. IN PPS_PIPE_PARAMETERS PipeParameters
  178. );
  179. typedef VOID
  180. (*PS_DELETE_PIPE)(
  181. IN PPS_PIPE_CONTEXT PipeContext
  182. );
  183. typedef NDIS_STATUS
  184. (*PS_CREATE_FLOW)(
  185. IN PPS_PIPE_CONTEXT PipeContext,
  186. IN HANDLE PsFlowContext,
  187. IN PCO_CALL_PARAMETERS CallParameters,
  188. IN PPS_FLOW_CONTEXT ComponentFlowContext
  189. );
  190. typedef NDIS_STATUS
  191. (*PS_MODIFY_FLOW)(
  192. IN PPS_PIPE_CONTEXT PipeContext,
  193. IN PPS_FLOW_CONTEXT FlowContext,
  194. IN PCO_CALL_PARAMETERS CallParameters
  195. );
  196. typedef VOID
  197. (*PS_DELETE_FLOW)(
  198. IN PPS_PIPE_CONTEXT PipeContext,
  199. IN PPS_FLOW_CONTEXT FlowContext
  200. );
  201. typedef VOID
  202. (*PS_EMPTY_FLOW)(
  203. IN PPS_PIPE_CONTEXT PipeContext,
  204. IN PPS_FLOW_CONTEXT FlowContext
  205. );
  206. typedef BOOLEAN
  207. (*PS_SUBMIT_PACKET)(
  208. IN PPS_PIPE_CONTEXT PipeContext,
  209. IN PPS_FLOW_CONTEXT FlowContext,
  210. IN PPS_CLASS_MAP_CONTEXT ClassMapContext,
  211. IN PPACKET_INFO_BLOCK PktInfo);
  212. typedef BOOLEAN
  213. (*PS_RECEIVE_PACKET)(
  214. IN PPS_PIPE_CONTEXT PipeContext,
  215. IN PPS_FLOW_CONTEXT FlowContext,
  216. IN PPS_CLASS_MAP_CONTEXT ClassMapContext,
  217. IN PNDIS_PACKET Packet,
  218. IN NDIS_MEDIUM Medium
  219. );
  220. typedef BOOLEAN
  221. (*PS_RECEIVE_INDICATION)(
  222. IN PPS_PIPE_CONTEXT PipeContext,
  223. IN PPS_FLOW_CONTEXT FlowContext,
  224. IN PPS_CLASS_MAP_CONTEXT ClassMapContext,
  225. IN PVOID HeaderBuffer,
  226. IN UINT HeaderBufferSize,
  227. IN PVOID LookAheadBuffer,
  228. IN UINT LookAheadBufferSize,
  229. IN UINT PacketSize,
  230. IN UINT TransportHeaderOffset
  231. );
  232. typedef VOID
  233. (*PS_SET_INFORMATION) (
  234. IN PPS_PIPE_CONTEXT PipeContext,
  235. IN PPS_FLOW_CONTEXT FlowContext,
  236. IN NDIS_OID Oid,
  237. IN ULONG BufferSize,
  238. IN PVOID Buffer
  239. );
  240. typedef VOID
  241. (*PS_QUERY_INFORMATION) (
  242. IN PPS_PIPE_CONTEXT PipeContext,
  243. IN PPS_FLOW_CONTEXT FlowContext,
  244. IN NDIS_OID Oid,
  245. IN ULONG BufferSize,
  246. IN PVOID Buffer,
  247. IN OUT PULONG BytesWritten,
  248. IN OUT PULONG BytesNeeded,
  249. IN OUT PNDIS_STATUS Status);
  250. typedef NDIS_STATUS
  251. (*PS_CREATE_CLASS_MAP) (
  252. IN PPS_PIPE_CONTEXT PipeContext,
  253. IN HANDLE PsClassMapContext,
  254. IN PTC_CLASS_MAP_FLOW ClassMap,
  255. IN PPS_CLASS_MAP_CONTEXT ComponentClassMapContext
  256. );
  257. typedef NDIS_STATUS
  258. (*PS_DELETE_CLASS_MAP) (
  259. IN PPS_PIPE_CONTEXT PipeContext,
  260. IN PPS_CLASS_MAP_CONTEXT
  261. );
  262. /* End Prototypes */
  263. //
  264. // Scheduling component registration structure.
  265. //
  266. #define PS_COMPONENT_CURRENT_VERSION 1
  267. typedef struct _PSI_INFO {
  268. LIST_ENTRY Links;
  269. BOOLEAN Registered;
  270. BOOLEAN AddIn;
  271. USHORT Version;
  272. NDIS_STRING ComponentName;
  273. ULONG PacketReservedLength;
  274. ULONG PipeContextLength;
  275. ULONG FlowContextLength;
  276. ULONG ClassMapContextLength;
  277. ULONG SupportedOidsLength;
  278. NDIS_OID *SupportedOidList;
  279. ULONG SupportedGuidsLength;
  280. NDIS_GUID *SupportedGuidList;
  281. PS_INITIALIZE_PIPE InitializePipe;
  282. PS_MODIFY_PIPE ModifyPipe;
  283. PS_DELETE_PIPE DeletePipe;
  284. PS_CREATE_FLOW CreateFlow;
  285. PS_MODIFY_FLOW ModifyFlow;
  286. PS_DELETE_FLOW DeleteFlow;
  287. PS_EMPTY_FLOW EmptyFlow;
  288. PS_SUBMIT_PACKET SubmitPacket;
  289. PS_RECEIVE_PACKET ReceivePacket;
  290. PS_RECEIVE_INDICATION ReceiveIndication;
  291. PS_SET_INFORMATION SetInformation;
  292. PS_QUERY_INFORMATION QueryInformation;
  293. PS_CREATE_CLASS_MAP CreateClassMap;
  294. PS_DELETE_CLASS_MAP DeleteClassMap;
  295. } PSI_INFO, *PPSI_INFO;
  296. //
  297. // Profile registration structure
  298. //
  299. #define MAX_COMPONENT_PER_PROFILE 10
  300. typedef struct _PS_PROFILE {
  301. LIST_ENTRY Links;
  302. USHORT UnregisteredAddInCnt;
  303. NDIS_STRING ProfileName;
  304. UINT ComponentCnt;
  305. // Allocate an extra slot for the StubComponent
  306. PPSI_INFO ComponentList[MAX_COMPONENT_PER_PROFILE + 1];
  307. } PS_PROFILE, *PPS_PROFILE;
  308. //
  309. // Debugging support for add-in components
  310. //
  311. typedef VOID
  312. (*PS_GET_CURRENT_TIME) (PLARGE_INTEGER SysTime);
  313. typedef VOID
  314. (*PS_LOGSTRING_PROC) (
  315. IN char *format,
  316. ...
  317. );
  318. typedef VOID
  319. (*PS_LOGSCHED_PROC) (
  320. IN ULONG SchedulerComponent,
  321. IN ULONG Action,
  322. IN PVOID VC,
  323. IN PNDIS_PACKET Packet,
  324. IN ULONG PacketLength,
  325. IN ULONG Priority,
  326. IN LONGLONG ArrivalTime,
  327. IN LONGLONG ConformanceTime,
  328. IN ULONG PacketsInComponent,
  329. IN ULONG BytesInComponent
  330. );
  331. typedef VOID
  332. (*PS_LOGREC_PROC) (
  333. IN ULONG ComponentId,
  334. IN PVOID RecordData,
  335. IN ULONG RecordLength
  336. );
  337. typedef ULONG
  338. (*PS_GETID_PROC) (
  339. VOID);
  340. typedef struct _PS_DEBUG_INFO {
  341. PULONG DebugLevel;
  342. PULONG DebugMask;
  343. PULONG LogTraceLevel;
  344. PULONG LogTraceMask;
  345. ULONG LogId;
  346. PS_GET_CURRENT_TIME GetCurrentTime;
  347. PS_LOGSTRING_PROC LogString;
  348. PS_LOGSCHED_PROC LogSched;
  349. PS_LOGREC_PROC LogRec;
  350. } PS_DEBUG_INFO, *PPS_DEBUG_INFO;
  351. NDIS_STATUS RegisterPsComponent( PPSI_INFO PsiComponentInfo, ULONG Size ,
  352. PPS_DEBUG_INFO Dbg);
  353. //
  354. // VOID
  355. // InsertEntryList(
  356. // PLIST_ENTRY Entry,
  357. // PLIST_ENTRY EntryToInsert
  358. // );
  359. //
  360. // insert EntryToInsert just after Entry
  361. //
  362. #define InsertEntryList( Entry, EntryToInsert ) { \
  363. (EntryToInsert)->Flink = (Entry)->Flink; \
  364. (Entry)->Flink = (EntryToInsert); \
  365. (EntryToInsert)->Blink = (EntryToInsert)->Flink->Blink; \
  366. (EntryToInsert)->Flink->Blink = (EntryToInsert); \
  367. }
  368. #define ARP_802_ADDR_LENGTH 6 // Length of an 802 address.
  369. #define ARP_ETYPE_IP 0x800
  370. typedef struct _ETH_HEADER {
  371. UCHAR DestAddr[ARP_802_ADDR_LENGTH];
  372. UCHAR SrcAddr[ARP_802_ADDR_LENGTH];
  373. USHORT Type;
  374. } ETH_HEADER, *PETH_HEADER;
  375. _inline
  376. IPHeader *
  377. GetIpHeader(ULONG TransportHeaderOffset, PNDIS_PACKET pNdisPacket)
  378. {
  379. PVOID pAddr;
  380. PNDIS_BUFFER pNdisBuf1, pNdisBuf2;
  381. UINT Len;
  382. pNdisBuf1 = pNdisPacket->Private.Head;
  383. NdisQueryBuffer(pNdisBuf1, &pAddr, &Len);
  384. while(Len <= TransportHeaderOffset) {
  385. //
  386. // Transport header is not in this buffer,
  387. // try the next buffer
  388. //
  389. TransportHeaderOffset -= Len;
  390. NdisGetNextBuffer(pNdisBuf1, &pNdisBuf2);
  391. ASSERT(pNdisBuf2);
  392. NdisQueryBuffer(pNdisBuf2, &pAddr, &Len);
  393. pNdisBuf1 = pNdisBuf2;
  394. }
  395. return (IPHeader *)(((PUCHAR)pAddr) + TransportHeaderOffset);
  396. }
  397. //
  398. // Set TOS byte and recalculate checksum
  399. // Use incremental checksum update
  400. // RFCs 1071, 1141, 1624
  401. //
  402. //
  403. // RFC : 1624
  404. // HC' = ~(~HC + ~m + m');
  405. // HC - old checksum, m - old value, m' - new value
  406. //
  407. #define SET_TOS_XSUM(Packet, pIpHdr, tos) { \
  408. PNDIS_PACKET_EXTENSION _PktExt; \
  409. NDIS_TCP_IP_CHECKSUM_PACKET_INFO _ChkPI; \
  410. _PktExt = NDIS_PACKET_EXTENSION_FROM_PACKET((Packet)); \
  411. _ChkPI.Value = PtrToUlong(_PktExt->NdisPacketInfo[TcpIpChecksumPacketInfo]); \
  412. if(_ChkPI.Transmit.NdisPacketIpChecksum) { \
  413. (pIpHdr)->iph_tos = ((pIpHdr)->iph_tos & PS_IP_DS_CODEPOINT_MASK) | (tos); \
  414. } \
  415. else { \
  416. USHORT _old, _new; \
  417. ULONG _sum; \
  418. _old = *(USHORT *)(pIpHdr); \
  419. (pIpHdr)->iph_tos = ((pIpHdr)->iph_tos & PS_IP_DS_CODEPOINT_MASK) | (tos); \
  420. _new = *(USHORT *)(pIpHdr); \
  421. _sum = ((~(pIpHdr)->iph_xsum) & 0xffff) + ((~_old) & 0xffff) + _new; \
  422. _sum = (_sum & 0xffff) + (_sum >> 16); \
  423. _sum += (_sum >> 16); \
  424. (pIpHdr)->iph_xsum = (ushort) ((~_sum) & 0xffff); \
  425. } \
  426. }
  427. //
  428. // Number of OS time units per second
  429. //
  430. #define OS_TIME_SCALE 10000000
  431. //
  432. // convert from OS's 100 ns to millisecs
  433. //
  434. #define OS_TIME_TO_MILLISECS(_time) ((_time)/10000)
  435. _inline VOID
  436. PsGetCurrentTime(
  437. PLARGE_INTEGER SysTime
  438. )
  439. /*++
  440. Routine Description:
  441. Get the current system time
  442. Arguments:
  443. Comments:
  444. 1. We need something that always increases - Hence we cannot use NdisGetCurrentSystemTime or
  445. KeQueryCurrentSystem time. Those APIs can return decreasing times (daylight savings, date/time, etc).
  446. Return Value:
  447. System time (in base OS time units)
  448. --*/
  449. {
  450. #if defined(PERF_COUNTER)
  451. LARGE_INTEGER Now;
  452. LARGE_INTEGER Frequency;
  453. Now = KeQueryPerformanceCounter(&Frequency);
  454. SysTime->QuadPart = (Now.QuadPart * OS_TIME_SCALE) / Frequency.QuadPart;
  455. #else
  456. //
  457. // We used to use KeQueryTickCount() with KeQueryTimeIncrement(). But, if we are driving the clock at a lower
  458. // resolution, then we cannot use KeQueryTickCount, because this will always return the time based on the
  459. // maximum resolution. Therefore, we use KeQueryInterruptTime().
  460. //
  461. SysTime->QuadPart = KeQueryInterruptTime();
  462. #endif
  463. }
  464. #endif /* _PKTSCHED_H_ */
  465. /* end pktsched.h */