При использовании CAN_INV_FILTER, как и вы, вы указываете «все проходит, кроме ID_x».
При использовании CAN_RAW_FILTER он проверит, существует ли правило, которое пропускает полученный идентификатор.В вашем случае ваши правила противоречат друг другу, поэтому ничего не фильтруется.
Из документации :
4.1.6 Опция сокета RAW CAN_RAW_JOIN_FILTERS
Сокет CAN_RAW может устанавливать несколько специфичных для идентификатора CAN фильтров, которые приводят к нескольким фильтрам при обработке фильтра af_can.c.Эти фильтры не зависят друг от друга, что приводит к применению фильтров логического ИЛИ при применении (см. 4.1.1).
Эта опция сокета объединяет данные фильтры CAN таким образом, что только кадры CAN передаются в пространство пользователя.что соответствует всем данным фильтрам CAN.Таким образом, семантика для примененных фильтров изменяется на логическое И.
Это особенно полезно, когда набор фильтров представляет собой комбинацию фильтров, в которых установлен флаг CAN_INV_FILTER, чтобы вырезать отдельные идентификаторы CAN ID или диапазоны CAN ID отвходящий трафик.
Чтобы иметь ожидаемое поведение, вы должны заменить:
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
на:
setsockopt(s, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS, &rfilter, sizeof(rfilter));
Примечание: возможно, чтоОпция CAN_RAW_JOIN_FILTERS не поддерживается вашим ядром Linux