/* * Copyright (c) 2021 BayLibre SAS * * SPDX-License-Identifier: Apache-2.0 */ #include LOG_MODULE_REGISTER(npf_ethernet, CONFIG_NET_PKT_FILTER_LOG_LEVEL); #include #include static bool addr_mask_compare(struct net_eth_addr *addr1, struct net_eth_addr *addr2, struct net_eth_addr *mask) { for (int i = 0; i < 6; i++) { if ((addr1->addr[i] & mask->addr[i]) != (addr2->addr[i] & mask->addr[i])) { return false; } } return true; } static bool addr_match(struct npf_test *test, struct net_eth_addr *pkt_addr) { struct npf_test_eth_addr *test_eth_addr = CONTAINER_OF(test, struct npf_test_eth_addr, test); struct net_eth_addr *addr = test_eth_addr->addresses; struct net_eth_addr *mask = &test_eth_addr->mask; unsigned int nb_addr = test_eth_addr->nb_addresses; while (nb_addr) { if (addr_mask_compare(addr, pkt_addr, mask)) { return true; } addr++; nb_addr--; } return false; } bool npf_eth_src_addr_match(struct npf_test *test, struct net_pkt *pkt) { struct net_eth_hdr *eth_hdr = NET_ETH_HDR(pkt); return addr_match(test, ð_hdr->src); } bool npf_eth_src_addr_unmatch(struct npf_test *test, struct net_pkt *pkt) { return !npf_eth_src_addr_match(test, pkt); } bool npf_eth_dst_addr_match(struct npf_test *test, struct net_pkt *pkt) { struct net_eth_hdr *eth_hdr = NET_ETH_HDR(pkt); return addr_match(test, ð_hdr->dst); } bool npf_eth_dst_addr_unmatch(struct npf_test *test, struct net_pkt *pkt) { return !npf_eth_dst_addr_match(test, pkt); } bool npf_eth_type_match(struct npf_test *test, struct net_pkt *pkt) { struct npf_test_eth_type *test_eth_type = CONTAINER_OF(test, struct npf_test_eth_type, test); struct net_eth_hdr *eth_hdr = NET_ETH_HDR(pkt); /* note: type_match->type is assumed to be in network order already */ return eth_hdr->type == test_eth_type->type; } bool npf_eth_type_unmatch(struct npf_test *test, struct net_pkt *pkt) { return !npf_eth_type_match(test, pkt); }