Current tunnel-pop API does not allow the netdev implementation retain a packet but STT can keep a packet from batch of packets during TCP reassembly processing. To return exact count of valid packet STT need to pass this number of packet parameter as a reference.
Signed-off-by: Pravin B Shelar <pshe...@ovn.org> --- lib/dpif-netdev.c | 9 +++++++-- lib/netdev-native-tnl.c | 41 +++++++++++++++++++++++++---------------- lib/netdev-native-tnl.h | 6 +++--- lib/netdev-provider.h | 6 ++++-- lib/netdev.c | 14 ++++++-------- lib/netdev.h | 2 +- 6 files changed, 46 insertions(+), 32 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 1e8a37c..5dcb862 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -3724,7 +3724,6 @@ dp_execute_cb(void *aux_, struct dp_packet **packets, int cnt, struct dp_netdev *dp = pmd->dp; int type = nl_attr_type(a); struct dp_netdev_port *p; - int i; switch ((enum ovs_action_attr)type) { case OVS_ACTION_ATTR_OUTPUT: @@ -3775,8 +3774,12 @@ dp_execute_cb(void *aux_, struct dp_packet **packets, int cnt, packets = tnl_pkt; } - err = netdev_pop_header(p->netdev, packets, cnt); + err = netdev_pop_header(p->netdev, packets, &cnt); + if (!cnt) { + return; + } if (!err) { + int i; for (i = 0; i < cnt; i++) { packets[i]->md.in_port.odp_port = portno; @@ -3799,6 +3802,7 @@ dp_execute_cb(void *aux_, struct dp_packet **packets, int cnt, struct ofpbuf actions; struct flow flow; ovs_u128 ufid; + int i; userdata = nl_attr_find_nested(a, OVS_USERSPACE_ATTR_USERDATA); ofpbuf_init(&actions, 0); @@ -3830,6 +3834,7 @@ dp_execute_cb(void *aux_, struct dp_packet **packets, int cnt, case OVS_ACTION_ATTR_RECIRC: if (*depth < MAX_RECIRC_DEPTH) { struct dp_packet *recirc_pkts[NETDEV_MAX_BURST]; + int i; if (!may_steal) { dp_netdev_clone_pkt_batch(recirc_pkts, packets, cnt); diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c index b52b068..d28cfbf 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -353,7 +353,7 @@ parse_gre_header(struct dp_packet *packet, return hlen; } -int +struct dp_packet * netdev_gre_pop_header(struct dp_packet *packet) { struct pkt_metadata *md = &packet->md; @@ -365,17 +365,20 @@ netdev_gre_pop_header(struct dp_packet *packet) pkt_metadata_init_tnl(md); if (hlen > dp_packet_size(packet)) { - return EINVAL; + goto err; } hlen = parse_gre_header(packet, tnl); if (hlen < 0) { - return -hlen; + goto err; } dp_packet_reset_packet(packet, hlen); - return 0; + return packet; +err: + dp_packet_delete(packet); + return NULL; } void @@ -450,7 +453,7 @@ netdev_gre_build_header(const struct netdev *netdev, return 0; } -int +struct dp_packet * netdev_vxlan_pop_header(struct dp_packet *packet) { struct pkt_metadata *md = &packet->md; @@ -460,12 +463,12 @@ netdev_vxlan_pop_header(struct dp_packet *packet) pkt_metadata_init_tnl(md); if (VXLAN_HLEN > dp_packet_l4_size(packet)) { - return EINVAL; + goto err; } vxh = udp_extract_tnl_md(packet, tnl, &hlen); if (!vxh) { - return EINVAL; + goto err; } if (get_16aligned_be32(&vxh->vx_flags) != htonl(VXLAN_FLAGS) || @@ -473,14 +476,17 @@ netdev_vxlan_pop_header(struct dp_packet *packet) VLOG_WARN_RL(&err_rl, "invalid vxlan flags=%#x vni=%#x\n", ntohl(get_16aligned_be32(&vxh->vx_flags)), ntohl(get_16aligned_be32(&vxh->vx_vni))); - return EINVAL; + goto err; } tnl->tun_id = htonll(ntohl(get_16aligned_be32(&vxh->vx_vni)) >> 8); tnl->flags |= FLOW_TNL_F_KEY; dp_packet_reset_packet(packet, hlen + VXLAN_HLEN); - return 0; + return packet; +err: + dp_packet_delete(packet); + return NULL; } int @@ -508,7 +514,7 @@ netdev_vxlan_build_header(const struct netdev *netdev, return 0; } -int +struct dp_packet * netdev_geneve_pop_header(struct dp_packet *packet) { struct pkt_metadata *md = &packet->md; @@ -520,12 +526,12 @@ netdev_geneve_pop_header(struct dp_packet *packet) if (GENEVE_BASE_HLEN > dp_packet_l4_size(packet)) { VLOG_WARN_RL(&err_rl, "geneve packet too small: min header=%u packet size=%"PRIuSIZE"\n", (unsigned int)GENEVE_BASE_HLEN, dp_packet_l4_size(packet)); - return EINVAL; + goto err; } gnh = udp_extract_tnl_md(packet, tnl, &ulen); if (!gnh) { - return EINVAL; + goto err; } opts_len = gnh->opt_len * 4; @@ -533,18 +539,18 @@ netdev_geneve_pop_header(struct dp_packet *packet) if (hlen > dp_packet_size(packet)) { VLOG_WARN_RL(&err_rl, "geneve packet too small: header len=%u packet size=%u\n", hlen, dp_packet_size(packet)); - return EINVAL; + goto err; } if (gnh->ver != 0) { VLOG_WARN_RL(&err_rl, "unknown geneve version: %"PRIu8"\n", gnh->ver); - return EINVAL; + goto err; } if (gnh->proto_type != htons(ETH_TYPE_TEB)) { VLOG_WARN_RL(&err_rl, "unknown geneve encapsulated protocol: %#x\n", ntohs(gnh->proto_type)); - return EINVAL; + goto err; } tnl->flags |= gnh->oam ? FLOW_TNL_F_OAM : 0; @@ -557,7 +563,10 @@ netdev_geneve_pop_header(struct dp_packet *packet) dp_packet_reset_packet(packet, hlen); - return 0; + return packet; +err: + dp_packet_delete(packet); + return NULL; } int diff --git a/lib/netdev-native-tnl.h b/lib/netdev-native-tnl.h index 5173b10..dbe6bd0 100644 --- a/lib/netdev-native-tnl.h +++ b/lib/netdev-native-tnl.h @@ -29,7 +29,7 @@ netdev_gre_build_header(const struct netdev *netdev, void netdev_gre_push_header(struct dp_packet *packet, const struct ovs_action_push_tnl *data); -int +struct dp_packet * netdev_gre_pop_header(struct dp_packet *packet); void @@ -39,14 +39,14 @@ int netdev_geneve_build_header(const struct netdev *netdev, struct ovs_action_push_tnl *data, const struct flow *tnl_flow); -int +struct dp_packet * netdev_geneve_pop_header(struct dp_packet *packet); int netdev_vxlan_build_header(const struct netdev *netdev, struct ovs_action_push_tnl *data, const struct flow *tnl_flow); -int +struct dp_packet * netdev_vxlan_pop_header(struct dp_packet *packet); void diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h index c2ddbf1..6af0708 100644 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@ -275,8 +275,10 @@ struct netdev_class { const struct ovs_action_push_tnl *data); /* Pop tunnel header from packet, build tunnel metadata and resize packet - * for further processing. */ - int (*pop_header)(struct dp_packet *packet); + * for further processing. + * Returns NULL in case of error or tunnel implementation queued packet for further + * processing. */ + struct dp_packet * (*pop_header)(struct dp_packet *packet); /* Returns the id of the numa node the 'netdev' is on. If there is no * such info, returns NETDEV_NUMA_UNSPEC. */ diff --git a/lib/netdev.c b/lib/netdev.c index 3e50694..cac91ea 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -767,23 +767,21 @@ netdev_send(struct netdev *netdev, int qid, struct dp_packet **buffers, } int -netdev_pop_header(struct netdev *netdev, struct dp_packet **buffers, int cnt) +netdev_pop_header(struct netdev *netdev, struct dp_packet **buffers, int *pcnt) { - int i; + int i, cnt = *pcnt, n_cnt = 0; if (!netdev->netdev_class->pop_header) { return EOPNOTSUPP; } for (i = 0; i < cnt; i++) { - int err; - - err = netdev->netdev_class->pop_header(buffers[i]); - if (err) { - dp_packet_clear(buffers[i]); + buffers[i] = netdev->netdev_class->pop_header(buffers[i]); + if (buffers[i]) { + buffers[n_cnt++] = buffers[i]; } } - + *pcnt = n_cnt; return 0; } diff --git a/lib/netdev.h b/lib/netdev.h index 6dabc92..f31b565 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -159,7 +159,7 @@ int netdev_push_header(const struct netdev *netdev, struct dp_packet **buffers, int cnt, const struct ovs_action_push_tnl *data); int netdev_pop_header(struct netdev *netdev, struct dp_packet **buffers, - int cnt); + int *pcnt); /* Hardware address. */ int netdev_set_etheraddr(struct netdev *, const struct eth_addr mac); -- 2.5.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev