Linux 커널은 하드웨어 TX 및 RX 필터링 모드를 어떻게 저장합니까?

Linux 커널은 하드웨어 TX 및 RX 필터링 모드를 어떻게 저장합니까?

나는 내 자신의 ethtool 버전과 마찬가지로 특정 네트워크 인터페이스에 대한 타임스탬프 정보를 얻는 C 프로그램을 작업하고 있습니다. 내 목표는 정보를 인쇄하는 것입니다 $ ethtool -T myNetIf. 그것은 다음과 같습니다:

Time stamping parameters for myNetIf:
Capabilities:
    hardware-transmit     (SOF_TIMESTAMPING_TX_HARDWARE)
    software-transmit     (SOF_TIMESTAMPING_TX_SOFTWARE)
    hardware-receive      (SOF_TIMESTAMPING_RX_HARDWARE)
    software-receive      (SOF_TIMESTAMPING_RX_SOFTWARE)
    software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
    hardware-raw-clock    (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
    off                   (HWTSTAMP_TX_OFF)
    on                    (HWTSTAMP_TX_ON)
Hardware Receive Filter Modes:
    none                  (HWTSTAMP_FILTER_NONE)
    all                   (HWTSTAMP_FILTER_ALL)

명령줄 출력만 가져오고 싶지 않았기 때문에 ioctl호출을 사용하여 ethtool에서 이 정보를 쿼리하고 플래그를 부호 없는 정수로 다시 가져올 수 있다는 것을 알았습니다.

struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
struct ethtool_ts_info etsi;
memset(&etsi, 0, sizeof(struct ethtool_ts_info));

etsi.cmd = ETHTOOL_GET_TS_INFO;
strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); // dev is read from stdin
ifr.ifr_data = (void *)&etsi;

ioctl(sock, SIOCETHTOOL, &ifr); // sock is an AF_INET socket

ethtool_ts_info내가 원하는 데이터를 포함하는 구조가 정의되어 있다고 생각합니다.여기. 특히, 나는 so_timestamping, tx_typesrx_filters필드를 잡고 있습니다.

so_timestamping동일한 예시 인터페이스를 사용하면 값은 0x5f, 또는 입니다 0101 1111. 한 번 봐net_tstamp.h 확인하다이는 예상할 수 있는 징후입니다.

그러나 내 문제는 tx_typessum 값을 해석하는 것입니다 rx_filters. 내가 가정하는 값은 tx_types다음과 같습니다 0x3( 0011여기서 세 번째 비트는 HWTSTAMP_TX_ON이고 네 번째 비트는 HWTSTAMP_TX_OFF입니다). 또는 가능한 전송 모드가 다음과 같이 정의되어 있으므로열거형4개의 값이 있는 경우 결과 0100는 각 int열거 값이 2비트일 수 있습니다.

그렇지 않다. tx_types실제 값은 입니다 0x7fdd. 에서 "HW_TX_OFF 및 ON"을 정확히 어떻게 얻어야 합니까 0x7fdd? 나는 rx_filters그 가치가 더욱 혼란스럽다고 생각한다. 그것은 무엇을 0x664758eb의미해야 합니까?

커널 소스 코드 자체 외에는 유용한 정보를 많이 찾지 못했습니다. 나는 모든 일을 제대로 하고 있다고 생각합니다. 결과를 이해하는 데 도움이 필요합니다.

답변1

이것은 당혹스럽습니다. 코드를 확인한 결과 구조를 올바르게 초기화하는 데 실제로 실패했다는 사실을 발견했습니다. 단지 예상했던 방식이 아니었습니다. 또한 과제 전부터 쓰레기 값이 남을 가능성을 배제했다고 생각했기 때문에 문제 해결에 필요한 전체 맥락을 제공하지 않았습니다.

내가 게시한 예제 코드는 내가 정의한 포함을 채우는 함수의 일부입니다 ethtool_ts_info.

typedef struct {
    unsigned int soTimestamping;
    unsigned int txTypes;
    unsigned int rxFilters;
} tsCapsFilters_t;

함수 사용자는 이 구조를 직접 초기화하고 함수는 이를 채울 뿐입니다. 따라서 예상되는 사용법은 다음과 같습니다.

tsCapsFilters_t tsInfo; // struct full of junk
if(getTsInfo(nameOfNetIf, &tsInfo, errMsgBuf, ERR_BUF_SZ) < 0) {
    // handle errors in here
}
printf("%x\n", tsInfo.soTimestamping); // struct filled out by getTsInfo

tx_types그러나 내가 저지른 실수 는 구조체(내 함수 내부) rx_filters에서 구조체(사용자에게 제공됨) 로 복사 하는 것을 잊었다는 것입니다 . 따라서 내 프로그램은 모든 필드를 제대로 가져오지만 3개의 값을 모두 반환해야 하는 경우에만 함수를 반환합니다.ethtool_ts_infotsCapsFilters_tso_timestamping

printf("%x\n", tsInfo.soTimestamping); // printed the expected values
printf("%x\n", tsInfo.txTypes); // printed junk
printf("%x\n", tsInfo.rxFilters); // printed junk

내가 말했듯이, 어색해요. 나는 현상금을 시도해보고 앞으로 내 구조에 더 조심하겠습니다.

답변2

struct ethtool_ts_info etsi;

ifr.ifr_data = (void *)&etsi;

~에서네트워크 타임스탬프에 대한 커널 문서, 귀하의 프로그램에서 호출한 ioctl(SIOCSHWTSTAMP)이 해당 유형의 일부 구조를 채워야 한다는 것을 이해합니다.hwtstamp_config

다음과 같이 정의 됩니다 struct hwtstamp_config.

struct hwtstamp_config {
    int flags;  /* no flags defined right now, must be zero */
    int tx_type;    /* HWTSTAMP_TX_* */
    int rx_filter;  /* HWTSTAMP_FILTER_* */
};

struct ifreq에 대한 포인터로 ioctl(SIOCSHWTSTAMP)을 호출하여 원하는 동작을 커널과 특정 장치에 전달합니다.ifr_data는 hwtstamp_config 구조체를 가리킵니다....모든 프로세스는 동일한 방식으로 이 구조를 ioctl(SIOCGHWTSTAMP)에 전달하여 실제 구성을 읽을 수 있습니다.

프로그램이 반환된 데이터를 사용하는 경우 다음과 같이 정의된 것과 같습니다 struct ethtool_ts_info.

struct ethtool_ts_info {
    __u32   cmd;
    __u32   so_timestamping;
    __s32   phc_index;
    __u32   tx_types;
    __u32   tx_reserved[3];
    __u32   rx_filters;
    __u32   rx_reserved[3];
};

이는 귀하의 프로그램이 세 번째 int(구체적으로는) 이상의 값을 추출한다는 것을 의미합니다.거래 유형그리고rx_filters당신이 관심을 갖고 있는 것은) 당신이 보고한 대로…무의미한.
이것(구성즉 능력이 아님) 가치거래 유형그리고rx_filtersifr.ifr_data 주소에서 시작하여 각각 두 번째 및 세 번째 int에서 얻어야 합니다.

이 경우 구성 값은 원하는 것이 아니며 ioctl-ing(SIOCGHWTSTAMP)은 적절한 접근 방식이 아닙니다.

관련 정보