[ovs-dev] [PATCH v2 07/10] netdev-offload-tc: Add conntrack label and mark support

Marcelo Ricardo Leitner mleitner at redhat.com
Wed Nov 27 15:06:39 UTC 2019


On Wed, Nov 27, 2019 at 02:55:13PM +0200, Roi Dayan wrote:
> From: Paul Blakey <paulb at mellanox.com>
> 
> Signed-off-by: Paul Blakey <paulb at mellanox.com>
> ---
>  lib/dpif-netlink.c      |  2 ++
>  lib/netdev-offload-tc.c | 66 +++++++++++++++++++++++++++++++++++++++++--------
>  lib/tc.c                | 52 ++++++++++++++++++++++++++++++++++++++
>  lib/tc.h                |  6 +++++
>  4 files changed, 116 insertions(+), 10 deletions(-)
> 
> diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
> index 620e94ea4bfc..22ba7cb360fb 100644
> --- a/lib/dpif-netlink.c
> +++ b/lib/dpif-netlink.c
> @@ -1603,6 +1603,8 @@ dpif_netlink_netdev_match_to_dpif_flow(struct match *match,
>              .recirc = true,
>              .ct_state = true,
>              .ct_zone = true,
> +            .ct_mark = true,
> +            .ct_label = true,
>          },
>      };
>      size_t offset;
> diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
> index 8dd48ab7c421..2b4ecfb9ca48 100644
> --- a/lib/netdev-offload-tc.c
> +++ b/lib/netdev-offload-tc.c
> @@ -623,6 +623,8 @@ parse_tc_flower_to_match(struct tc_flower *flower,
>          }
>  
>          match_set_ct_zone_masked(match, key->ct_zone, mask->ct_zone);
> +        match_set_ct_mark_masked(match, key->ct_mark, mask->ct_mark);
> +        match_set_ct_label_masked(match, key->ct_label, mask->ct_label);
>      }
>  
>      if (flower->tunnel) {
> @@ -792,6 +794,26 @@ parse_tc_flower_to_match(struct tc_flower *flower,
>                      nl_msg_put_u16(buf, OVS_CT_ATTR_ZONE, action->ct.zone);
>                  }
>  
> +                if (action->ct.mark_mask) {
> +                    uint32_t mark_and_mask[2] = { action->ct.mark,
> +                                                  action->ct.mark_mask };
> +                    nl_msg_put_unspec(buf, OVS_CT_ATTR_MARK, &mark_and_mask,
> +                                      sizeof mark_and_mask);
> +                }
> +
> +                if (!ovs_u128_is_zero(action->ct.label_mask)) {
> +                    struct {
> +                        ovs_u128 key;
> +                        ovs_u128 mask;
> +                    } *ct_label;
> +
> +                    ct_label = nl_msg_put_unspec_uninit(buf,
> +                                                        OVS_CT_ATTR_LABELS,
> +                                                        sizeof *ct_label);
> +                    ct_label->key = action->ct.label;
> +                    ct_label->mask = action->ct.label_mask;
> +                }
> +
>                  nl_msg_end_nested(buf, ct_offset);
>              }
>              break;
> @@ -903,6 +925,28 @@ parse_put_flow_ct_action(struct tc_flower *flower,
>                      action->ct.zone = nl_attr_get_u16(ct_attr);
>                  }
>                  break;
> +                case OVS_CT_ATTR_MARK: {
> +                    const struct {
> +                        uint32_t key;
> +                        uint32_t mask;
> +                    } *ct_mark;
> +
> +                    ct_mark = nl_attr_get_unspec(ct_attr, sizeof *ct_mark);
> +                    action->ct.mark = ct_mark->key;
> +                    action->ct.mark_mask = ct_mark->mask;
> +                }
> +                break;
> +                case OVS_CT_ATTR_LABELS: {
> +                    const struct {
> +                        ovs_u128 key;
> +                        ovs_u128 mask;
> +                    } *ct_label;
> +
> +                    ct_label = nl_attr_get_unspec(ct_attr, sizeof *ct_label);
> +                    action->ct.label = ct_label->key;
> +                    action->ct.label_mask = ct_label->mask;
> +                }
> +                break;
>              }
>          }
>  
> @@ -1093,22 +1137,12 @@ test_key_and_mask(struct match *match)
>          return EOPNOTSUPP;
>      }
>  
> -    if (mask->ct_mark) {
> -        VLOG_DBG_RL(&rl, "offloading attribute ct_mark isn't supported");
> -        return EOPNOTSUPP;
> -    }
> -
>      if (mask->packet_type && key->packet_type) {
>          VLOG_DBG_RL(&rl, "offloading attribute packet_type isn't supported");
>          return EOPNOTSUPP;
>      }
>      mask->packet_type = 0;
>  
> -    if (!ovs_u128_is_zero(mask->ct_label)) {
> -        VLOG_DBG_RL(&rl, "offloading attribute ct_label isn't supported");
> -        return EOPNOTSUPP;
> -    }
> -
>      for (int i = 0; i < FLOW_N_REGS; i++) {
>          if (mask->regs[i]) {
>              VLOG_DBG_RL(&rl,
> @@ -1467,6 +1501,18 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
>          mask->ct_zone = 0;
>      }
>  
> +    if (mask->ct_mark) {
> +        flower.key.ct_mark = key->ct_mark;
> +        flower.mask.ct_mark = mask->ct_mark;
> +        mask->ct_mark = 0;
> +    }
> +
> +    if (!ovs_u128_is_zero(mask->ct_label)) {
> +        flower.key.ct_label = key->ct_label;
> +        flower.mask.ct_label = mask->ct_label;
> +        mask->ct_label = OVS_U128_ZERO;
> +    }
> +
>      err = test_key_and_mask(match);
>      if (err) {
>          return err;
> diff --git a/lib/tc.c b/lib/tc.c
> index 841552e1e4a6..1062326d4b86 100644
> --- a/lib/tc.c
> +++ b/lib/tc.c
> @@ -404,6 +404,11 @@ static const struct nl_policy tca_flower_policy[] = {
>      [TCA_FLOWER_KEY_CT_STATE_MASK] = { .type = NL_A_U16, .optional = true, },
>      [TCA_FLOWER_KEY_CT_ZONE] = { .type = NL_A_U16, .optional = true, },
>      [TCA_FLOWER_KEY_CT_ZONE_MASK] = { .type = NL_A_U16, .optional = true, },
> +    [TCA_FLOWER_KEY_CT_MARK] = { .type = NL_A_U32, .optional = true, },
> +    [TCA_FLOWER_KEY_CT_MARK_MASK] = { .type = NL_A_U32, .optional = true, },
> +    [TCA_FLOWER_KEY_CT_LABELS] = { .type = NL_A_U128, .optional = true, },
> +    [TCA_FLOWER_KEY_CT_LABELS_MASK] = { .type = NL_A_U128,
> +                                        .optional = true, },
>  };
>  
>  static void
> @@ -726,6 +731,20 @@ nl_parse_flower_ct_match(struct nlattr **attrs, struct tc_flower *flower) {
>          key->ct_zone = nl_attr_get_u16(attr_key);
>          mask->ct_zone = nl_attr_get_u16(attr_mask);
>      }
> +
> +    attr_key = attrs[TCA_FLOWER_KEY_CT_MARK];
> +    attr_mask = attrs[TCA_FLOWER_KEY_CT_MARK_MASK];
> +    if (attrs[TCA_FLOWER_KEY_CT_MARK_MASK]) {
> +        key->ct_mark = nl_attr_get_u32(attr_key);
> +        mask->ct_mark = nl_attr_get_u32(attr_mask);
> +    }
> +
> +    attr_key = attrs[TCA_FLOWER_KEY_CT_LABELS];
> +    attr_mask = attrs[TCA_FLOWER_KEY_CT_LABELS_MASK];
> +    if (attrs[TCA_FLOWER_KEY_CT_LABELS_MASK]) {
> +        key->ct_label = nl_attr_get_u128(attr_key);
> +        mask->ct_label = nl_attr_get_u128(attr_mask);
> +    }
>  }
>  
>  static void
> @@ -1255,6 +1274,14 @@ static const struct nl_policy ct_policy[] = {
>                           .optional = true, },
>      [TCA_CT_ZONE] = { .type = NL_A_U16,
>                        .optional = true, },
> +    [TCA_CT_MARK] = { .type = NL_A_U32,
> +                       .optional = true, },
> +    [TCA_CT_MARK_MASK] = { .type = NL_A_U32,
> +                            .optional = true, },
> +    [TCA_CT_LABELS] = { .type = NL_A_UNSPEC,
> +                         .optional = true, },
> +    [TCA_CT_LABELS_MASK] = { .type = NL_A_UNSPEC,
> +                              .optional = true, },
>  };
>  
>  static int
> @@ -1283,11 +1310,20 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower)
>      action->ct.clear = ct_action & TCA_CT_ACT_CLEAR;
>      if (!action->ct.clear) {
>          struct nlattr *zone = ct_attrs[TCA_CT_ZONE];
> +        struct nlattr *mark = ct_attrs[TCA_CT_MARK];
> +        struct nlattr *mark_mask = ct_attrs[TCA_CT_MARK_MASK];
> +        struct nlattr *label = ct_attrs[TCA_CT_LABELS];
> +        struct nlattr *label_mask = ct_attrs[TCA_CT_LABELS_MASK];
>  
>          action->ct.commit = ct_action & TCA_CT_ACT_COMMIT;
>          action->ct.force = ct_action & TCA_CT_ACT_FORCE;
>  
>          action->ct.zone = zone ? nl_attr_get_u16(zone) : 0;
> +        action->ct.mark = mark ? nl_attr_get_u32(mark) : 0;
> +        action->ct.mark_mask = mark_mask ? nl_attr_get_u32(mark_mask) : 0;
> +        action->ct.label = label? nl_attr_get_u128(label) : OVS_U128_ZERO;
> +        action->ct.label_mask = label_mask ?
> +                                nl_attr_get_u128(label_mask) : OVS_U128_ZERO;
>  
>      }
>      action->type = TC_ACT_CT;
> @@ -1999,6 +2035,21 @@ nl_msg_put_act_ct(struct ofpbuf *request, struct tc_action *action)
>                  nl_msg_put_u16(request, TCA_CT_ZONE, action->ct.zone);
>              }
>  
> +            if (!is_all_zeros(&action->ct.label_mask,
> +                              sizeof action->ct.label_mask)) {
> +                nl_msg_put_u128(request, TCA_CT_LABELS,
> +                                action->ct.label);
> +                nl_msg_put_u128(request, TCA_CT_LABELS_MASK,
> +                                action->ct.label_mask);
> +            }
> +
> +            if (action->ct.mark_mask) {
> +                nl_msg_put_u32(request, TCA_CT_MARK,
> +                               action->ct.mark);
> +                nl_msg_put_u32(request, TCA_CT_MARK_MASK,
> +                               action->ct.mark_mask);
> +            }
> +
>              if (action->ct.commit) {
>                  ct_action = TCA_CT_ACT_COMMIT;
>                  if (action->ct.force) {
> @@ -2539,6 +2590,7 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
>  
>          FLOWER_PUT_MASKED_VALUE(ct_state, TCA_FLOWER_KEY_CT_STATE);
>          FLOWER_PUT_MASKED_VALUE(ct_zone, TCA_FLOWER_KEY_CT_ZONE);

Why not also?
+        FLOWER_PUT_MASKED_VALUE(ct_mark, TCA_FLOWER_KEY_CT_MARK);

> +        FLOWER_PUT_MASKED_VALUE(ct_label, TCA_FLOWER_KEY_CT_LABELS);
>      }
>  
>      if (host_eth_type == ETH_P_IP) {
> diff --git a/lib/tc.h b/lib/tc.h
> index b1e2174b7369..e853aeb77468 100644
> --- a/lib/tc.h
> +++ b/lib/tc.h
> @@ -118,6 +118,8 @@ struct tc_flower_key {
>  
>      uint16_t ct_state;
>      uint16_t ct_zone;
> +    uint32_t ct_mark;
> +    ovs_u128 ct_label;
>  
>      struct {
>          ovs_be32 ipv4_src;
> @@ -207,6 +209,10 @@ struct tc_action {
>  
>          struct {
>              uint16_t zone;
> +            uint32_t mark;
> +            uint32_t mark_mask;
> +            ovs_u128 label;
> +            ovs_u128 label_mask;
>              bool clear;
>              bool force;
>              bool commit;
> -- 
> 2.8.4
> 



More information about the dev mailing list