- void *wild_field = (char *) &wild->flow + f->ofs;
- void *fixed_field = (char *) fixed + f->ofs;
-
- if ((wild->wc.wildcards & f->wildcards) == f->wildcards ||
- !memcmp(wild_field, fixed_field, f->len)) {
- /* Definite match. */
- continue;
+ bool eq;
+
+ if (f->wildcards) {
+ void *wild_field = (char *) &wild->flow + f->ofs;
+ void *fixed_field = (char *) fixed + f->ofs;
+ eq = ((wild->wc.wildcards & f->wildcards) == f->wildcards
+ || !memcmp(wild_field, fixed_field, f->len));
+ } else if (f_idx == CLS_F_IDX_NW_SRC) {
+ eq = !((fixed->nw_src ^ wild->flow.nw_src) & wild->wc.nw_src_mask);
+ } else if (f_idx == CLS_F_IDX_NW_DST) {
+ eq = !((fixed->nw_dst ^ wild->flow.nw_dst) & wild->wc.nw_dst_mask);
+ } else if (f_idx == CLS_F_IDX_TP_SRC) {
+ eq = !((fixed->tp_src ^ wild->flow.tp_src) & wild->wc.tp_src_mask);
+ } else if (f_idx == CLS_F_IDX_TP_DST) {
+ eq = !((fixed->tp_dst ^ wild->flow.tp_dst) & wild->wc.tp_dst_mask);
+ } else if (f_idx == CLS_F_IDX_DL_SRC) {
+ eq = eth_addr_equal_except(fixed->dl_src, wild->flow.dl_src,
+ wild->wc.dl_src_mask);
+ } else if (f_idx == CLS_F_IDX_DL_DST) {
+ eq = eth_addr_equal_except(fixed->dl_dst, wild->flow.dl_dst,
+ wild->wc.dl_dst_mask);
+ } else if (f_idx == CLS_F_IDX_VLAN_TCI) {
+ eq = !((fixed->vlan_tci ^ wild->flow.vlan_tci)
+ & wild->wc.vlan_tci_mask);
+ } else if (f_idx == CLS_F_IDX_TUN_ID) {
+ eq = !((fixed->tun_id ^ wild->flow.tun_id) & wild->wc.tun_id_mask);
+ } else if (f_idx == CLS_F_IDX_METADATA) {
+ eq = !((fixed->metadata ^ wild->flow.metadata)
+ & wild->wc.metadata_mask);
+ } else if (f_idx == CLS_F_IDX_NW_DSCP) {
+ eq = !((fixed->nw_tos ^ wild->flow.nw_tos) & IP_DSCP_MASK);
+ } else {
+ NOT_REACHED();