[ovs-dev] [PATCH 3/4] User-Space MPLS actions and matches

Isaku Yamahata yamahata at valinux.co.jp
Fri Oct 26 08:22:13 UTC 2012


On Thu, Oct 18, 2012 at 06:02:20PM +0900, Simon Horman wrote:
> diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
> index 1fb0304..13eb367 100644
> --- a/lib/ofp-actions.c
> +++ b/lib/ofp-actions.c
> @@ -378,6 +378,26 @@ ofpact_from_nxast(const union ofp_action *a, enum ofputil_action_code code,
>      case OFPUTIL_NXAST_CONTROLLER:
>          controller_from_openflow((const struct nx_action_controller *) a, out);
>          break;
> +
> +    case OFPUTIL_NXAST_PUSH_MPLS: {
> +        struct nx_action_push *nxap = (struct nx_action_push *)a;
> +        if (nxap->ethertype != htons(ETH_TYPE_MPLS) &&
> +            nxap->ethertype != htons(ETH_TYPE_MPLS_MCAST)) {
> +            return OFPERR_OFPBAC_BAD_ARGUMENT;
> +        }
> +        ofpact_put_PUSH_MPLS(out)->ethertype = nxap->ethertype;
> +        break;
> +    }
> +
> +    case OFPUTIL_NXAST_POP_MPLS: {
> +        struct nx_action_pop_mpls *nxapm = (struct nx_action_pop_mpls *)a;
> +        if (nxapm->ethertype == htons(ETH_TYPE_MPLS) ||
> +            nxapm->ethertype == htons(ETH_TYPE_MPLS_MCAST)) {
> +            return OFPERR_OFPBAC_BAD_ARGUMENT;
> +        }
> +        ofpact_put_POP_MPLS(out)->ethertype = nxapm->ethertype;
> +        break;
> +    }
>      }
>  
>      return error;
> @@ -722,6 +742,26 @@ ofpact_from_openflow11(const union ofp_action *a, struct ofpbuf *out)
>          return nxm_reg_load_from_openflow12_set_field(
>              (const struct ofp12_action_set_field *)a, out);
>  
> +    case OFPUTIL_OFPAT11_PUSH_MPLS: {
> +        struct ofp11_action_push *oap = (struct ofp11_action_push *)a;
> +        if (oap->ethertype != htons(ETH_TYPE_MPLS) &&
> +            oap->ethertype != htons(ETH_TYPE_MPLS_MCAST)) {
> +            return OFPERR_OFPBAC_BAD_ARGUMENT;
> +        }
> +        ofpact_put_PUSH_MPLS(out)->ethertype = oap->ethertype;
> +        break;
> +    }
> +
> +    case OFPUTIL_OFPAT11_POP_MPLS: {
> +        struct ofp11_action_pop_mpls *oapm = (struct ofp11_action_pop_mpls *)a;
> +        if (oapm->ethertype == htons(ETH_TYPE_MPLS) ||
> +            oapm->ethertype == htons(ETH_TYPE_MPLS_MCAST)) {
> +            return OFPERR_OFPBAC_BAD_ARGUMENT;
> +        }
> +        ofpact_put_POP_MPLS(out)->ethertype = oapm->ethertype;
> +        break;
> +    }
> +
>  #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
>  #include "ofp-util.def"
>          return ofpact_from_nxast(a, code, out);
> @@ -1052,6 +1092,8 @@ ofpact_check__(const struct ofpact *a, int max_ports)
>  
>      case OFPACT_NOTE:
>      case OFPACT_EXIT:
> +    case OFPACT_PUSH_MPLS:
> +    case OFPACT_POP_MPLS:
>          return 0;
>  
>      case OFPACT_CLEAR_ACTIONS:
> @@ -1260,6 +1302,16 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
>          ofputil_put_NXAST_EXIT(out);
>          break;
>  
> +    case OFPACT_PUSH_MPLS:
> +        ofputil_put_NXAST_PUSH_MPLS(out)->ethertype =
> +            ofpact_get_PUSH_MPLS(a)->ethertype;
> +        break;
> +
> +    case OFPACT_POP_MPLS:
> +        ofputil_put_NXAST_POP_MPLS(out)->ethertype =
> +            ofpact_get_POP_MPLS(a)->ethertype;
> +        break;
> +
>      case OFPACT_OUTPUT:
>      case OFPACT_ENQUEUE:
>      case OFPACT_SET_VLAN_VID:
> @@ -1384,6 +1436,8 @@ ofpact_to_openflow10(const struct ofpact *a, struct ofpbuf *out)
>      case OFPACT_AUTOPATH:
>      case OFPACT_NOTE:
>      case OFPACT_EXIT:
> +    case OFPACT_PUSH_MPLS:
> +    case OFPACT_POP_MPLS:
>          ofpact_to_nxast(a, out);
>          break;
>      }
> @@ -1476,6 +1530,16 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
>              = htons(ofpact_get_SET_L4_DST_PORT(a)->port);
>          break;
>  
> +    case OFPACT_PUSH_MPLS:
> +        ofputil_put_OFPAT11_PUSH_MPLS(out)->ethertype =
> +            ofpact_get_PUSH_MPLS(a)->ethertype;
> +        break;
> +
> +    case OFPACT_POP_MPLS:
> +        ofputil_put_OFPAT11_POP_MPLS(out)->ethertype =
> +            ofpact_get_POP_MPLS(a)->ethertype;
> +        break;
> +
>      case OFPACT_CLEAR_ACTIONS:
>      case OFPACT_GOTO_TABLE:
>          NOT_REACHED();

Even when NX MPLS actions is used, retrieved actions always results in
OF1.1+ MPLS actions. We can keep it easily.

Set ofpact->compat = OFPUTIL_NX_xxx_MPLS in ofpact_from_nxact().
And then
if (a->compat == OFPUTIL_NXAST_xxx_MPLS) {
    NX MPLS action
} else {
    OF11+ MPLS action
}
-- 
yamahata



More information about the dev mailing list