On Wed, Aug 16, 2017 at 11:15:28PM +0800, Eric Garver wrote: > On Wed, Aug 16, 2017 at 01:35:30PM +0800, Yi Yang wrote: > > + > > +#define NSH_DST_PORT 4790 /* UDP Port for NSH on VXLAN. */ > > +#define ETH_P_NSH 0x894F /* Ethertype for NSH. */ > > ETH_P_NSH probably belongs in include/uapi/linux/if_ether.h with all the > other ETH_P_* defines. >
Ok, I'll move it to include/uapi/linux/if_ether.h, but in userspace, we still need to keep it in nsh.h. > > > > +struct ovs_key_nsh { > > + __u8 flags; > > + __u8 mdtype; > > + __u8 np; > > + __u8 pad; > > + __be32 path_hdr; > > + __be32 context[NSH_MD1_CONTEXT_SIZE]; > > +}; > > + > > struct sw_flow_key { > > u8 tun_opts[IP_TUNNEL_OPTS_MAX]; > > u8 tun_opts_len; > > @@ -144,6 +154,7 @@ struct sw_flow_key { > > }; > > } ipv6; > > }; > > + struct ovs_key_nsh nsh; /* network service header */ > > Are you intentionally not reserving space in the flow key for > OVS_NSH_KEY_ATTR_MD2? I know it's not supported yet, but much of the > code is stubbed out for it - just making sure this wasn't an oversight. > For MD type 2, we'll reuse tun_metedata keys in struct flow_tnl which will be reworked and it will be shared by NSH and GENEVE, so we won't have new keys in "struct ovs_key_nsh" for MD type 2. > > struct { > > /* Connection tracking fields not packed above. */ > > struct { > > diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c > > index f07d10a..79059db 100644 > > --- a/net/openvswitch/flow_netlink.c > > +++ b/net/openvswitch/flow_netlink.c > > @@ -78,9 +78,11 @@ static bool actions_may_change_flow(const struct nlattr > > *actions) > > case OVS_ACTION_ATTR_HASH: > > case OVS_ACTION_ATTR_POP_ETH: > > case OVS_ACTION_ATTR_POP_MPLS: > > + case OVS_ACTION_ATTR_POP_NSH: > > case OVS_ACTION_ATTR_POP_VLAN: > > case OVS_ACTION_ATTR_PUSH_ETH: > > case OVS_ACTION_ATTR_PUSH_MPLS: > > + case OVS_ACTION_ATTR_PUSH_NSH: > > case OVS_ACTION_ATTR_PUSH_VLAN: > > case OVS_ACTION_ATTR_SAMPLE: > > case OVS_ACTION_ATTR_SET: > > @@ -322,12 +324,22 @@ size_t ovs_tun_key_attr_size(void) > > + nla_total_size(2); /* OVS_TUNNEL_KEY_ATTR_TP_DST */ > > } > > > > +size_t ovs_nsh_key_attr_size(void) > > +{ > > + /* Whenever adding new OVS_NSH_KEY_ FIELDS, we should consider > > + * updating this function. > > + */ > > + return nla_total_size(8) /* OVS_NSH_KEY_ATTR_BASE */ > > + + nla_total_size(16) /* OVS_NSH_KEY_ATTR_MD1 */ > > + + nla_total_size(248); /* OVS_NSH_KEY_ATTR_MD2 */ > > _MD1 and _MD2 are mutually exclusive. You only need the larger of the > two. > > Maybe use OVS_PUSH_NSH_MAX_MD_LEN instead of 248. Got it, will use nla_total_size(NSH_M_TYPE2_MAX_LEN - NSH_BASE_HDR_LEN) > > + > > + switch (type) { > > + case OVS_NSH_KEY_ATTR_BASE: { > > + const struct ovs_nsh_key_base *base = > > + (struct ovs_nsh_key_base *)nla_data(a); > > + nsh->flags = base->flags; > > + nsh->mdtype = base->mdtype; > > + nsh->np = base->np; > > + nsh->path_hdr = base->path_hdr; > > + break; > > + } > > + case OVS_NSH_KEY_ATTR_MD1: { > > + const struct ovs_nsh_key_md1 *md1 = > > + (struct ovs_nsh_key_md1 *)nla_data(a); > > + memcpy(nsh->context, md1->context, sizeof(*md1)); > > + break; > > + } > > + case OVS_NSH_KEY_ATTR_MD2: > > + /* Not supported yet */ > > + break; > > When we encounter these metadata attributes do we need to verify that > nsh->mdtype is set correctly? Keep in mind we may parse ATTR_MD{1,2} > before ATTR_BASE. Good point, will add check code for this.