X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnx-match.c;h=84a14de360b231c2c396d4f29136cdfce18b07a7;hb=d0c0b87f1ed1668499b8f4f770022ff3af225172;hp=beaed3dacabf270a28c84f9aa57cef546d4c62ae;hpb=dc56021df437b866c372085c195b8bdd12bd87b2;p=openvswitch diff --git a/lib/nx-match.c b/lib/nx-match.c index beaed3da..84a14de3 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -225,12 +225,15 @@ nx_pull_match(struct ofpbuf *b, unsigned int match_len, uint16_t priority, } if (error) { + char *msg = ofputil_error_to_string(error); VLOG_DBG_RL(&rl, "bad nxm_entry with vendor=%"PRIu32", " "field=%"PRIu32", hasmask=%"PRIu32", type=%"PRIu32" " - "(error %x)", + "(%s)", NXM_VENDOR(header), NXM_FIELD(header), NXM_HASMASK(header), NXM_TYPE(header), - error); + msg); + free(msg); + return error; } @@ -262,6 +265,24 @@ nxm_put_8(struct ofpbuf *b, uint32_t header, uint8_t value) ofpbuf_put(b, &value, sizeof value); } +static void +nxm_put_8m(struct ofpbuf *b, uint32_t header, uint8_t value, uint8_t mask) +{ + switch (mask) { + case 0: + break; + + case UINT8_MAX: + nxm_put_8(b, header, value); + break; + + default: + nxm_put_header(b, NXM_MAKE_WILD_HEADER(header)); + ofpbuf_put(b, &value, sizeof value); + ofpbuf_put(b, &mask, sizeof mask); + } +} + static void nxm_put_16(struct ofpbuf *b, uint32_t header, ovs_be16 value) { @@ -400,6 +421,32 @@ nxm_put_ipv6(struct ofpbuf *b, uint32_t header, } } +static void +nxm_put_tos_frag(struct ofpbuf *b, const struct cls_rule *cr) +{ + uint8_t tos_frag = cr->flow.tos_frag; + uint8_t tos_frag_mask = cr->wc.tos_frag_mask; + + if (tos_frag_mask & IP_DSCP_MASK) { + nxm_put_8(b, NXM_OF_IP_TOS, tos_frag & IP_DSCP_MASK); + } + + switch (tos_frag_mask & FLOW_FRAG_MASK) { + case 0: + break; + + case FLOW_FRAG_MASK: + /* Output it as exact-match even though only the low 2 bits matter. */ + nxm_put_8(b, NXM_NX_IP_FRAG, tos_frag & FLOW_FRAG_MASK); + break; + + default: + nxm_put_8m(b, NXM_NX_IP_FRAG, tos_frag & FLOW_FRAG_MASK, + tos_frag_mask & FLOW_FRAG_MASK); + break; + } +} + /* Appends to 'b' the nx_match format that expresses 'cr' (except for * 'cr->priority', because priority is not part of nx_match), plus enough * zero bytes to pad the nx_match out to a multiple of 8. @@ -419,7 +466,7 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr) int match_len; int i; - BUILD_ASSERT_DECL(FLOW_WC_SEQ == 2); + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 3); /* Metadata. */ if (!(wc & FWW_IN_PORT)) { @@ -443,9 +490,7 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr) /* L3. */ if (!(wc & FWW_DL_TYPE) && flow->dl_type == htons(ETH_TYPE_IP)) { /* IP. */ - if (!(wc & FWW_NW_TOS)) { - nxm_put_8(b, NXM_OF_IP_TOS, flow->nw_tos & 0xfc); - } + nxm_put_tos_frag(b, cr); nxm_put_32m(b, NXM_OF_IP_SRC, flow->nw_src, cr->wc.nw_src_mask); nxm_put_32m(b, NXM_OF_IP_DST, flow->nw_dst, cr->wc.nw_dst_mask); @@ -485,10 +530,7 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr) } } else if (!(wc & FWW_DL_TYPE) && flow->dl_type == htons(ETH_TYPE_IPV6)) { /* IPv6. */ - - if (!(wc & FWW_NW_TOS)) { - nxm_put_8(b, NXM_OF_IP_TOS, flow->nw_tos & 0xfc); - } + nxm_put_tos_frag(b, cr); nxm_put_ipv6(b, NXM_NX_IPV6_SRC, &flow->ipv6_src, &cr->wc.ipv6_src_mask); nxm_put_ipv6(b, NXM_NX_IPV6_DST, &flow->ipv6_dst, @@ -997,7 +1039,10 @@ nxm_read_field(const struct nxm_field *src, const struct flow *flow) return ntohs(flow->vlan_tci); case NFI_NXM_OF_IP_TOS: - return flow->nw_tos; + return flow->tos_frag & IP_DSCP_MASK; + + case NFI_NXM_NX_IP_FRAG: + return flow->tos_frag & FLOW_FRAG_MASK; case NFI_NXM_OF_IP_PROTO: case NFI_NXM_OF_ARP_OP: @@ -1072,6 +1117,7 @@ nxm_read_field(const struct nxm_field *src, const struct flow *flow) case NFI_NXM_NX_IPV6_SRC_W: case NFI_NXM_NX_IPV6_DST: case NFI_NXM_NX_IPV6_DST_W: + case NFI_NXM_NX_IP_FRAG_W: case NFI_NXM_NX_ND_TARGET: case N_NXM_FIELDS: NOT_REACHED(); @@ -1143,7 +1189,13 @@ nxm_write_field(const struct nxm_field *dst, struct flow *flow, #endif case NFI_NXM_OF_IP_TOS: - flow->nw_tos = new_value & IP_DSCP_MASK; + flow->tos_frag &= ~IP_DSCP_MASK; + flow->tos_frag |= new_value & IP_DSCP_MASK; + break; + + case NFI_NXM_NX_IP_FRAG: + flow->tos_frag &= ~FLOW_FRAG_MASK; + flow->tos_frag |= new_value & FLOW_FRAG_MASK; break; case NFI_NXM_OF_IP_SRC: @@ -1185,6 +1237,7 @@ nxm_write_field(const struct nxm_field *dst, struct flow *flow, case NFI_NXM_NX_IPV6_SRC_W: case NFI_NXM_NX_IPV6_DST: case NFI_NXM_NX_IPV6_DST_W: + case NFI_NXM_NX_IP_FRAG_W: case NFI_NXM_NX_ICMPV6_TYPE: case NFI_NXM_NX_ICMPV6_CODE: case NFI_NXM_NX_ND_TARGET: