From bef3f465bcd5f81823c7fb8750e3f639486b3587 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 7 Mar 2016 20:46:48 -0800 Subject: [PATCH] openflow: Support matching and modifying MPLS TTL field. Occasionally we get asked about this and I don't see a reason not to support it. Signed-off-by: Ben Pfaff Acked-by: Justin Pettit --- NEWS | 1 + lib/match.c | 19 ++++++++++++++++++- lib/match.h | 4 +++- lib/meta-flow.c | 20 ++++++++++++++++++++ lib/meta-flow.h | 15 +++++++++++++++ tests/ofproto.at | 3 ++- 6 files changed, 59 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 6d71df7c8..38f6b56a7 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ Post-v2.5.0 * OpenFlow 1.3 Extension 230, adding OpenFlow Bundles support, is now implemented. Only flow mod and port mod messages are supported in bundles. + * New OpenFlow extension NXM_NX_MPLS_TTL to provide access to MPLS TTL. - ovs-ofctl: * queue-get-config command now allows a queue ID to be specified. * '--bundle' option can now be used with OpenFlow 1.3. diff --git a/lib/match.c b/lib/match.c index 95d34bc70..e4b28fa5b 100644 --- a/lib/match.c +++ b/lib/match.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -591,6 +591,23 @@ match_set_mpls_bos(struct match *match, int idx, uint8_t mpls_bos) flow_set_mpls_bos(&match->flow, idx, mpls_bos); } +/* Modifies 'match' so that the TTL of MPLS label 'idx' is wildcarded. */ +void +match_set_any_mpls_ttl(struct match *match, int idx) +{ + match->wc.masks.mpls_lse[idx] &= ~htonl(MPLS_TTL_MASK); + flow_set_mpls_ttl(&match->flow, idx, 0); +} + +/* Modifies 'match' so that it matches only packets in which the TTL of MPLS + * label 'idx' equals 'mpls_ttl'. */ +void +match_set_mpls_ttl(struct match *match, int idx, uint8_t mpls_ttl) +{ + match->wc.masks.mpls_lse[idx] |= htonl(MPLS_TTL_MASK); + flow_set_mpls_ttl(&match->flow, idx, mpls_ttl); +} + /* Modifies 'match' so that the MPLS LSE is wildcarded. */ void match_set_any_mpls_lse(struct match *match, int idx) diff --git a/lib/match.h b/lib/match.h index 650a203d3..0a6ac29ce 100644 --- a/lib/match.h +++ b/lib/match.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -120,6 +120,8 @@ void match_set_any_mpls_tc(struct match *, int idx); void match_set_mpls_tc(struct match *, int idx, uint8_t); void match_set_any_mpls_bos(struct match *, int idx); void match_set_mpls_bos(struct match *, int idx, uint8_t); +void match_set_any_mpls_ttl(struct match *, int idx); +void match_set_mpls_ttl(struct match *, int idx, uint8_t); void match_set_tp_src(struct match *, ovs_be16); void match_set_mpls_lse(struct match *, int idx, ovs_be32 lse); void match_set_tp_src_masked(struct match *, ovs_be16 port, ovs_be16 mask); diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 16b9c929a..6c899e1fd 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -271,6 +271,8 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc) return !(wc->masks.mpls_lse[0] & htonl(MPLS_TC_MASK)); case MFF_MPLS_BOS: return !(wc->masks.mpls_lse[0] & htonl(MPLS_BOS_MASK)); + case MFF_MPLS_TTL: + return !(wc->masks.mpls_lse[0] & htonl(MPLS_TTL_MASK)); case MFF_IPV4_SRC: return !wc->masks.nw_src; @@ -527,6 +529,7 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value) case MFF_ETH_DST: case MFF_ETH_TYPE: case MFF_VLAN_TCI: + case MFF_MPLS_TTL: case MFF_IPV4_SRC: case MFF_IPV4_DST: case MFF_IPV6_SRC: @@ -741,6 +744,10 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow, value->u8 = mpls_lse_to_bos(flow->mpls_lse[0]); break; + case MFF_MPLS_TTL: + value->u8 = mpls_lse_to_ttl(flow->mpls_lse[0]); + break; + case MFF_IPV4_SRC: value->be32 = flow->nw_src; break; @@ -995,6 +1002,10 @@ mf_set_value(const struct mf_field *mf, match_set_mpls_bos(match, 0, value->u8); break; + case MFF_MPLS_TTL: + match_set_mpls_ttl(match, 0, value->u8); + break; + case MFF_IPV4_SRC: match_set_nw_src(match, value->be32); break; @@ -1301,6 +1312,10 @@ mf_set_flow_value(const struct mf_field *mf, flow_set_mpls_bos(flow, 0, value->u8); break; + case MFF_MPLS_TTL: + flow_set_mpls_ttl(flow, 0, value->u8); + break; + case MFF_IPV4_SRC: flow->nw_src = value->be32; break; @@ -1623,6 +1638,10 @@ mf_set_wild(const struct mf_field *mf, struct match *match, char **err_str) match_set_any_mpls_bos(match, 0); break; + case MFF_MPLS_TTL: + match_set_any_mpls_ttl(match, 0); + break; + case MFF_IPV4_SRC: case MFF_ARP_SPA: match_set_nw_src_masked(match, htonl(0), htonl(0)); @@ -1779,6 +1798,7 @@ mf_set(const struct mf_field *mf, case MFF_MPLS_LABEL: case MFF_MPLS_TC: case MFF_MPLS_BOS: + case MFF_MPLS_TTL: case MFF_IP_PROTO: case MFF_IP_TTL: case MFF_IP_DSCP: diff --git a/lib/meta-flow.h b/lib/meta-flow.h index cb4e22d33..d6ffdfa65 100644 --- a/lib/meta-flow.h +++ b/lib/meta-flow.h @@ -1144,6 +1144,21 @@ enum OVS_PACKED_ENUM mf_field_id { */ MFF_MPLS_BOS, + /* "mpls_ttl". + * + * The outermost MPLS label's time-to-live (TTL) field, or 0 if no MPLS + * labels are present. + * + * Type: u8. + * Maskable: no. + * Formatting: decimal. + * Prerequisites: MPLS. + * Access: read/write. + * NXM: NXM_NX_MPLS_TTL(30) since v2.6. + * OXM: none. + */ + MFF_MPLS_TTL, + /* ## ---- ## */ /* ## IPv4 ## */ /* ## ---- ## */ diff --git a/tests/ofproto.at b/tests/ofproto.at index 880fbc051..5d82ff911 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -1777,7 +1777,7 @@ head_table () { actions: output group set_field strip_vlan push_vlan mod_nw_ttl dec_ttl set_mpls_ttl dec_mpls_ttl push_mpls pop_mpls set_queue supported on Set-Field: tun_id tun_src tun_dst tun_ipv6_src tun_ipv6_dst tun_flags tun_gbp_id tun_gbp_flags tun_metadata0 dnl tun_metadata1 tun_metadata2 tun_metadata3 tun_metadata4 tun_metadata5 tun_metadata6 tun_metadata7 tun_metadata8 tun_metadata9 tun_metadata10 tun_metadata11 tun_metadata12 tun_metadata13 tun_metadata14 tun_metadata15 tun_metadata16 tun_metadata17 tun_metadata18 tun_metadata19 tun_metadata20 tun_metadata21 tun_metadata22 tun_metadata23 tun_metadata24 tun_metadata25 tun_metadata26 tun_metadata27 tun_metadata28 tun_metadata29 tun_metadata30 tun_metadata31 tun_metadata32 tun_metadata33 tun_metadata34 tun_metadata35 tun_metadata36 tun_metadata37 tun_metadata38 tun_metadata39 tun_metadata40 tun_metadata41 tun_metadata42 tun_metadata43 tun_metadata44 tun_metadata45 tun_metadata46 tun_metadata47 tun_metadata48 tun_metadata49 tun_metadata50 tun_metadata51 tun_metadata52 tun_metadata53 tun_metadata54 tun_metadata55 tun_metadata56 tun_metadata57 tun_metadata58 tun_metadata59 tun_metadata60 tun_metadata61 tun_metadata62 tun_metadata63 dnl -metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 xreg0 xreg1 xreg2 xreg3 eth_src eth_dst vlan_tci vlan_vid vlan_pcp mpls_label mpls_tc ip_src ip_dst ipv6_src ipv6_dst ipv6_label nw_tos ip_dscp nw_ecn nw_ttl arp_op arp_spa arp_tpa arp_sha arp_tha tcp_src tcp_dst udp_src udp_dst sctp_src sctp_dst icmp_type icmp_code icmpv6_type icmpv6_code nd_target nd_sll nd_tll +metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 xreg0 xreg1 xreg2 xreg3 eth_src eth_dst vlan_tci vlan_vid vlan_pcp mpls_label mpls_tc mpls_ttl ip_src ip_dst ipv6_src ipv6_dst ipv6_label nw_tos ip_dscp nw_ecn nw_ttl arp_op arp_spa arp_tpa arp_sha arp_tha tcp_src tcp_dst udp_src udp_dst sctp_src sctp_dst icmp_type icmp_code icmpv6_type icmpv6_code nd_target nd_sll nd_tll matching: dp_hash: arbitrary mask recirc_id: exact match or wildcard @@ -1884,6 +1884,7 @@ metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4 mpls_label: exact match or wildcard mpls_tc: exact match or wildcard mpls_bos: exact match or wildcard + mpls_ttl: exact match or wildcard ip_src: arbitrary mask ip_dst: arbitrary mask ipv6_src: arbitrary mask -- 2.20.1