diff mbox series

[ovs-dev,v2] lib/tc: add single mpls match offload support

Message ID 1535893669-12143-1-git-send-email-pieter.jansenvanvuuren@netronome.com
State Superseded
Headers show
Series [ovs-dev,v2] lib/tc: add single mpls match offload support | expand

Commit Message

Pieter Jansen van Vuuren Sept. 2, 2018, 1:07 p.m. UTC
Add TC offload support for classifying single MPLS tagged traffic.

Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: John Hurley <john.hurley@netronome.com>
---
 lib/netdev-tc-offloads.c | 14 ++++++--
 lib/tc.c                 | 69 ++++++++++++++++++++++++++++++++++++++++
 lib/tc.h                 |  1 +
 3 files changed, 82 insertions(+), 2 deletions(-)

Comments

Simon Horman Sept. 3, 2018, 9:22 a.m. UTC | #1
On Sun, Sep 02, 2018 at 02:07:49PM +0100, Pieter Jansen van Vuuren wrote:
> Add TC offload support for classifying single MPLS tagged traffic.
> 
> Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
> Reviewed-by: Simon Horman <simon.horman@netronome.com>
> Reviewed-by: John Hurley <john.hurley@netronome.com>

Thanks Pieter,

this looks good to me. I would like to wait a few days to give
other's a chance to review this patch before applying.
Simon Horman Sept. 7, 2018, 1:08 p.m. UTC | #2
On Mon, Sep 03, 2018 at 11:22:00AM +0200, Simon Horman wrote:
> On Sun, Sep 02, 2018 at 02:07:49PM +0100, Pieter Jansen van Vuuren wrote:
> > Add TC offload support for classifying single MPLS tagged traffic.
> > 
> > Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
> > Reviewed-by: Simon Horman <simon.horman@netronome.com>
> > Reviewed-by: John Hurley <john.hurley@netronome.com>
> 
> Thanks Pieter,
> 
> this looks good to me. I would like to wait a few days to give
> other's a chance to review this patch before applying.

Thanks again Pieter, applied to master.
diff mbox series

Patch

diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c
index 7bc745e95..a12bc4c39 100644
--- a/lib/netdev-tc-offloads.c
+++ b/lib/netdev-tc-offloads.c
@@ -446,6 +446,10 @@  parse_tc_flower_to_match(struct tc_flower *flower,
             match_set_dl_type(match, key->encap_eth_type[0]);
         }
         flow_fix_vlan_tpid(&match->flow);
+    } else if (eth_type_mpls(key->eth_type)) {
+        match->flow.mpls_lse[0] = key->mpls_lse & mask->mpls_lse;
+        match->wc.masks.mpls_lse[0] = mask->mpls_lse;
+        match_set_dl_type(match, key->encap_eth_type[0]);
     } else {
         match_set_dl_type(match, key->eth_type);
     }
@@ -875,9 +879,9 @@  test_key_and_mask(struct match *match)
         return EOPNOTSUPP;
     }
 
-    for (int i = 0; i < FLOW_MAX_MPLS_LABELS; i++) {
+    for (int i = 1; i < FLOW_MAX_MPLS_LABELS; i++) {
         if (mask->mpls_lse[i]) {
-            VLOG_DBG_RL(&rl, "offloading attribute mpls_lse isn't supported");
+            VLOG_DBG_RL(&rl, "offloading multiple mpls_lses isn't supported");
             return EOPNOTSUPP;
         }
     }
@@ -979,6 +983,12 @@  netdev_tc_flow_put(struct netdev *netdev, struct match *match,
 
     flower.key.eth_type = key->dl_type;
     flower.mask.eth_type = mask->dl_type;
+    if (mask->mpls_lse[0]) {
+        flower.key.mpls_lse = key->mpls_lse[0];
+        flower.mask.mpls_lse = mask->mpls_lse[0];
+        flower.key.encap_eth_type[0] = flower.key.eth_type;
+    }
+    mask->mpls_lse[0] = 0;
 
     if (mask->vlans[0].tci) {
         ovs_be16 vid_mask = mask->vlans[0].tci & htons(VLAN_VID_MASK);
diff --git a/lib/tc.c b/lib/tc.c
index bbc382326..ede683c4e 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -272,6 +272,10 @@  static const struct nl_policy tca_flower_policy[] = {
     [TCA_FLOWER_KEY_SCTP_DST] = { .type = NL_A_U16, .optional = true, },
     [TCA_FLOWER_KEY_SCTP_SRC_MASK] = { .type = NL_A_U16, .optional = true, },
     [TCA_FLOWER_KEY_SCTP_DST_MASK] = { .type = NL_A_U16, .optional = true, },
+    [TCA_FLOWER_KEY_MPLS_TTL] = { .type = NL_A_U8, .optional = true, },
+    [TCA_FLOWER_KEY_MPLS_TC] = { .type = NL_A_U8, .optional = true, },
+    [TCA_FLOWER_KEY_MPLS_BOS] = { .type = NL_A_U8, .optional = true, },
+    [TCA_FLOWER_KEY_MPLS_LABEL] = { .type = NL_A_U32, .optional = true, },
     [TCA_FLOWER_KEY_VLAN_ID] = { .type = NL_A_U16, .optional = true, },
     [TCA_FLOWER_KEY_VLAN_PRIO] = { .type = NL_A_U8, .optional = true, },
     [TCA_FLOWER_KEY_VLAN_ETH_TYPE] = { .type = NL_A_U16, .optional = true, },
@@ -344,6 +348,46 @@  nl_parse_flower_eth(struct nlattr **attrs, struct tc_flower *flower)
     }
 }
 
+static void
+nl_parse_flower_mpls(struct nlattr **attrs, struct tc_flower *flower)
+{
+    uint8_t ttl, tc, bos;
+    uint32_t label;
+
+    if (!eth_type_mpls(flower->key.eth_type)) {
+        return;
+    }
+
+    flower->key.encap_eth_type[0] =
+        nl_attr_get_be16(attrs[TCA_FLOWER_KEY_ETH_TYPE]);
+    flower->key.mpls_lse = 0;
+    flower->mask.mpls_lse = 0;
+
+    if (attrs[TCA_FLOWER_KEY_MPLS_TTL]) {
+        ttl = nl_attr_get_u8(attrs[TCA_FLOWER_KEY_MPLS_TTL]);
+        set_mpls_lse_ttl(&flower->key.mpls_lse, ttl);
+        set_mpls_lse_ttl(&flower->mask.mpls_lse, 0xff);
+    }
+
+    if (attrs[TCA_FLOWER_KEY_MPLS_BOS]) {
+        bos = nl_attr_get_u8(attrs[TCA_FLOWER_KEY_MPLS_BOS]);
+        set_mpls_lse_bos(&flower->key.mpls_lse, bos);
+        set_mpls_lse_ttl(&flower->mask.mpls_lse, 0xff);
+    }
+
+    if (attrs[TCA_FLOWER_KEY_MPLS_TC]) {
+        tc = nl_attr_get_u8(attrs[TCA_FLOWER_KEY_MPLS_TC]);
+        set_mpls_lse_tc(&flower->key.mpls_lse, tc);
+        set_mpls_lse_tc(&flower->mask.mpls_lse, 0xff);
+    }
+
+    if (attrs[TCA_FLOWER_KEY_MPLS_LABEL]) {
+        label = nl_attr_get_u32(attrs[TCA_FLOWER_KEY_MPLS_LABEL]);
+        set_mpls_lse_label(&flower->key.mpls_lse, htonl(label));
+        set_mpls_lse_label(&flower->mask.mpls_lse, OVS_BE32_MAX);
+    }
+}
+
 static void
 nl_parse_flower_vlan(struct nlattr **attrs, struct tc_flower *flower)
 {
@@ -1035,6 +1079,7 @@  nl_parse_flower_options(struct nlattr *nl_options, struct tc_flower *flower)
     }
 
     nl_parse_flower_eth(attrs, flower);
+    nl_parse_flower_mpls(attrs, flower);
     nl_parse_flower_vlan(attrs, flower);
     nl_parse_flower_ip(attrs, flower);
     nl_parse_flower_tunnel(attrs, flower);
@@ -1652,6 +1697,7 @@  nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
     uint16_t host_eth_type = ntohs(flower->key.eth_type);
     bool is_vlan = eth_type_vlan(flower->key.eth_type);
     bool is_qinq = is_vlan && eth_type_vlan(flower->key.encap_eth_type[0]);
+    bool is_mpls = eth_type_mpls(flower->key.eth_type);
     int err;
 
     /* need to parse acts first as some acts require changing the matching
@@ -1669,6 +1715,10 @@  nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
         }
     }
 
+    if (is_mpls) {
+        host_eth_type = ntohs(flower->key.encap_eth_type[0]);
+    }
+
     FLOWER_PUT_MASKED_VALUE(dst_mac, TCA_FLOWER_KEY_ETH_DST);
     FLOWER_PUT_MASKED_VALUE(src_mac, TCA_FLOWER_KEY_ETH_SRC);
 
@@ -1711,6 +1761,25 @@  nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
 
     nl_msg_put_be16(request, TCA_FLOWER_KEY_ETH_TYPE, flower->key.eth_type);
 
+    if (is_mpls) {
+        if (mpls_lse_to_ttl(flower->mask.mpls_lse)) {
+            nl_msg_put_u8(request, TCA_FLOWER_KEY_MPLS_TTL,
+                          mpls_lse_to_ttl(flower->key.mpls_lse));
+        }
+        if (mpls_lse_to_tc(flower->mask.mpls_lse)) {
+            nl_msg_put_u8(request, TCA_FLOWER_KEY_MPLS_TC,
+                          mpls_lse_to_tc(flower->key.mpls_lse));
+        }
+        if (mpls_lse_to_bos(flower->mask.mpls_lse)) {
+            nl_msg_put_u8(request, TCA_FLOWER_KEY_MPLS_BOS,
+                          mpls_lse_to_bos(flower->key.mpls_lse));
+        }
+        if (mpls_lse_to_label(flower->mask.mpls_lse)) {
+            nl_msg_put_u32(request, TCA_FLOWER_KEY_MPLS_LABEL,
+                           mpls_lse_to_label(flower->key.mpls_lse));
+        }
+    }
+
     if (is_vlan) {
         if (flower->key.vlan_id[0] || flower->key.vlan_prio[0]) {
             nl_msg_put_u16(request, TCA_FLOWER_KEY_VLAN_ID,
diff --git a/lib/tc.h b/lib/tc.h
index aa8805df2..036aba245 100644
--- a/lib/tc.h
+++ b/lib/tc.h
@@ -78,6 +78,7 @@  struct tc_flower_key {
     struct eth_addr dst_mac;
     struct eth_addr src_mac;
 
+    ovs_be32 mpls_lse;
     ovs_be16 tcp_src;
     ovs_be16 tcp_dst;
     ovs_be16 tcp_flags;