TSO - تخلیه جانبی یا انتقال سگمنت های بسته های بزرگ TCP
 TSO – تخلیه جانبی یا انتقال سگمنت های بسته های بزرگ TCP 

درایورهای مینی پورت NDIS می توانند سگمنت های بسته های بزرگ TCP را (که بزرگتر از حداکثر واحد انتقال MTU در رسانه شبکه هستند) را تخلیه کند. یک کارت شبکه که از سگمنت بسته های بزرگ TCP پشتیبانی می کند باید بتواند:

  • چک سام IP را برای ارسال بسته هایی که حاوی گزینه های IP هستند محاسبه کند.
  • چک سام TCP را برای ارسال بسته هایی که حاوی گزینه های TCP هستند محاسبه کند.

NDIS های نسخه 6.0 و بعد از آن از نسخه  LSOV1 پشتبانی می کنند که شبیه به LSO در NDIS 5.x هستند. NDIS نسخه 6.0 . بعد از آن همچنین از large send offload version 2 (LSOV2) پشتیبانی می کنند که سرویس های سگمنت بسته های بزرگ ارتقاء داده شده را (از جمله پشتیبانی از IPv6) را فراهم می آورد.

درایورهای مینی پورتی که از LSOV2 و LSOV1 پشتیبانی می کنند باید نوع  تخلیه جانبی اطلاعات OOB ساختار NET_BUFFER_LIST تعیین کند . درایورها می توانند از نوع ساختار  NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO را استفاده کنند تا تعیین کنند که آیا پشته درایور استفاده شده LSOV2 است یا LSOV1 و آیا این پلت فرم سرویس های تخلیه جانبی مناسبی را ارائه می دهد یا خیر. هر ساختار NET_BUFFER_LIST که حاوی اطلاعات LSOv1 یا LSOv2 OOB است شامل ساختار NET_BUFFER نیز می باشد. با این حال در مواردی که مینی پورتی  پارامتر OID_TCP_OFFLOAD_PARAMETERS را دریافت می کند تا قابلیت LSO را در مینی پورت غیرفعال کند و بعد سرویس انتقال بار OID را تکمیل  کرده است ،  سرویس انتقال بار باید تمام لیست بافر شبکه  (NET_BUFFER_LIST) را که حاوی اطلاعات ) LSOv2 OOB یا LSOv1 غیر صفر هستند را از بین ببرد.

TCP/IP تنها بسته های TCP بزرگی که معیارهای زیر را برآورده می کند را انتقال می دهد:

  • بسته یک بسته TCP است.  TCP/IP بسته های بزرگ UDP را برای سگمنت کردن انتقال نمی دهد.
  • بسته باید با حداقل تعداد سگمنت های مشخص شده توسط درایور مینی پورت را مشخص کند.
  • بسته نباید یک بسته لوپ بک باشد.
  • بسته از طریق یک تونل ارسال نمی شود.

 TSO - تخلیه جانبی یا انتقال سگمنت های بسته های بزرگ TCP

قبل از انتقال بسته های TCP بزرگ برای سگمنشن، TCP/IP باید:

  • اطلاعات تقسیم بندی بسته  بزرگ را که به ساختار NET_BUFFER_LIST مربوط است را بروزرسانی کند. این اطلاعات یک ساختار NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO  می باشد که  بخشی از اطلاعات NET_BUFFER_LIST است و با ساختار NET_BUFFER_LIST مرتبط است. لایه انتقال TCP / IP مقدار MSS را به بیشترین اندازه سگمنت (MSS)  ست می کند.
  • طول کلی بسته بزرگ TCP در فیلد Total Length هدر IP بسته نوشته می شود. طول کلی شامل طول هدر IP است و در صورتی که گزینه های IP وجود داشته باشند طول آنها درج می شود و اطلاعات دیگری مانند طول هدر TCP، طول گزینه های TCP و طول پی لود TCP را شامل می شود.
  • مکمل 1 جمع برای pseudoheader یا شبه فرآیند فرضیTCP  محاسبه می شود و این مقدار جمع در فیلد چک سام هدر TCP نوشته می شود. لایه انتقال  TCP / IP مکمل 1 جمع فیلدهای موجود در pseudoheader ( آدرس آی پی منبع، ادرس آی پی مقصد و پروتکل) را محاسبه می کند. این مکمل 1 جمع برای pseudoheader
  •  توسط لایه انتقال TCP/IP کارت شبکه ارائه می شود که در همان ابتدا با محاسبه چک سام TCP برای هر بسته که کارت شبکه از بسته بزرگ TCP تحویل می دهد محاسبه می شود ( بدون اینکه هدر IP را بررسی کرده باشد).
  • توجه داشته باشید که RFC 793 تعیین می کند که چک سام هدر pseudo روی آدرس آی پی منبع، آدرس آی پی مقصد، پروتکل و طول TCP (طول هدر TCP به علاوه طول پی لود TCP است و شامل طول هدر pseudo نمی شود) محاسبه شود.
  • با این حال، زیرساخت درایور مینی پورت و NIC ، بخش های TCP از بسته بزرگی  به دست می آورد که از لایه انتقال پروتکل TCP/IP گذشته باشد، لایه انتقال اندازه پی لود TCP هر سگمنت TCP را نمی داند و در نتیجه طول TCP موجود در هدر pseudo را نمی داند. در عوض، همانطور که در ادامه توضیح داده می شود، کارت شبکه چک سام هدر pseudo را که توسط لایه انتقال TCP/IP تامین می شود را گسترش می دهد تا طول TCP هر سگمنت TCP تولید شده را پوشش دهد.
  • شماره توالی صحیح در فیلد Sequence Number هدر TCP نوشته می شود. این شماره توالی اولین بایت از پی لود TCP را مشخص می کند.

بعد از اینکه  درایور مینی پورت،  ساختار NET_BUFFER_LIST را  در توابع MiniportSendNetBufferLists یا MiniportCoSendNetBufferLists بدست آورد می تواند ماکرو NET_BUFFER_LIST_INFO را با یک شناسه از TcpLargeSendNetBufferListInfo فراخونی کند تا مقدار MSS ی که توسط لایه انتقال TCP/IP نوشته شده است را بدست آورد.

درایور مینی پورت طول کلی بسته بزرگ را از هدر IP بسته بدست می آورد و مقدار MSS را برای تقسیم بسته بزرگ TCP به بسته های کوچکتر را استفاده می کند. هر بسته کوچکتر شامل MSS یا بایت های اطلاعاتی کمتر کاربر است. توجه داشته باشید که تنها آخرین بسته ای که از بسته بزرگ سگمنت شده ایجاد شده، باید حاوی مقدار کمتری از بایت های اطلاعات کاربر MSS باشد اگر از این قانون پیروی نکنید، ایجاد و انتقال بسته های غیر ضروری اضافی می تواند عملکرد را کاهش دهد. درایورهای مینی پورت هدرهای MAC,IP و TCP را به هر سگمنت که از تقسیم بسته بزرگ استخراج می شود اضافه می کند. درایور مینی پورت باید چک سام های TCP و IP را برای هر یک از این بسته های تقسیم شده را بدست بیاورد. برای محاسبه چک سام TCP برای هر بسته که از بسته TCP بزرگ بدست آمده، کارت شبکه بخش قابل دید چک سام TCP ( برای هدر TCP و پی لود TCP) محاسبه می کند و این چک سام را به مکمل 1 جمع اضافه می کند تا pseudoheader توسط لایه انتقال TCP/IP محاسبه شود و بعد مکمل 1 شانزده بیتی برای چک سام محاسبه می شود. شکل زیر تقسیم بندی یک بسته بزرگ را  نشان می دهد.

 TSO - تخلیه جانبی یا انتقال سگمنت های بسته های بزرگ TCP

طول داده های کاربر TCP در بسته TCP بزرگ باید برابر یا کمتر از مقداری باشد که درایور مینی پورت برای مقدار MaxOffLoadSize تعریف می کند. بعد از اینکه درایو وضعیتی مشکل زا را نشان دارد شاخص باید به مقدار MaxOffLoadSize تغییر کند. در صورتی که درخواست ارسال LSO ی دریافت شد که از مقدار قبلی MaxOffLoadSize استفاده می کند این درایور نباید کرش شود. در عوض درایور می تواند با درخواست ارسال را رد کند.

یک  درایور میانجی که نشانه های وضعیت را  انتشار می دهد و تغییر در مقدار بار جانبی  Max  را گزارش می دهد باید تضمین کند که زیرساخت آداپتور مینی پورت که نشانه وضعیت را صادر نکرده است هیچ بسته ی بزرگتر  از مقدار MaxOffLoadSize  (که آداپتور مینی پورت گزارش داده بود) را دریافت نمی کند.

یک درایور مینی پورت میانجی که به OID_TCP_OFFLOAD_PARAMETERS پاسخ می دهد تا سرویس LSO را غیرفعال کند باید برای یک بازه زمانی محدود آماده باشد تا درخواست ارسال LSO بتواند به درایور مینی پورت دست یابد. طول داده های کاربر TCP در یک سگمنت بسته باید معادل یا کمتر از MSS باشد. MSS یک مقدارULONG  است که با استفاده از اطلاعات  LSO NET_BUFFER_LIST  که متناظر با ساختار NET_BUFFER_LIST است از لایه انتقال TCP می گذرد.

توجه داشته باشید که تنها آخرین بسته ای که از بسته بزرگ سگمنت شده ایجاد شده،  باید حاوی بایت های اطلاعات کاربری MSS  کمتر باشد. تمام بسته های دیگر که از بسته سگمنت شده ساخته شده اند باید حاوی بایت های اطلاعات کاربر MSS باشند اگر از این قانون پیروی نکنید، ایجاد و انتقال بسته های غیر ضروری اضافی می تواند عملکرد را کاهش دهد. تعداد سگمنت بسته ها که از بسته TCP بزرگ استخراج شده باید برابر یا بیشتر از مقدار MinSegmentCount  که توسط درایور مینی پورت مشخص می شود باشد.

فرضیه های و محدودیت های زیر مربوط به پردازش  هدرهای  IP و TCP است:

  • بیت MF در هدر IP بسته بزرگ TCP که لایه انتقال TCP/IP تخلیه می کند ست نشده باشد و Fragment Offset در هدر IP به صفر شده باشد.
  • پرچم های URG, RST و SYN در هدر TCP بسته بزرگ TCP ست نشده باشد و آفست (اشاره گر) urgent در هدر TCP به صفر ست شده باشد.
  • اگر بیت FIN در  هدر TCP بسته بزرگ ست شده باشد، درایور مینی پورت باید این بیت را در هدر TCP آخرین بسته که از بسته بزرگ TCP ساخته شده است قرار دهد.
  • اگر بیت PSH در هدر TCP بسته بزرگ TCP تنظیم شود، درایور مینی پورت باید این بیت را در  هدر TCP آخرین بسته که از بسته بزرگ TCP ایجاد شده است قرار دهد.
  • اگر بسته بزرگ TCP حاوی گزینه های IP یا گزینه های TCP (یا هر دو) باشد،  درایور مینی پورت،  این گزینه ها را بدون تغییر، در بسته هایی که از بسته بزرگ TCP بدست آمده کپی می کند به طور خاص، کارت شبکه گزینه Time Stamp را افرایش نخواهد داد.
  • تمام  هدرهای بسته (اترنت، IP، TCP) در اولین MDL بسته خواهد بود. هدرها در سراسر MDL های مختلف تقسیم نخواهند شد.

 نکته : این فرض زمانی معتبر است که LSO فعال باشد. در غير اينصورت، هنگامي كه LSO فعال نباشد،  درایورهای مینی پورت نمي توانند فرض كنند كه هدرهای  IP در همان MDL هدر اترنت هستند.

 درایور مینی پورت باید بسته ها  را در ساختار NET_BUFFER_LIST ارسال کند به طوری که بتوانند ساختارهای NET_BUFFER_LIST را از لایه انتقال TCP/IP دریافت کنند. هنگام پردازش یک بسته بزرگ TCP، آداپتور مینی پورت مسئول تقسیم کردن بسته و  الحاق هدرهای   MAC، IP، و TCP به بسته هایی است که از بسته های بزرگ TCP ایجاد شده اند. لایه انتقال  TCP / IP تمام کارهای دیگر (مانند تنظیم اندازه پنجره ارسال بر اساس اندازه پنجره دریافت هاست ریموت) را انجام می دهد.

 قبل از تکمیل عملیات ارسال برای بسته بزرگ (مانند NdisMSendNetBufferListsComplete یا NdisMCoSendNetBufferListsComplete)،  درایور مینی پورت مقدار NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO را با تعداد کل بایت های اطلاعات کاربر TCP که به طور موفقیت آمیزی در همه بسته هایی که از بسته بزرگ TCP ساخته شده اند ارسال شده اند را می نویسد.

علاوه بر نیازهای قبلی LSO،  درایور های مینی پورت با قابلیت LSOV2 باید:

  • از IPv4 یا IPv6 یا هر دوی IPv4 و IPv6 پشتیبانی کنند.
  •   تکرار از گزینه های IPv4، از بسته بزرگ، در هر بخش بسته پشتیبانی می کند که کارت رابط شبکه (NIC) تولید می کند.
  • از تکثیر هدر اکستنشن IPv6، از بسته بزرگ TCP در هر سگمنت بسته TCP پشتیبانی کند .
  • از تکثیر گزینه های TCP در هر سگمنت بسته TCP که درایور مینی پورت ایجاد می کند پشتیبانی کند.
  •   از هدر IP و TCP در ساختار NET_BUFFER_LIST به عنوان یک الگو برای تولید هدرهای TCP / IP برای هر سگمنت بسته استفاده کند.
  • از مقدار IP ID در محدوده 0x0000 تا 0x7FFF استفاده کند. (محدوده از 0x8000 تا 0xFFFF برای دستگاه هایی که از قابلیت تخلیه جانبی  TCP پشتیبانی می کنند محفوظ است.) به عنوان مثال، اگر  الگوی هدر IP با مقدار شناسه 0x7FFE شروع شود، اولین بسته ی سگمنت TCP باید یک مقدار ID IP   از  0x7FFE داشته باشد  که به دنبال 0x7FFF، 0x0000، 0x0001 و غیره می آید.
  •   از بایت آفست در بخش TcpHeaderOffset ساختار NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO استفاده کند تا مکان هدر TCP مشخص شود و از اولین بایت بسته شروع شود.
  •   تعداد ساختارهای NET_BUFFER  را که متناظر با ساختار NET_BUFFER_LIST LSOV2  است را محدود کند.
  • طول کل بسته را از طول اولین ساختار  NET_BUFFER  موجود در ساختار NET_BUFFER_LIST را تعیین کند.
  •  از گزینه های TCP، گزینه های IP و  هدرهای اکستنشن IP پشتیبانی کند.
  • وقتی یک عملیات ارسال کامل شد، درایور مینی پورت  بایدLsoV2TransmitComplete  ساختار NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO را به صفر تنظیم کند و LsoV2TransmitComplete.Type را به NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE تنظیم کند.