@@ -5072,8 +5072,58 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
ctx_trigger_freeze(ctx);
a = ofpact_next(a);
break;
- case OFPACT_PUSH_NSH:
+ case OFPACT_PUSH_NSH: {
+ struct ovs_action_push_nsh push;
+ struct nsh_header *nsh = (struct nsh_header *)push.header;
+ //int md_len = 0;
+ //bool crit_opt;
+
+ if (flow->nsh.md_type == NSH_MD_TYPE1) {
+ struct nsh_md1_ctx *ctx = NULL;
+
+ nsh->base.flags = flow->nsh.flags;
+ nsh->base.length = NSH_TYPE1_LEN >> 2;
+ nsh->base.md_type = NSH_MD_TYPE1;
+ nsh->base.next_proto = flow->nsh.next_proto;
+ nsh->base.sfp = (flow->nsh.nsp >> 8) | (flow->nsh.nsi << 24);
+
+ ctx = (struct nsh_md1_ctx *)(nsh + 1);
+ ctx->nshc1 = flow->nsh.nshc1;
+ ctx->nshc2 = flow->nsh.nshc2;
+ ctx->nshc3 = flow->nsh.nshc3;
+ ctx->nshc4 = flow->nsh.nshc4;
+
+ push.len = NSH_TYPE1_LEN;
+#if 0
+ } else if (flow->nsh.md_type == NSH_MD_TYPE2) {
+ /* MD type 2 prototype with TUN_METADATA APIs. */
+ struct nsh_md2_ctx *ctx = NULL;
+
+ nsh->base.md_type = NSH_MD_TYPE2;
+ nsh->base.next_proto = flow->nsh.next_proto;
+ nsh->base.sfp = (flow->nsh.nsp >> 8) | (flow->nsh.nsi << 24);
+
+ ctx = (struct nsh_md2_ctx *)(nsh + 1);
+ md_len = tun_metadata_to_geneve_header(&flow->tunnel,
+ (struct geneve_opt *)ctx,
+ &crit_opt);
+ nsh->base.length = (sizeof(struct nsh_header) + md_len) >> 2;
+ push.len = md_len + sizeof(struct nsh_header);
+#endif
+ }
+
+ nl_msg_put_unspec(ctx->odp_actions, OVS_ACTION_ATTR_PUSH_NSH,
+ &push, sizeof push);
+
+ flow->dl_type = htons(ETH_TYPE_NSH);
+ memset(&wc->masks.nsh.md_type, 0xff, sizeof wc->masks.nsh.md_type);
+ break;
+ }
+
case OFPACT_POP_NSH:
+ memset(&wc->masks.nsh.md_type, 0xff, sizeof wc->masks.nsh.md_type);
+ memset(&flow->nsh, 0x0, sizeof flow->nsh);
+ nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_POP_NSH);
break;
}
Signed-off-by: Johnson Li <johnson.li@intel.com>