Skip to content

Commit

Permalink
Generic encap and decap support for NSH
Browse files Browse the repository at this point in the history
This commit adds translation and netdev datapath support for generic
encap and decap actions for the NSH MD1 header. The generic encap and
decap actions are mapped to specific encap_nsh and decap_nsh actions
in the datapath.

The translation follows that general scheme that decap() of an NSH
packet triggers recirculation after decapsulation, while encap(nsh)
just modifies struct flow and sets the ctx->pending_encap flag to
generate the encap_nsh action at the next commit to be able to include
subsequent set_field actions for NSH headers.

Support for the flexible MD2 format using TLV properties is foreseen
in encap(nsh), but not yet fully implemented.

The CLI syntax for encap of NSH is
encap(nsh(md_type=1))
encap(nsh(md_type=2[,tlv(<tlv_class>,<tlv_type>,<hex_string>),...]))

Signed-off-by: Jan Scheurich <jan.scheurich@ericsson.com>
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
  • Loading branch information
JanScheurich authored and blp committed Aug 7, 2017
1 parent 478b147 commit 1fc11c5
Show file tree
Hide file tree
Showing 14 changed files with 788 additions and 36 deletions.
23 changes: 23 additions & 0 deletions datapath/linux/compat/include/linux/openvswitch.h
Expand Up @@ -793,6 +793,25 @@ struct ovs_action_push_eth {
struct ovs_key_ethernet addresses;
};

#define OVS_ENCAP_NSH_MAX_MD_LEN 16
/*
* struct ovs_action_encap_nsh - %OVS_ACTION_ATTR_ENCAP_NSH
* @flags: NSH header flags.
* @mdtype: NSH metadata type.
* @mdlen: Length of NSH metadata in bytes.
* @np: NSH next_protocol: Inner packet type.
* @path_hdr: NSH service path id and service index.
* @metadata: NSH metadata for MD type 1 or 2
*/
struct ovs_action_encap_nsh {
uint8_t flags;
uint8_t mdtype;
uint8_t mdlen;
uint8_t np;
__be32 path_hdr;
uint8_t metadata[OVS_ENCAP_NSH_MAX_MD_LEN];
};

/**
* enum ovs_nat_attr - Attributes for %OVS_CT_ATTR_NAT.
*
Expand Down Expand Up @@ -868,6 +887,8 @@ enum ovs_nat_attr {
* @OVS_ACTION_ATTR_PUSH_ETH: Push a new outermost Ethernet header onto the
* packet.
* @OVS_ACTION_ATTR_POP_ETH: Pop the outermost Ethernet header off the packet.
* @OVS_ACTION_ATTR_ENCAP_NSH: encap NSH action to push NSH header.
* @OVS_ACTION_ATTR_DECAP_NSH: decap NSH action to remove NSH header.
*
* Only a single header can be set with a single %OVS_ACTION_ATTR_SET. Not all
* fields within a header are modifiable, e.g. the IPv4 protocol and fragment
Expand Down Expand Up @@ -909,6 +930,8 @@ enum ovs_action_attr {
OVS_ACTION_ATTR_TUNNEL_POP, /* u32 port number. */
OVS_ACTION_ATTR_CLONE, /* Nested OVS_CLONE_ATTR_*. */
OVS_ACTION_ATTR_METER, /* u32 meter number. */
OVS_ACTION_ATTR_ENCAP_NSH, /* struct ovs_action_encap_nsh. */
OVS_ACTION_ATTR_DECAP_NSH, /* No argument. */
#endif
__OVS_ACTION_ATTR_MAX, /* Nothing past this will be accepted
* from userspace. */
Expand Down
44 changes: 41 additions & 3 deletions include/openvswitch/ofp-ed-props.h
Expand Up @@ -27,9 +27,10 @@ extern "C" {

enum ofp_ed_prop_class {
OFPPPC_BASIC = 0, /* ONF Basic class. */
OFPPPC_MPLS = 1, /* MPLS property class. */
OFPPPC_GRE = 2, /* GRE property class. */
OFPPPC_GTP = 3, /* GTP property class. */
OFPPPC_MPLS = 1, /* MPLS property class. */
OFPPPC_GRE = 2, /* GRE property class. */
OFPPPC_GTP = 3, /* GTP property class. */
OFPPPC_NSH = 4, /* NSH property class */

/* Experimenter property class.
*
Expand All @@ -39,6 +40,12 @@ enum ofp_ed_prop_class {
OFPPPC_EXPERIMENTER=0xffff
};

enum ofp_ed_nsh_prop_type {
OFPPPT_PROP_NSH_NONE = 0, /* unused */
OFPPPT_PROP_NSH_MDTYPE = 1, /* property MDTYPE in NSH */
OFPPPT_PROP_NSH_TLV = 2, /* property TLV in NSH */
};

/*
* External representation of encap/decap properties.
* These must be padded to a multiple of 8 bytes.
Expand All @@ -49,6 +56,22 @@ struct ofp_ed_prop_header {
uint8_t len;
};

struct ofp_ed_prop_nsh_md_type {
struct ofp_ed_prop_header header;
uint8_t md_type; /* NSH MD type .*/
uint8_t pad[3]; /* Padding to 8 bytes. */
};

struct ofp_ed_prop_nsh_tlv {
struct ofp_ed_prop_header header;
ovs_be16 tlv_class; /* Metadata class. */
uint8_t tlv_type; /* Metadata type including C bit. */
uint8_t tlv_len; /* Metadata value length (0-127). */

/* tlv_len octets of metadata value, padded to a multiple of 8 bytes. */
uint8_t data[0];
};

/*
* Internal representation of encap/decap properties
*/
Expand All @@ -58,6 +81,21 @@ struct ofpact_ed_prop {
uint8_t len;
};

struct ofpact_ed_prop_nsh_md_type {
struct ofpact_ed_prop header;
uint8_t md_type; /* NSH MD type .*/
uint8_t pad[3]; /* Padding to 8 bytes. */
};

struct ofpact_ed_prop_nsh_tlv {
struct ofpact_ed_prop header;
ovs_be16 tlv_class; /* Metadata class. */
uint8_t tlv_type; /* Metadata type including C bit. */
uint8_t tlv_len; /* Metadata value length (0-127). */

/* tlv_len octets of metadata value, padded to a multiple of 8 bytes. */
uint8_t data[0];
};
enum ofperr decode_ed_prop(const struct ofp_ed_prop_header **ofp_prop,
struct ofpbuf *out, size_t *remaining);
enum ofperr encode_ed_prop(const struct ofpact_ed_prop **prop,
Expand Down
2 changes: 2 additions & 0 deletions lib/dpif-netdev.c
Expand Up @@ -5407,6 +5407,8 @@ dp_execute_cb(void *aux_, struct dp_packet_batch *packets_,
case OVS_ACTION_ATTR_PUSH_ETH:
case OVS_ACTION_ATTR_POP_ETH:
case OVS_ACTION_ATTR_CLONE:
case OVS_ACTION_ATTR_ENCAP_NSH:
case OVS_ACTION_ATTR_DECAP_NSH:
case __OVS_ACTION_ATTR_MAX:
OVS_NOT_REACHED();
}
Expand Down
2 changes: 2 additions & 0 deletions lib/dpif.c
Expand Up @@ -1255,6 +1255,8 @@ dpif_execute_helper_cb(void *aux_, struct dp_packet_batch *packets_,
case OVS_ACTION_ATTR_PUSH_ETH:
case OVS_ACTION_ATTR_POP_ETH:
case OVS_ACTION_ATTR_CLONE:
case OVS_ACTION_ATTR_ENCAP_NSH:
case OVS_ACTION_ATTR_DECAP_NSH:
case OVS_ACTION_ATTR_UNSPEC:
case __OVS_ACTION_ATTR_MAX:
OVS_NOT_REACHED();
Expand Down
32 changes: 26 additions & 6 deletions lib/odp-execute.c
Expand Up @@ -289,10 +289,9 @@ odp_set_nsh(struct dp_packet *packet, const struct ovs_key_nsh *key,
}
break;
case NSH_M_TYPE2:
/* TODO */
break;
default:
OVS_NOT_REACHED();
/* No support for setting any other metadata format yet. */
break;
}
} else {
uint8_t flags = (ntohs(nsh->ver_flags_len) & NSH_FLAGS_MASK) >>
Expand All @@ -314,10 +313,9 @@ odp_set_nsh(struct dp_packet *packet, const struct ovs_key_nsh *key,
}
break;
case NSH_M_TYPE2:
/* TODO */
break;
default:
OVS_NOT_REACHED();
/* No support for setting any other metadata format yet. */
break;
}
}
}
Expand Down Expand Up @@ -654,6 +652,8 @@ requires_datapath_assistance(const struct nlattr *a)
case OVS_ACTION_ATTR_PUSH_ETH:
case OVS_ACTION_ATTR_POP_ETH:
case OVS_ACTION_ATTR_CLONE:
case OVS_ACTION_ATTR_ENCAP_NSH:
case OVS_ACTION_ATTR_DECAP_NSH:
return false;

case OVS_ACTION_ATTR_UNSPEC:
Expand Down Expand Up @@ -818,6 +818,26 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,
}
break;

case OVS_ACTION_ATTR_ENCAP_NSH: {
const struct ovs_action_encap_nsh *enc_nsh = nl_attr_get(a);
DP_PACKET_BATCH_FOR_EACH (packet, batch) {
encap_nsh(packet, enc_nsh);
}
break;
}
case OVS_ACTION_ATTR_DECAP_NSH: {
size_t i, num = batch->count;

DP_PACKET_BATCH_REFILL_FOR_EACH (i, num, packet, batch) {
if (decap_nsh(packet)) {
dp_packet_batch_refill(batch, packet, i);
} else {
dp_packet_delete(packet);
}
}
break;
}

case OVS_ACTION_ATTR_OUTPUT:
case OVS_ACTION_ATTR_TUNNEL_PUSH:
case OVS_ACTION_ATTR_TUNNEL_POP:
Expand Down

0 comments on commit 1fc11c5

Please sign in to comment.