[ovs-dev] [PATCH v2 02/15] netdev: Return number of packet from netdev_pop_header()
Pravin B Shelar
pshelar at ovn.org
Fri Apr 22 01:54:17 UTC 2016
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 <pshelar at 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
More information about the dev
mailing list