diff options
author | Yi-Hung Wei <yihung.wei@gmail.com> | 2017-05-15 10:04:57 -0700 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2017-05-31 14:54:10 -0700 |
commit | d7892c814a8a9cf5681d34c6470bc9d841f4ad21 (patch) | |
tree | 3f0a70672a3781b56f3b6f8ae7e41178d4721c94 /lib | |
parent | 577bfa9f687936d53970d0ff41928c3a727720e8 (diff) | |
download | openvswitch-d7892c814a8a9cf5681d34c6470bc9d841f4ad21.tar.gz |
ofproto: Add pipeline fields support for OF 1.5 packet-out
This patch decodes pipeline fields from a packet-out message, and populates
the pipeline fields into datapath. Error OFPERR_OFPBRC_PIPELINE_FIELDS_ONLY
is returned if the match field of a packet-out messages contains any
non pipeline fields. Currently, the supported pipeline fields
are as following.
* metadata fields:
- in_port, in_port_oxm
* tunnel fields:
- tun_id, tun_src, tun_dst, tun_ipv6_src, tun_ipv6_dst
- tun_gbp_id, tun_gpb_flags, tun_flags
- tun_metadata0 - tun_metadata63
* register fields:
- metadata
- reg0 - reg-15, xreg0 - xreg7, xxreg0 - xxreg3
Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/meta-flow.c | 90 | ||||
-rw-r--r-- | lib/nx-match.c | 54 | ||||
-rw-r--r-- | lib/nx-match.h | 14 | ||||
-rw-r--r-- | lib/ofp-util.c | 23 |
4 files changed, 143 insertions, 38 deletions
diff --git a/lib/meta-flow.c b/lib/meta-flow.c index b82a27381..b520e11c5 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -1553,6 +1553,96 @@ mf_is_tun_metadata(const struct mf_field *mf) mf->id < MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS; } +bool +mf_is_pipeline_field(const struct mf_field *mf) +{ + switch (mf->id) { + case MFF_TUN_ID: + case MFF_TUN_SRC: + case MFF_TUN_DST: + case MFF_TUN_IPV6_SRC: + case MFF_TUN_IPV6_DST: + case MFF_TUN_FLAGS: + case MFF_TUN_GBP_ID: + case MFF_TUN_GBP_FLAGS: + CASE_MFF_TUN_METADATA: + case MFF_METADATA: + case MFF_IN_PORT: + case MFF_IN_PORT_OXM: + CASE_MFF_REGS: + CASE_MFF_XREGS: + CASE_MFF_XXREGS: + return true; + + case MFF_DP_HASH: + case MFF_RECIRC_ID: + case MFF_CONJ_ID: + case MFF_TUN_TTL: + case MFF_TUN_TOS: + case MFF_ACTSET_OUTPUT: + case MFF_SKB_PRIORITY: + case MFF_PKT_MARK: + case MFF_CT_STATE: + case MFF_CT_ZONE: + case MFF_CT_MARK: + case MFF_CT_LABEL: + case MFF_CT_NW_PROTO: + case MFF_CT_NW_SRC: + case MFF_CT_NW_DST: + case MFF_CT_IPV6_SRC: + case MFF_CT_IPV6_DST: + case MFF_CT_TP_SRC: + case MFF_CT_TP_DST: + case MFF_ETH_SRC: + case MFF_ETH_DST: + case MFF_ETH_TYPE: + case MFF_VLAN_TCI: + case MFF_DL_VLAN: + case MFF_VLAN_VID: + case MFF_DL_VLAN_PCP: + case MFF_VLAN_PCP: + case MFF_MPLS_LABEL: + case MFF_MPLS_TC: + case MFF_MPLS_BOS: + case MFF_MPLS_TTL: + case MFF_IPV4_SRC: + case MFF_IPV4_DST: + case MFF_IPV6_SRC: + case MFF_IPV6_DST: + case MFF_IPV6_LABEL: + case MFF_IP_PROTO: + case MFF_IP_DSCP: + case MFF_IP_DSCP_SHIFTED: + case MFF_IP_ECN: + case MFF_IP_TTL: + case MFF_IP_FRAG: + case MFF_ARP_OP: + case MFF_ARP_SPA: + case MFF_ARP_TPA: + case MFF_ARP_SHA: + case MFF_ARP_THA: + case MFF_TCP_SRC: + case MFF_TCP_DST: + case MFF_TCP_FLAGS: + case MFF_UDP_SRC: + case MFF_UDP_DST: + case MFF_SCTP_SRC: + case MFF_SCTP_DST: + case MFF_ICMPV4_TYPE: + case MFF_ICMPV4_CODE: + case MFF_ICMPV6_TYPE: + case MFF_ICMPV6_CODE: + case MFF_ND_TARGET: + case MFF_ND_SLL: + case MFF_ND_TLL: + return false; + + case MFF_N_IDS: + default: + OVS_NOT_REACHED(); + } +} + /* Returns true if 'mf' has previously been set in 'flow', false if * it contains a non-default value. * diff --git a/lib/nx-match.c b/lib/nx-match.c index 68e58d393..5d8aac571 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -510,8 +510,8 @@ nx_pull_match_entry(struct ofpbuf *b, bool allow_cookie, * ethertype being present, when decoding metadata only. */ static enum ofperr nx_pull_raw(const uint8_t *p, unsigned int match_len, bool strict, - struct match *match, ovs_be64 *cookie, ovs_be64 *cookie_mask, - const struct tun_table *tun_table, + bool pipeline_fields_only, struct match *match, ovs_be64 *cookie, + ovs_be64 *cookie_mask, const struct tun_table *tun_table, const struct vl_mff_map *vl_mff_map) { ovs_assert((cookie != NULL) == (cookie_mask != NULL)); @@ -549,6 +549,8 @@ nx_pull_raw(const uint8_t *p, unsigned int match_len, bool strict, error = OFPERR_OFPBMC_BAD_PREREQ; } else if (!mf_is_all_wild(field, &match->wc)) { error = OFPERR_OFPBMC_DUP_FIELD; + } else if (pipeline_fields_only && !mf_is_pipeline_field(field)) { + error = OFPERR_OFPBRC_PIPELINE_FIELDS_ONLY; } else { char *err_str; @@ -575,7 +577,7 @@ nx_pull_raw(const uint8_t *p, unsigned int match_len, bool strict, static enum ofperr nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict, - struct match *match, + bool pipeline_fields_only, struct match *match, ovs_be64 *cookie, ovs_be64 *cookie_mask, const struct tun_table *tun_table, const struct vl_mff_map *vl_mff_map) @@ -592,14 +594,17 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict, } } - return nx_pull_raw(p, match_len, strict, match, cookie, cookie_mask, - tun_table, vl_mff_map); + return nx_pull_raw(p, match_len, strict, pipeline_fields_only, match, + cookie, cookie_mask, tun_table, vl_mff_map); } /* Parses the nx_match formatted match description in 'b' with length * 'match_len'. Stores the results in 'match'. If 'cookie' and 'cookie_mask' * are valid pointers, then stores the cookie and mask in them if 'b' contains * a "NXM_NX_COOKIE*" match. Otherwise, stores 0 in both. + * If 'pipeline_fields_only' is true, this function returns + * OFPERR_OFPBRC_PIPELINE_FIELDS_ONLY if there is any non pipeline fields + * in 'b'. * * 'vl_mff_map" is an optional parameter that is used to validate the length * of variable length mf_fields in 'match'. If it is not provided, the @@ -611,11 +616,11 @@ nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict, enum ofperr nx_pull_match(struct ofpbuf *b, unsigned int match_len, struct match *match, ovs_be64 *cookie, ovs_be64 *cookie_mask, - const struct tun_table *tun_table, + bool pipeline_fields_only, const struct tun_table *tun_table, const struct vl_mff_map *vl_mff_map) { - return nx_pull_match__(b, match_len, true, match, cookie, cookie_mask, - tun_table, vl_mff_map); + return nx_pull_match__(b, match_len, true, pipeline_fields_only, match, + cookie, cookie_mask, tun_table, vl_mff_map); } /* Behaves the same as nx_pull_match(), but skips over unknown NXM headers, @@ -623,16 +628,16 @@ nx_pull_match(struct ofpbuf *b, unsigned int match_len, struct match *match, * prerequisities. */ enum ofperr nx_pull_match_loose(struct ofpbuf *b, unsigned int match_len, - struct match *match, - ovs_be64 *cookie, ovs_be64 *cookie_mask, + struct match *match, ovs_be64 *cookie, + ovs_be64 *cookie_mask, bool pipeline_fields_only, const struct tun_table *tun_table) { - return nx_pull_match__(b, match_len, false, match, cookie, cookie_mask, - tun_table, NULL); + return nx_pull_match__(b, match_len, false, pipeline_fields_only, match, + cookie, cookie_mask, tun_table, NULL); } static enum ofperr -oxm_pull_match__(struct ofpbuf *b, bool strict, +oxm_pull_match__(struct ofpbuf *b, bool strict, bool pipeline_fields_only, const struct tun_table *tun_table, const struct vl_mff_map *vl_mff_map, struct match *match) { @@ -662,11 +667,15 @@ oxm_pull_match__(struct ofpbuf *b, bool strict, } return nx_pull_raw(p + sizeof *omh, match_len - sizeof *omh, - strict, match, NULL, NULL, tun_table, vl_mff_map); + strict, pipeline_fields_only, match, NULL, NULL, + tun_table, vl_mff_map); } /* Parses the oxm formatted match description preceded by a struct * ofp11_match_header in 'b'. Stores the result in 'match'. + * If 'pipeline_fields_only' is true, this function returns + * OFPERR_OFPBRC_PIPELINE_FIELDS_ONLY if there is any non pipeline fields + * in 'b'. * * 'vl_mff_map' is an optional parameter that is used to validate the length * of variable length mf_fields in 'match'. If it is not provided, the @@ -676,20 +685,23 @@ oxm_pull_match__(struct ofpbuf *b, bool strict, * * Returns 0 if successful, otherwise an OpenFlow error code. */ enum ofperr -oxm_pull_match(struct ofpbuf *b, const struct tun_table *tun_table, +oxm_pull_match(struct ofpbuf *b, bool pipeline_fields_only, + const struct tun_table *tun_table, const struct vl_mff_map *vl_mff_map, struct match *match) { - return oxm_pull_match__(b, true, tun_table, vl_mff_map, match); + return oxm_pull_match__(b, true, pipeline_fields_only, tun_table, + vl_mff_map, match); } /* Behaves the same as oxm_pull_match() with two exceptions. Skips over * unknown OXM headers instead of failing with an error when they are * encountered, and does not check for field prerequisities. */ enum ofperr -oxm_pull_match_loose(struct ofpbuf *b, const struct tun_table *tun_table, - struct match *match) +oxm_pull_match_loose(struct ofpbuf *b, bool pipeline_fields_only, + const struct tun_table *tun_table, struct match *match) { - return oxm_pull_match__(b, false, tun_table, NULL, match); + return oxm_pull_match__(b, false, pipeline_fields_only, tun_table, NULL, + match); } /* Parses the OXM match description in the 'oxm_len' bytes in 'oxm'. Stores @@ -705,8 +717,8 @@ oxm_decode_match(const void *oxm, size_t oxm_len, bool loose, const struct tun_table *tun_table, const struct vl_mff_map *vl_mff_map, struct match *match) { - return nx_pull_raw(oxm, oxm_len, !loose, match, NULL, NULL, tun_table, - vl_mff_map); + return nx_pull_raw(oxm, oxm_len, !loose, false, match, NULL, NULL, + tun_table, vl_mff_map); } /* Verify an array of OXM TLVs treating value of each TLV as a mask, diff --git a/lib/nx-match.h b/lib/nx-match.h index 6afb310ef..90cb6f8fd 100644 --- a/lib/nx-match.h +++ b/lib/nx-match.h @@ -50,17 +50,19 @@ char *mf_parse_subfield(struct mf_subfield *, const char *s) /* Decoding matches. */ enum ofperr nx_pull_match(struct ofpbuf *, unsigned int match_len, - struct match *, - ovs_be64 *cookie, ovs_be64 *cookie_mask, + struct match *, ovs_be64 *cookie, + ovs_be64 *cookie_mask, bool pipeline_fields_only, const struct tun_table *, const struct vl_mff_map *); enum ofperr nx_pull_match_loose(struct ofpbuf *, unsigned int match_len, struct match *, ovs_be64 *cookie, ovs_be64 *cookie_mask, + bool pipeline_fields_only, const struct tun_table *); -enum ofperr oxm_pull_match(struct ofpbuf *, const struct tun_table *, - const struct vl_mff_map *, struct match *); -enum ofperr oxm_pull_match_loose(struct ofpbuf *, const struct tun_table *, - struct match *); +enum ofperr oxm_pull_match(struct ofpbuf *, bool pipeline_fields_only, + const struct tun_table *, const struct vl_mff_map *, + struct match *); +enum ofperr oxm_pull_match_loose(struct ofpbuf *, bool pipeline_fields_only, + const struct tun_table *, struct match *); enum ofperr oxm_decode_match(const void *, size_t, bool, const struct tun_table *, const struct vl_mff_map *, struct match *); diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 6b9d59f7c..62cc3228c 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -309,7 +309,7 @@ ofputil_pull_ofp11_match(struct ofpbuf *buf, const struct tun_table *tun_table, if (padded_match_len) { *padded_match_len = ROUND_UP(match_len, 8); } - return oxm_pull_match(buf, tun_table, vl_mff_map, match); + return oxm_pull_match(buf, false, tun_table, vl_mff_map, match); default: return OFPERR_OFPBMC_BAD_TYPE; @@ -1685,7 +1685,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, nfm = ofpbuf_pull(&b, sizeof *nfm); error = nx_pull_match(&b, ntohs(nfm->match_len), &fm->match, &fm->cookie, &fm->cookie_mask, - tun_table, vl_mff_map); + false, tun_table, vl_mff_map); if (error) { return error; } @@ -2324,7 +2324,7 @@ ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request *fsr, nfsr = ofpbuf_pull(b, sizeof *nfsr); error = nx_pull_match(b, ntohs(nfsr->match_len), &fsr->match, - &fsr->cookie, &fsr->cookie_mask, tun_table, + &fsr->cookie, &fsr->cookie_mask, false, tun_table, vl_mff_map); if (error) { return error; @@ -2996,7 +2996,7 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs, "claims invalid length %"PRIuSIZE, match_len, length); return EINVAL; } - if (nx_pull_match(msg, match_len, &fs->match, NULL, NULL, NULL, + if (nx_pull_match(msg, match_len, &fs->match, NULL, NULL, false, NULL, NULL)) { return EINVAL; } @@ -3253,7 +3253,7 @@ ofputil_decode_flow_removed(struct ofputil_flow_removed *fr, nfr = ofpbuf_pull(&b, sizeof *nfr); error = nx_pull_match(&b, ntohs(nfr->match_len), &fr->match, NULL, - NULL, NULL, NULL); + NULL, false, NULL, NULL); if (error) { return error; } @@ -3514,7 +3514,7 @@ ofputil_decode_packet_in(const struct ofp_header *oh, bool loose, const ovs_be64 *cookie = (raw == OFPRAW_OFPT13_PACKET_IN ? ofpbuf_pull(&b, sizeof *cookie) : NULL); - enum ofperr error = oxm_pull_match_loose(&b, tun_table, + enum ofperr error = oxm_pull_match_loose(&b, false, tun_table, &pin->flow_metadata); if (error) { return error; @@ -3574,7 +3574,8 @@ ofputil_decode_packet_in(const struct ofp_header *oh, bool loose, npi = ofpbuf_pull(&b, sizeof *npi); error = nx_pull_match_loose(&b, ntohs(npi->match_len), - &pin->flow_metadata, NULL, NULL, NULL); + &pin->flow_metadata, NULL, NULL, false, + NULL); if (error) { return error; } @@ -4210,7 +4211,7 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po, const struct ofp15_packet_out *opo = ofpbuf_pull(&b, sizeof *opo); po->buffer_id = ntohl(opo->buffer_id); - error = oxm_pull_match_loose(&b, NULL, &po->flow_metadata); + error = oxm_pull_match_loose(&b, true, NULL, &po->flow_metadata); if (error) { return error; } @@ -6831,7 +6832,7 @@ ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request *rq, rq->table_id = nfmr->table_id; return nx_pull_match(msg, ntohs(nfmr->match_len), &rq->match, NULL, - NULL, NULL, NULL); + NULL, false, NULL, NULL); } void @@ -6939,8 +6940,8 @@ ofputil_decode_flow_update(struct ofputil_flow_update *update, update->cookie = nfuf->cookie; update->priority = ntohs(nfuf->priority); - error = nx_pull_match(msg, match_len, &update->match, NULL, NULL, NULL, - NULL); + error = nx_pull_match(msg, match_len, &update->match, NULL, NULL, + false, NULL, NULL); if (error) { return error; } |