[ovs-dev] [PATCH 4/4] openflow: Support matching and modifying MPLS TTL field.

Ben Pfaff blp at ovn.org
Mon Mar 7 19:18:57 UTC 2016


Occasionally we get asked about this and I don't see a reason not to
support it.

Signed-off-by: Ben Pfaff <blp at ovn.org>
---
 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 6d71df7..38f6b56 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 95d34bc..17ef752 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 MPLS TTL 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 with an MPLS header whose
+ * TTL 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 650a203..0a6ac29 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 16b9c92..6c899e1 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 cb4e22d..3297154 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-level (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 880fbc0..5d82ff9 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.1.3




More information about the dev mailing list