2017-01-23 6 views
5

मैं लिनक्स कर्नेल के network timestamping दस्तावेज पढ़ रहा हूं और ऐसा कुछ है जो मुझे स्पष्ट नहीं है।लिनक्स कर्नेल यूडीपी रिसेप्शन टाइमस्टैम्प

SO_TIMESTAMPNS द्वारा प्रदान की गई टाइमस्टैम्प कहां है? हार्डवेयर में या कर्नेल में? यदि ऐसा है तो जैसे ही एक नया पैकेट उठाने के लिए बाधा उत्पन्न होती है?

SO_TIMESTAMPING हार्डवेयर टाइमस्टैम्प की पीढ़ी को भी अनुमति देना चाहिए। क्या यह सभी एनआईसी द्वारा समर्थित है? SO_TIMESTAMPING विकल्प SOF_TIMESTAMPING_RX_HARDWARE andSO_TIMESTAMPNS के साथ कैसे करता है? उस मामले में हार्डवेयर टाइमस्टैम्प सिस्टम घड़ी या एनआईसी घड़ी का जिक्र है? दूसरे मामले में विलुप्त समय की गणना करने के लिए एनआईसी घड़ी को कैसे प्राप्त किया जाए?

+3

हार्डवेयर यदि समर्थित है, और गिरी। आम तौर पर ऐसे हार्डवेयर कार्ड सिंक्रनाइज़ करने के लिए पीटीपी की तरह कुछ उपयोग करेंगे, इसलिए आपको घड़ी के संबंध में एक टाइमस्टैंप प्राप्त करना चाहिए (सुनिश्चित नहीं है कि यह मोनोटोनिक होने की गारंटी है - शायद कोई और टिप्पणी कर सकता है ..) – Nim

+0

@Nim, समर्थित होने पर हार्डवेयर लौटाता है? SO_TIMESTAMPNS? क्या मुझे हार्डवेयर टाइमस्टैम्पिंग को सक्षम करना है? – Maverik

+0

सामान्य रूप से हार्डवेयर जो इस कार्यक्षमता का समर्थन करता है, सॉकेट विकल्प ('SO_TIMESTAMPNS' या' SO_TIMESTAMP') देखेंगे और फिर पैकेट को टिकट देगा। इसलिए, उदाहरण के लिए, यदि आपके पास उचित सौरफ्लर कार्ड है, तो विकल्प सेट करने से कार्ड टाइमस्टैम्प हो जाएगा। अन्यथा यह कर्नेल द्वारा प्रबंधित किया जाएगा। स्पष्ट रूप से बोलते हुए, मुझे वास्तव में यह पसंद नहीं है कि आपको वास्तव में टाइमस्टैम्प प्राप्त करने के लिए नियंत्रण शीर्षलेख पढ़ना होगा - यह एक भयानक इंटरफ़ेस है .. – Nim

उत्तर

4

सॉफ़्टवेयर टाइमस्टैम्पिंग के लिए उपयोग की जाने वाली सॉकेट विशेषता, SO_TIMESTAMPNS है। यह सॉकेट विशेषता सिस्टम घड़ी से समय लौटाती है। यह हार्डवेयर में उत्पन्न नहीं होता है, बल्कि सॉफ़्टवेयर में बाधा को संभालने पर सिस्टम समय का स्नैपशॉट होता है। हम सहायक डेटा (CMSG) सॉकेट पेलोड का हिस्सा नहीं है के माध्यम से इस टाइमस्टैम्प उपयोग कर सकते हैं, का उपयोग करते हुए:

int level, type; 
struct cmsghdr *cm; 
struct timespec *ts = NULL; 
for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm)) 
{ 
    level = cm->cmsg_level; 
    type = cm->cmsg_type; 
    if (SOL_SOCKET == level && SO_TIMESTAMPNS == type) { 
     ts = (struct timespec *) CMSG_DATA(cm); 
     printf("SW TIMESTAMP %ld.%09ld\n", (long)ts[0].tv_sec, (long)ts[0].tv_nsec); 
    } 
} 

SO_TIMESTAMPING सॉकेट विकल्प कई अलग अलग झंडे प्रदान करता है, उनमें से कुछ हैं,

SOF_TIMESTAMPING_TX_HARDWARE // Transmit timestamp generated in hardware by NIC clock 
SOF_TIMESTAMPING_RX_HARDWARE // Receive timestamp generated in hardware by NIC clock 
SOF_TIMESTAMPING_TX_SOFTWARE // Transmit timestamp generated in kernel driver by NIC clock 
SOF_TIMESTAMPING_RX_SOFTWARE // Receive timestamp generated in kernel driver by NIC clock 

यह सॉकेट विकल्प सभी नेटवर्क इंटरफेस कार्ड (एनआईसी) द्वारा समर्थित नहीं है। वर्तमान में कई ईथरनेट एनआईसी SO_TIMESTAMPING का समर्थन करते हैं।

ethtool -T ethX // where X corresponds to your particular interface 

यह सब सॉकेट विशेषताओं ethX timestamping के लिए समर्थन करता है, वापस आ जाएगी: आदेश में एक विशेष इंटरफ़ेस चालक SO_TIMESTAMPING, उपयोग का समर्थन करता है, तो लगता है।

एक विशेष एनआईसी द्वारा प्रदान की हार्डवेयर timestamping सुविधा का उपयोग करने के लिए, कोड का उपयोग करें:

int flags; 
flags = SOF_TIMESTAMPING_TX_HARDWARE 
      | SOF_TIMESTAMPING_RX_HARDWARE 
      | SOF_TIMESTAMPING_TX_SOFTWARE 
      | SOF_TIMESTAMPING_RX_SOFTWARE 
      | SOF_TIMESTAMPING_RAW_HARDWARE; 
    if (setsockopt(sd, SOL_SOCKET, SO_TIMESTAMPING, &flags, sizeof(flags)) < 0) 
     printf("ERROR: setsockopt SO_TIMESTAMPING\n"); 

int level, type; 
struct cmsghdr *cm; 
struct timespec *ts = NULL; 
for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm)) 
{ 
    if (SOL_SOCKET == level && SO_TIMESTAMPING == type) { 
     ts = (struct timespec *) CMSG_DATA(cm); 
     printf("HW TIMESTAMP %ld.%09ld\n", (long)ts[2].tv_sec, (long)ts[2].tv_nsec); 
     } 
} 
संबंधित मुद्दे