/* Returns true if 'a' and 'b' represent the same wildcards, false if they are * different. */ bool flow_wildcards_equal(const struct flow_wildcards *a, const struct flow_wildcards *b) { int i; BUILD_ASSERT_DECL(FLOW_WC_SEQ == 14); if (a->wildcards != b->wildcards || a->tun_id_mask != b->tun_id_mask || a->nw_src_mask != b->nw_src_mask || a->nw_dst_mask != b->nw_dst_mask || a->vlan_tci_mask != b->vlan_tci_mask || a->metadata_mask != b->metadata_mask || !ipv6_addr_equals(&a->ipv6_src_mask, &b->ipv6_src_mask) || !ipv6_addr_equals(&a->ipv6_dst_mask, &b->ipv6_dst_mask) || a->ipv6_label_mask != b->ipv6_label_mask || !ipv6_addr_equals(&a->nd_target_mask, &b->nd_target_mask) || a->tp_src_mask != b->tp_src_mask || a->tp_dst_mask != b->tp_dst_mask || !eth_addr_equals(a->dl_src_mask, b->dl_src_mask) || !eth_addr_equals(a->dl_dst_mask, b->dl_dst_mask) || !eth_addr_equals(a->arp_sha_mask, b->arp_sha_mask) || !eth_addr_equals(a->arp_tha_mask, b->arp_tha_mask)) { return false; } for (i = 0; i < FLOW_N_REGS; i++) { if (a->reg_masks[i] != b->reg_masks[i]) { return false; } } return true; }
static struct mac_entry * search_bucket(struct list *bucket, const uint8_t mac[ETH_ADDR_LEN], uint16_t vlan) { struct mac_entry *e; LIST_FOR_EACH (e, struct mac_entry, hash_node, bucket) { if (eth_addr_equals(e->mac, mac) && e->vlan == vlan) { return e; } } return NULL; }
/* Returns true if at least one bit or field is wildcarded in 'a' but not in * 'b', false otherwise. */ bool flow_wildcards_has_extra(const struct flow_wildcards *a, const struct flow_wildcards *b) { int i; uint8_t eth_masked[ETH_ADDR_LEN]; struct in6_addr ipv6_masked; BUILD_ASSERT_DECL(FLOW_WC_SEQ == 14); for (i = 0; i < FLOW_N_REGS; i++) { if ((a->reg_masks[i] & b->reg_masks[i]) != b->reg_masks[i]) { return true; } } eth_addr_bitand(a->dl_src_mask, b->dl_src_mask, eth_masked); if (!eth_addr_equals(eth_masked, b->dl_src_mask)) { return true; } eth_addr_bitand(a->dl_dst_mask, b->dl_dst_mask, eth_masked); if (!eth_addr_equals(eth_masked, b->dl_dst_mask)) { return true; } eth_addr_bitand(a->arp_sha_mask, b->arp_sha_mask, eth_masked); if (!eth_addr_equals(eth_masked, b->arp_sha_mask)) { return true; } eth_addr_bitand(a->arp_tha_mask, b->arp_tha_mask, eth_masked); if (!eth_addr_equals(eth_masked, b->arp_tha_mask)) { return true; } ipv6_masked = ipv6_addr_bitand(&a->ipv6_src_mask, &b->ipv6_src_mask); if (!ipv6_addr_equals(&ipv6_masked, &b->ipv6_src_mask)) { return true; } ipv6_masked = ipv6_addr_bitand(&a->ipv6_dst_mask, &b->ipv6_dst_mask); if (!ipv6_addr_equals(&ipv6_masked, &b->ipv6_dst_mask)) { return true; } ipv6_masked = ipv6_addr_bitand(&a->nd_target_mask, &b->nd_target_mask); if (!ipv6_addr_equals(&ipv6_masked, &b->nd_target_mask)) { return true; } return (a->wildcards & ~b->wildcards || (a->tun_id_mask & b->tun_id_mask) != b->tun_id_mask || (a->nw_src_mask & b->nw_src_mask) != b->nw_src_mask || (a->nw_dst_mask & b->nw_dst_mask) != b->nw_dst_mask || (a->ipv6_label_mask & b->ipv6_label_mask) != b->ipv6_label_mask || (a->vlan_tci_mask & b->vlan_tci_mask) != b->vlan_tci_mask || (a->metadata_mask & b->metadata_mask) != b->metadata_mask || (a->tp_src_mask & b->tp_src_mask) != b->tp_src_mask || (a->tp_dst_mask & b->tp_dst_mask) != b->tp_dst_mask || (a->nw_frag_mask & b->nw_frag_mask) != b->nw_frag_mask); }