]> git.proxmox.com Git - mirror_ovs.git/commitdiff
netdev: Return number of packet from netdev_pop_header()
authorPravin B Shelar <pshelar@ovn.org>
Wed, 18 May 2016 00:32:06 +0000 (17:32 -0700)
committerPravin B Shelar <pshelar@ovn.org>
Thu, 19 May 2016 02:39:18 +0000 (19:39 -0700)
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@ovn.org>
Acked-by: Jesse Gross <jesse@kernel.org>
lib/dpif-netdev.c
lib/netdev-native-tnl.c
lib/netdev-native-tnl.h
lib/netdev-provider.h
lib/netdev.c
lib/netdev.h

index 33fd2283cd0789b979223fc505567a70f1394894..5982ca41a27ff4dd589f061b4ab7eb2d064514b7 100644 (file)
@@ -3722,7 +3722,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:
@@ -3773,8 +3772,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;
@@ -3797,6 +3800,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);
@@ -3828,6 +3832,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);
index b307940d690d9f264009a934c4bf6fd8c23c739c..2e181f299acdbaf8e11310e40ed365ba24141010 100644 (file)
@@ -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
index e382fa10698952f10ea522d63a05e517a440206b..e0d15fc44cd3e48cc23948bd9a0097e35957d3c2 100644 (file)
@@ -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);
 
 static inline bool
index c2ddbf1d349668020b82407852e470bef12b2dbe..6af0708e21e29547af5a85ed8e6a2c1ba1b602a5 100644 (file)
@@ -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. */
index a6786885b88b8e251cd04cad4c7debbe7eeb5a2a..228b0688dba49aa92a99460ee182f06f9f36e3c3 100644 (file)
@@ -734,23 +734,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;
 }
 
index 6dabc923a75083e4e6674eca18548955bf5e66b9..f31b5654a70eff8057136546b87f3a1c72da0e77 100644 (file)
@@ -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);