> -----Original Message-----
> From: dev [mailto:dev-boun...@dpdk.org] On Behalf Of Dumitrescu,
> Cristian
> Sent: Monday, October 15, 2018 5:05 PM
> To: Pattan, Reshma <reshma.pat...@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2] net/softnic: add support for flow API
> vxlan encap action
> 
> 
> 
> > -----Original Message-----
> > From: Pattan, Reshma
> > Sent: Monday, October 15, 2018 3:42 PM
> > To: dev@dpdk.org; Dumitrescu, Cristian <cristian.dumitre...@intel.com>
> > Cc: Pattan, Reshma <reshma.pat...@intel.com>
> > Subject: [PATCH v2] net/softnic: add support for flow API vxlan encap
> action
> >
> > Added support to handle vxlan encap action of rte flow rule.
> >
> > Signed-off-by: Reshma Pattan <reshma.pat...@intel.com>
> > Acked-by: Dumitrescu Cristian <cristian.dumitre...@intel.com>
> > ---
> >  drivers/net/softnic/rte_eth_softnic_flow.c | 192
> > +++++++++++++++++++++
> >  1 file changed, 192 insertions(+)
> >
> > diff --git a/drivers/net/softnic/rte_eth_softnic_flow.c
> > b/drivers/net/softnic/rte_eth_softnic_flow.c
> > index 23ef32969..3a17046b4 100644
> > --- a/drivers/net/softnic/rte_eth_softnic_flow.c
> > +++ b/drivers/net/softnic/rte_eth_softnic_flow.c
> > @@ -1634,6 +1634,198 @@ flow_rule_action_get(struct pmd_internals
> > *softnic,
> >                     break;
> >             } /* RTE_FLOW_ACTION_TYPE_METER */
> >
> > +           case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
> > +           {
> > +                   const struct rte_flow_action_vxlan_encap *conf =
> > +                           action->conf;
> > +                   const struct rte_flow_item *item;
> > +                   union flow_item spec, mask;
> > +                   int disabled = 0, status;
> > +                   size_t size;
> > +
> > +                   if (conf == NULL)
> > +                           return rte_flow_error_set(error,
> > +                                   EINVAL,
> > +                                   RTE_FLOW_ERROR_TYPE_ACTION,
> > +                                   action,
> > +                                   "VXLAN ENCAP: Null configuration");
> > +
> > +                   item = conf->definition;
> > +                   if (item == NULL)
> > +                           return rte_flow_error_set(error,
> > +                                   EINVAL,
> > +                                   RTE_FLOW_ERROR_TYPE_ACTION,
> > +                                   action,
> > +                                   "VXLAN ENCAP: Null configuration
> > definition");
> > +
> > +                   if (!(params->action_mask &
> > +                                   (1LLU <<
> > RTE_TABLE_ACTION_ENCAP)))
> > +                           return rte_flow_error_set(error,
> > +                                   EINVAL,
> > +
> >     RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> > +                                   NULL,
> > +                                   "VXLAN ENCAP: Encap action not
> > enabled for this table");
> > +
> > +                   /* Check for Ether. */
> > +                   flow_item_skip_void(&item);
> > +                   status = flow_item_proto_preprocess(item, &spec,
> > &mask,
> > +                           &size, &disabled, error);
> > +                   if (status)
> > +                           return status;
> > +
> > +                   if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
> > +                           return rte_flow_error_set(error,
> > +                                   EINVAL,
> > +                                   RTE_FLOW_ERROR_TYPE_ITEM,
> > +                                   item,
> > +                                   "VXLAN ENCAP: first encap item
> > should be ether");
> > +                   }
> > +                   ether_addr_copy(&spec.eth.dst,
> > +                                   &rule_action-
> > >encap.vxlan.ether.da);
> > +                   ether_addr_copy(&spec.eth.src,
> > +                                   &rule_action->encap.vxlan.ether.sa);
> > +
> > +                   item++;
> > +
> > +                   /* Check for VLAN. */
> > +                   flow_item_skip_void(&item);
> > +                   status = flow_item_proto_preprocess(item, &spec,
> > &mask,
> > +                                   &size, &disabled, error);
> > +                   if (status)
> > +                           return status;
> > +
> > +                   if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
> > +                           if (!params->encap.vxlan.vlan)
> > +                                   return rte_flow_error_set(error,
> > +                                           ENOTSUP,
> > +
> >     RTE_FLOW_ERROR_TYPE_ITEM,
> > +                                           item,
> > +                                           "VXLAN ENCAP: vlan encap
> > not supported by table");
> > +
> > +                           uint16_t tci = rte_ntohs(spec.vlan.tci);
> > +                           rule_action->encap.vxlan.vlan.pcp =
> > +                                   tci & 0x7;
> > +                           rule_action->encap.vxlan.vlan.dei =
> > +                                   (tci & 0x8) >> 3;
> > +                           rule_action->encap.vxlan.vlan.vid =
> > +                                   tci & 0xfff0;
> 
> rule_action->encap.vxlan.vlan.pcp = tci >> 13;
> rule_action->encap.vxlan.vlan.dei = (tci >> 12) & 0x1;
> rule_action->encap.vxlan.vlan.vid = tci & 0xFFF;
> 
> > +
> > +                           item++;
> > +
> > +                           flow_item_skip_void(&item);
> > +                           status = flow_item_proto_preprocess(item,
> > &spec,
> > +                                           &mask, &size, &disabled,
> > error);
> > +                           if (status)
> > +                                   return status;
> > +                   } else {
> > +                           if (params->encap.vxlan.vlan)
> > +                                   return rte_flow_error_set(error,
> > +                                           ENOTSUP,
> > +
> >     RTE_FLOW_ERROR_TYPE_ITEM,
> > +                                           item,
> > +                                           "VXLAN ENCAP: expecting
> > vlan encap item");
> > +                   }
> > +
> > +                   /* Check for IPV4/IPV6. */
> > +                   switch (item->type) {
> > +                   case RTE_FLOW_ITEM_TYPE_IPV4:
> > +                   {
> > +                           rule_action->encap.vxlan.ipv4.sa =
> > +                                   rte_ntohl(spec.ipv4.hdr.src_addr);
> > +                           rule_action->encap.vxlan.ipv4.da =
> > +                                   rte_ntohl(spec.ipv4.hdr.dst_addr);
> > +                           rule_action->encap.vxlan.ipv4.dscp =
> > +                                   spec.ipv4.hdr.type_of_service >> 2;
> > +                           rule_action->encap.vxlan.ipv4.ttl =
> > +                                   spec.ipv4.hdr.time_to_live;
> > +                           break;
> > +                   }
> > +                   case RTE_FLOW_ITEM_TYPE_IPV6:
> > +                   {
> > +                           uint32_t vtc_flow;
> > +
> > +                           memcpy(&rule_action->encap.vxlan.ipv6.sa,
> > +                                           &spec.ipv6.hdr.src_addr,
> > +
> >     sizeof(spec.ipv6.hdr.src_addr));
> > +                           memcpy(&rule_action->encap.vxlan.ipv6.da,
> > +                                           &spec.ipv6.hdr.dst_addr,
> > +
> >     sizeof(spec.ipv6.hdr.dst_addr));
> > +                           vtc_flow = rte_ntohl(spec.ipv6.hdr.vtc_flow);
> > +                           rule_action->encap.vxlan.ipv6.flow_label =
> > +                                           vtc_flow >> 12;

rule_action->encap.vxlan.ipv6.flow_label = vtc_flow & 0xFFFFF;

> > +                           rule_action->encap.vxlan.ipv6.dscp =
> > +                                           (vtc_flow & 0x00000fc0) >> 6;

rule_action->encap.vxlan.ipv6.dscp = (vtc_flow >> 22) & 0x3F;

> > +                           rule_action->encap.vxlan.ipv6.hop_limit =
> > +                                   spec.ipv6.hdr.hop_limits;
> > +                           break;
> > +                   }
> > +                   default:
> > +                           return rte_flow_error_set(error,
> > +                                   EINVAL,
> > +                                   RTE_FLOW_ERROR_TYPE_ITEM,
> > +                                   item,
> > +                                   "VXLAN ENCAP: encap item after
> > ether should be ipv4/ipv6");
> > +                   }
> > +
> > +                   item++;
> > +
> > +                   /* Check for UDP. */
> > +                   flow_item_skip_void(&item);
> > +                   status = flow_item_proto_preprocess(item, &spec,
> > &mask,
> > +                                   &size, &disabled, error);
> > +                   if (status)
> > +                           return status;
> > +
> > +                   if (item->type != RTE_FLOW_ITEM_TYPE_UDP) {
> > +                           return rte_flow_error_set(error,
> > +                                   EINVAL,
> > +                                   RTE_FLOW_ERROR_TYPE_ITEM,
> > +                                   item,
> > +                                   "VXLAN ENCAP: encap item after
> > ipv4/ipv6 should be udp");
> > +                   }
> > +                   rule_action->encap.vxlan.udp.sp =
> > +                           rte_ntohs(spec.udp.hdr.src_port);
> > +                   rule_action->encap.vxlan.udp.dp =
> > +                           rte_ntohs(spec.udp.hdr.dst_port);
> > +
> > +                   item++;
> > +
> > +                   /* Check for VXLAN. */
> > +                   flow_item_skip_void(&item);
> > +                   status = flow_item_proto_preprocess(item, &spec,
> > &mask,
> > +                                   &size, &disabled, error);
> > +                   if (status)
> > +                           return status;
> > +
> > +                   if (item->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
> > +                           return rte_flow_error_set(error,
> > +                                   EINVAL,
> > +                                   RTE_FLOW_ERROR_TYPE_ITEM,
> > +                                   item,
> > +                                   "VXLAN ENCAP: encap item after udp
> > should be vxlan");
> > +                   }
> > +                   rule_action->encap.vxlan.vxlan.vni =
> > +                           (spec.vxlan.vni[0] << 16U |
> > +                                   spec.vxlan.vni[1] << 8U
> > +                                   | spec.vxlan.vni[2]);
> > +
> > +                   item++;
> > +
> > +                   /* Check for END. */
> > +                   flow_item_skip_void(&item);
> > +
> > +                   if (item->type != RTE_FLOW_ITEM_TYPE_END)
> > +                           return rte_flow_error_set(error,
> > +                                   EINVAL,
> > +                                   RTE_FLOW_ERROR_TYPE_ITEM,
> > +                                   item,
> > +                                   "VXLAN ENCAP: expecting END
> > item");
> > +
> > +                   rule_action->encap.type =
> > RTE_TABLE_ACTION_ENCAP_VXLAN;
> > +                   rule_action->action_mask |= 1 <<
> > RTE_TABLE_ACTION_ENCAP;
> > +                   break;
> > +           } /* RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP */
> > +
> >             default:
> >                     return -ENOTSUP;
> >             }
> > --
> > 2.17.1

Reply via email to