LCOV - code coverage report
Current view: top level - lib - dp-packet.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 182 186 97.8 %
Date: 2016-09-14 01:02:56 Functions: 50 50 100.0 %
Branches: 48 66 72.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at:
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : #ifndef DPBUF_H
      18                 :            : #define DPBUF_H 1
      19                 :            : 
      20                 :            : #include <stddef.h>
      21                 :            : #include <stdint.h>
      22                 :            : #include "openvswitch/list.h"
      23                 :            : #include "packets.h"
      24                 :            : #include "util.h"
      25                 :            : #include "netdev-dpdk.h"
      26                 :            : 
      27                 :            : #ifdef  __cplusplus
      28                 :            : extern "C" {
      29                 :            : #endif
      30                 :            : 
      31                 :            : enum OVS_PACKED_ENUM dp_packet_source {
      32                 :            :     DPBUF_MALLOC,              /* Obtained via malloc(). */
      33                 :            :     DPBUF_STACK,               /* Un-movable stack space or static buffer. */
      34                 :            :     DPBUF_STUB,                /* Starts on stack, may expand into heap. */
      35                 :            :     DPBUF_DPDK,                /* buffer data is from DPDK allocated memory.
      36                 :            :                                 * ref to build_dp_packet() in netdev-dpdk. */
      37                 :            : };
      38                 :            : 
      39                 :            : #define DP_PACKET_CONTEXT_SIZE 64
      40                 :            : 
      41                 :            : /* Buffer for holding packet data.  A dp_packet is automatically reallocated
      42                 :            :  * as necessary if it grows too large for the available memory.
      43                 :            :  */
      44                 :            : struct dp_packet {
      45                 :            : #ifdef DPDK_NETDEV
      46                 :            :     struct rte_mbuf mbuf;       /* DPDK mbuf */
      47                 :            : #else
      48                 :            :     void *base_;                /* First byte of allocated space. */
      49                 :            :     uint16_t allocated_;        /* Number of bytes allocated. */
      50                 :            :     uint16_t data_ofs;          /* First byte actually in use. */
      51                 :            :     uint32_t size_;             /* Number of bytes in use. */
      52                 :            :     uint32_t rss_hash;          /* Packet hash. */
      53                 :            :     bool rss_hash_valid;        /* Is the 'rss_hash' valid? */
      54                 :            : #endif
      55                 :            :     enum dp_packet_source source;  /* Source of memory allocated as 'base'. */
      56                 :            :     uint8_t l2_pad_size;           /* Detected l2 padding size.
      57                 :            :                                     * Padding is non-pullable. */
      58                 :            :     uint16_t l2_5_ofs;             /* MPLS label stack offset, or UINT16_MAX */
      59                 :            :     uint16_t l3_ofs;               /* Network-level header offset,
      60                 :            :                                     * or UINT16_MAX. */
      61                 :            :     uint16_t l4_ofs;               /* Transport-level header offset,
      62                 :            :                                       or UINT16_MAX. */
      63                 :            :     uint32_t cutlen;               /* length in bytes to cut from the end. */
      64                 :            :     union {
      65                 :            :         struct pkt_metadata md;
      66                 :            :         uint64_t data[DP_PACKET_CONTEXT_SIZE / 8];
      67                 :            :     };
      68                 :            : };
      69                 :            : 
      70                 :            : static inline void *dp_packet_data(const struct dp_packet *);
      71                 :            : static inline void dp_packet_set_data(struct dp_packet *, void *);
      72                 :            : static inline void *dp_packet_base(const struct dp_packet *);
      73                 :            : static inline void dp_packet_set_base(struct dp_packet *, void *);
      74                 :            : 
      75                 :            : static inline uint32_t dp_packet_size(const struct dp_packet *);
      76                 :            : static inline void dp_packet_set_size(struct dp_packet *, uint32_t);
      77                 :            : 
      78                 :            : static inline uint16_t dp_packet_get_allocated(const struct dp_packet *);
      79                 :            : static inline void dp_packet_set_allocated(struct dp_packet *, uint16_t);
      80                 :            : 
      81                 :            : void *dp_packet_resize_l2(struct dp_packet *, int increment);
      82                 :            : void *dp_packet_resize_l2_5(struct dp_packet *, int increment);
      83                 :            : static inline void *dp_packet_l2(const struct dp_packet *);
      84                 :            : static inline void dp_packet_reset_offsets(struct dp_packet *);
      85                 :            : static inline uint8_t dp_packet_l2_pad_size(const struct dp_packet *);
      86                 :            : static inline void dp_packet_set_l2_pad_size(struct dp_packet *, uint8_t);
      87                 :            : static inline void *dp_packet_l2_5(const struct dp_packet *);
      88                 :            : static inline void dp_packet_set_l2_5(struct dp_packet *, void *);
      89                 :            : static inline void *dp_packet_l3(const struct dp_packet *);
      90                 :            : static inline void dp_packet_set_l3(struct dp_packet *, void *);
      91                 :            : static inline void *dp_packet_l4(const struct dp_packet *);
      92                 :            : static inline void dp_packet_set_l4(struct dp_packet *, void *);
      93                 :            : static inline size_t dp_packet_l4_size(const struct dp_packet *);
      94                 :            : static inline const void *dp_packet_get_tcp_payload(const struct dp_packet *);
      95                 :            : static inline const void *dp_packet_get_udp_payload(const struct dp_packet *);
      96                 :            : static inline const void *dp_packet_get_sctp_payload(const struct dp_packet *);
      97                 :            : static inline const void *dp_packet_get_icmp_payload(const struct dp_packet *);
      98                 :            : static inline const void *dp_packet_get_nd_payload(const struct dp_packet *);
      99                 :            : 
     100                 :            : void dp_packet_use(struct dp_packet *, void *, size_t);
     101                 :            : void dp_packet_use_stub(struct dp_packet *, void *, size_t);
     102                 :            : void dp_packet_use_const(struct dp_packet *, const void *, size_t);
     103                 :            : 
     104                 :            : void dp_packet_init_dpdk(struct dp_packet *, size_t allocated);
     105                 :            : 
     106                 :            : void dp_packet_init(struct dp_packet *, size_t);
     107                 :            : void dp_packet_uninit(struct dp_packet *);
     108                 :            : 
     109                 :            : struct dp_packet *dp_packet_new(size_t);
     110                 :            : struct dp_packet *dp_packet_new_with_headroom(size_t, size_t headroom);
     111                 :            : struct dp_packet *dp_packet_clone(const struct dp_packet *);
     112                 :            : struct dp_packet *dp_packet_clone_with_headroom(const struct dp_packet *,
     113                 :            :                                                 size_t headroom);
     114                 :            : struct dp_packet *dp_packet_clone_data(const void *, size_t);
     115                 :            : struct dp_packet *dp_packet_clone_data_with_headroom(const void *, size_t,
     116                 :            :                                                      size_t headroom);
     117                 :            : static inline void dp_packet_delete(struct dp_packet *);
     118                 :            : 
     119                 :            : static inline void *dp_packet_at(const struct dp_packet *, size_t offset,
     120                 :            :                                  size_t size);
     121                 :            : static inline void *dp_packet_at_assert(const struct dp_packet *,
     122                 :            :                                         size_t offset, size_t size);
     123                 :            : static inline void *dp_packet_tail(const struct dp_packet *);
     124                 :            : static inline void *dp_packet_end(const struct dp_packet *);
     125                 :            : 
     126                 :            : void *dp_packet_put_uninit(struct dp_packet *, size_t);
     127                 :            : void *dp_packet_put_zeros(struct dp_packet *, size_t);
     128                 :            : void *dp_packet_put(struct dp_packet *, const void *, size_t);
     129                 :            : char *dp_packet_put_hex(struct dp_packet *, const char *s, size_t *n);
     130                 :            : void dp_packet_reserve(struct dp_packet *, size_t);
     131                 :            : void dp_packet_reserve_with_tailroom(struct dp_packet *, size_t headroom,
     132                 :            :                                      size_t tailroom);
     133                 :            : void *dp_packet_push_uninit(struct dp_packet *, size_t);
     134                 :            : void *dp_packet_push_zeros(struct dp_packet *, size_t);
     135                 :            : void *dp_packet_push(struct dp_packet *, const void *, size_t);
     136                 :            : 
     137                 :            : static inline size_t dp_packet_headroom(const struct dp_packet *);
     138                 :            : static inline size_t dp_packet_tailroom(const struct dp_packet *);
     139                 :            : void dp_packet_prealloc_headroom(struct dp_packet *, size_t);
     140                 :            : void dp_packet_prealloc_tailroom(struct dp_packet *, size_t);
     141                 :            : void dp_packet_shift(struct dp_packet *, int);
     142                 :            : 
     143                 :            : static inline void dp_packet_clear(struct dp_packet *);
     144                 :            : static inline void *dp_packet_pull(struct dp_packet *, size_t);
     145                 :            : static inline void *dp_packet_try_pull(struct dp_packet *, size_t);
     146                 :            : 
     147                 :            : void *dp_packet_steal_data(struct dp_packet *);
     148                 :            : 
     149                 :            : static inline bool dp_packet_equal(const struct dp_packet *,
     150                 :            :                                    const struct dp_packet *);
     151                 :            : 
     152                 :            : 
     153                 :            : /* Frees memory that 'b' points to, as well as 'b' itself. */
     154                 :            : static inline void
     155                 :      68442 : dp_packet_delete(struct dp_packet *b)
     156                 :            : {
     157         [ +  + ]:      68442 :     if (b) {
     158         [ -  + ]:      67647 :         if (b->source == DPBUF_DPDK) {
     159                 :            :             /* If this dp_packet was allocated by DPDK it must have been
     160                 :            :              * created as a dp_packet */
     161                 :          0 :             free_dpdk_buf((struct dp_packet*) b);
     162                 :          0 :             return;
     163                 :            :         }
     164                 :            : 
     165                 :      67647 :         dp_packet_uninit(b);
     166                 :      67647 :         free(b);
     167                 :            :     }
     168                 :            : }
     169                 :            : 
     170                 :            : /* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to
     171                 :            :  * byte 'offset'.  Otherwise, returns a null pointer. */
     172                 :            : static inline void *
     173                 :       2099 : dp_packet_at(const struct dp_packet *b, size_t offset, size_t size)
     174                 :            : {
     175                 :       4198 :     return offset + size <= dp_packet_size(b)
     176                 :       2097 :            ? (char *) dp_packet_data(b) + offset
     177         [ +  + ]:       4196 :            : NULL;
     178                 :            : }
     179                 :            : 
     180                 :            : /* Returns a pointer to byte 'offset' in 'b', which must contain at least
     181                 :            :  * 'offset + size' bytes of data. */
     182                 :            : static inline void *
     183                 :         11 : dp_packet_at_assert(const struct dp_packet *b, size_t offset, size_t size)
     184                 :            : {
     185         [ -  + ]:         11 :     ovs_assert(offset + size <= dp_packet_size(b));
     186                 :         11 :     return ((char *) dp_packet_data(b)) + offset;
     187                 :            : }
     188                 :            : 
     189                 :            : /* Returns a pointer to byte following the last byte of data in use in 'b'. */
     190                 :            : static inline void *
     191                 :     839298 : dp_packet_tail(const struct dp_packet *b)
     192                 :            : {
     193                 :     839298 :     return (char *) dp_packet_data(b) + dp_packet_size(b);
     194                 :            : }
     195                 :            : 
     196                 :            : /* Returns a pointer to byte following the last byte allocated for use (but
     197                 :            :  * not necessarily in use) in 'b'. */
     198                 :            : static inline void *
     199                 :     450125 : dp_packet_end(const struct dp_packet *b)
     200                 :            : {
     201                 :     450125 :     return (char *) dp_packet_base(b) + dp_packet_get_allocated(b);
     202                 :            : }
     203                 :            : 
     204                 :            : /* Returns the number of bytes of headroom in 'b', that is, the number of bytes
     205                 :            :  * of unused space in dp_packet 'b' before the data that is in use.  (Most
     206                 :            :  * commonly, the data in a dp_packet is at its beginning, and thus the
     207                 :            :  * dp_packet's headroom is 0.) */
     208                 :            : static inline size_t
     209                 :      18884 : dp_packet_headroom(const struct dp_packet *b)
     210                 :            : {
     211                 :      18884 :     return (char *) dp_packet_data(b) - (char *) dp_packet_base(b);
     212                 :            : }
     213                 :            : 
     214                 :            : /* Returns the number of bytes that may be appended to the tail end of
     215                 :            :  * dp_packet 'b' before the dp_packet must be reallocated. */
     216                 :            : static inline size_t
     217                 :     450125 : dp_packet_tailroom(const struct dp_packet *b)
     218                 :            : {
     219                 :     450125 :     return (char *) dp_packet_end(b) - (char *) dp_packet_tail(b);
     220                 :            : }
     221                 :            : 
     222                 :            : /* Clears any data from 'b'. */
     223                 :            : static inline void
     224                 :      19291 : dp_packet_clear(struct dp_packet *b)
     225                 :            : {
     226                 :      19291 :     dp_packet_set_data(b, dp_packet_base(b));
     227                 :      19291 :     dp_packet_set_size(b, 0);
     228                 :      19291 : }
     229                 :            : 
     230                 :            : /* Removes 'size' bytes from the head end of 'b', which must contain at least
     231                 :            :  * 'size' bytes of data.  Returns the first byte of data removed. */
     232                 :            : static inline void *
     233                 :       9647 : dp_packet_pull(struct dp_packet *b, size_t size)
     234                 :            : {
     235                 :       9647 :     void *data = dp_packet_data(b);
     236         [ -  + ]:       9647 :     ovs_assert(dp_packet_size(b) - dp_packet_l2_pad_size(b) >= size);
     237                 :       9647 :     dp_packet_set_data(b, (char *) dp_packet_data(b) + size);
     238                 :       9647 :     dp_packet_set_size(b, dp_packet_size(b) - size);
     239                 :       9647 :     return data;
     240                 :            : }
     241                 :            : 
     242                 :            : /* If 'b' has at least 'size' bytes of data, removes that many bytes from the
     243                 :            :  * head end of 'b' and returns the first byte removed.  Otherwise, returns a
     244                 :            :  * null pointer without modifying 'b'. */
     245                 :            : static inline void *
     246                 :         19 : dp_packet_try_pull(struct dp_packet *b, size_t size)
     247                 :            : {
     248                 :         38 :     return dp_packet_size(b) - dp_packet_l2_pad_size(b) >= size
     249         [ +  - ]:         19 :         ? dp_packet_pull(b, size) : NULL;
     250                 :            : }
     251                 :            : 
     252                 :            : static inline bool
     253                 :            : dp_packet_equal(const struct dp_packet *a, const struct dp_packet *b)
     254                 :            : {
     255                 :            :     return dp_packet_size(a) == dp_packet_size(b) &&
     256                 :            :            !memcmp(dp_packet_data(a), dp_packet_data(b), dp_packet_size(a));
     257                 :            : }
     258                 :            : 
     259                 :            : /* Get the start of the Ethernet frame.  'l3_ofs' marks the end of the l2
     260                 :            :  * headers, so return NULL if it is not set. */
     261                 :            : static inline void *
     262                 :      12351 : dp_packet_l2(const struct dp_packet *b)
     263                 :            : {
     264         [ +  - ]:      12351 :     return (b->l3_ofs != UINT16_MAX) ? dp_packet_data(b) : NULL;
     265                 :            : }
     266                 :            : 
     267                 :            : /* Resets all layer offsets.  'l3' offset must be set before 'l2' can be
     268                 :            :  * retrieved. */
     269                 :            : static inline void
     270                 :     176503 : dp_packet_reset_offsets(struct dp_packet *b)
     271                 :            : {
     272                 :     176503 :     b->l2_pad_size = 0;
     273                 :     176503 :     b->l2_5_ofs = UINT16_MAX;
     274                 :     176503 :     b->l3_ofs = UINT16_MAX;
     275                 :     176503 :     b->l4_ofs = UINT16_MAX;
     276                 :     176503 : }
     277                 :            : 
     278                 :            : static inline uint8_t
     279                 :      15489 : dp_packet_l2_pad_size(const struct dp_packet *b)
     280                 :            : {
     281                 :      15489 :     return b->l2_pad_size;
     282                 :            : }
     283                 :            : 
     284                 :            : static inline void
     285                 :      23341 : dp_packet_set_l2_pad_size(struct dp_packet *b, uint8_t pad_size)
     286                 :            : {
     287         [ -  + ]:      23341 :     ovs_assert(pad_size <= dp_packet_size(b));
     288                 :      23341 :     b->l2_pad_size = pad_size;
     289                 :      23341 : }
     290                 :            : 
     291                 :            : static inline void *
     292                 :        233 : dp_packet_l2_5(const struct dp_packet *b)
     293                 :            : {
     294                 :        233 :     return b->l2_5_ofs != UINT16_MAX
     295                 :        233 :            ? (char *) dp_packet_data(b) + b->l2_5_ofs
     296         [ +  - ]:        466 :            : NULL;
     297                 :            : }
     298                 :            : 
     299                 :            : static inline void
     300                 :         67 : dp_packet_set_l2_5(struct dp_packet *b, void *l2_5)
     301                 :            : {
     302         [ -  + ]:         67 :     b->l2_5_ofs = l2_5
     303                 :          0 :                   ? (char *) l2_5 - (char *) dp_packet_data(b)
     304                 :            :                   : UINT16_MAX;
     305                 :         67 : }
     306                 :            : 
     307                 :            : static inline void *
     308                 :      35161 : dp_packet_l3(const struct dp_packet *b)
     309                 :            : {
     310                 :      35161 :     return b->l3_ofs != UINT16_MAX
     311                 :      35161 :            ? (char *) dp_packet_data(b) + b->l3_ofs
     312         [ +  - ]:      70322 :            : NULL;
     313                 :            : }
     314                 :            : 
     315                 :            : static inline void
     316                 :      34680 : dp_packet_set_l3(struct dp_packet *b, void *l3)
     317                 :            : {
     318         [ +  - ]:      34680 :     b->l3_ofs = l3 ? (char *) l3 - (char *) dp_packet_data(b) : UINT16_MAX;
     319                 :      34680 : }
     320                 :            : 
     321                 :            : static inline void *
     322                 :      14788 : dp_packet_l4(const struct dp_packet *b)
     323                 :            : {
     324                 :      14788 :     return b->l4_ofs != UINT16_MAX
     325                 :      14787 :            ? (char *) dp_packet_data(b) + b->l4_ofs
     326         [ +  + ]:      29575 :            : NULL;
     327                 :            : }
     328                 :            : 
     329                 :            : static inline void
     330                 :       1492 : dp_packet_set_l4(struct dp_packet *b, void *l4)
     331                 :            : {
     332         [ +  - ]:       1492 :     b->l4_ofs = l4 ? (char *) l4 - (char *) dp_packet_data(b) : UINT16_MAX;
     333                 :       1492 : }
     334                 :            : 
     335                 :            : static inline size_t
     336                 :       7446 : dp_packet_l4_size(const struct dp_packet *b)
     337                 :            : {
     338         [ +  + ]:      12765 :     return b->l4_ofs != UINT16_MAX
     339                 :       5319 :         ? (const char *)dp_packet_tail(b) - (const char *)dp_packet_l4(b)
     340                 :       5319 :         - dp_packet_l2_pad_size(b)
     341                 :            :         : 0;
     342                 :            : }
     343                 :            : 
     344                 :            : static inline const void *
     345                 :        522 : dp_packet_get_tcp_payload(const struct dp_packet *b)
     346                 :            : {
     347                 :        522 :     size_t l4_size = dp_packet_l4_size(b);
     348                 :            : 
     349         [ +  + ]:        522 :     if (OVS_LIKELY(l4_size >= TCP_HEADER_LEN)) {
     350                 :        518 :         struct tcp_header *tcp = dp_packet_l4(b);
     351                 :        518 :         int tcp_len = TCP_OFFSET(tcp->tcp_ctl) * 4;
     352                 :            : 
     353 [ +  - ][ +  - ]:        518 :         if (OVS_LIKELY(tcp_len >= TCP_HEADER_LEN && tcp_len <= l4_size)) {
     354                 :        518 :             return (const char *)tcp + tcp_len;
     355                 :            :         }
     356                 :            :     }
     357                 :          4 :     return NULL;
     358                 :            : }
     359                 :            : 
     360                 :            : static inline const void *
     361                 :       1146 : dp_packet_get_udp_payload(const struct dp_packet *b)
     362                 :            : {
     363                 :       2292 :     return OVS_LIKELY(dp_packet_l4_size(b) >= UDP_HEADER_LEN)
     364         [ +  - ]:       1146 :         ? (const char *)dp_packet_l4(b) + UDP_HEADER_LEN : NULL;
     365                 :            : }
     366                 :            : 
     367                 :            : static inline const void *
     368                 :          7 : dp_packet_get_sctp_payload(const struct dp_packet *b)
     369                 :            : {
     370                 :         14 :     return OVS_LIKELY(dp_packet_l4_size(b) >= SCTP_HEADER_LEN)
     371         [ +  - ]:          7 :         ? (const char *)dp_packet_l4(b) + SCTP_HEADER_LEN : NULL;
     372                 :            : }
     373                 :            : 
     374                 :            : static inline const void *
     375                 :          4 : dp_packet_get_icmp_payload(const struct dp_packet *b)
     376                 :            : {
     377                 :          8 :     return OVS_LIKELY(dp_packet_l4_size(b) >= ICMP_HEADER_LEN)
     378         [ +  - ]:          4 :         ? (const char *)dp_packet_l4(b) + ICMP_HEADER_LEN : NULL;
     379                 :            : }
     380                 :            : 
     381                 :            : static inline const void *
     382                 :          3 : dp_packet_get_nd_payload(const struct dp_packet *b)
     383                 :            : {
     384                 :          6 :     return OVS_LIKELY(dp_packet_l4_size(b) >= ND_MSG_LEN)
     385         [ +  - ]:          3 :         ? (const char *)dp_packet_l4(b) + ND_MSG_LEN : NULL;
     386                 :            : }
     387                 :            : 
     388                 :            : #ifdef DPDK_NETDEV
     389                 :            : BUILD_ASSERT_DECL(offsetof(struct dp_packet, mbuf) == 0);
     390                 :            : 
     391                 :            : static inline void *
     392                 :            : dp_packet_base(const struct dp_packet *b)
     393                 :            : {
     394                 :            :     return b->mbuf.buf_addr;
     395                 :            : }
     396                 :            : 
     397                 :            : static inline void
     398                 :            : dp_packet_set_base(struct dp_packet *b, void *d)
     399                 :            : {
     400                 :            :     b->mbuf.buf_addr = d;
     401                 :            : }
     402                 :            : 
     403                 :            : static inline uint32_t
     404                 :            : dp_packet_size(const struct dp_packet *b)
     405                 :            : {
     406                 :            :     return b->mbuf.pkt_len;
     407                 :            : }
     408                 :            : 
     409                 :            : static inline void
     410                 :            : dp_packet_set_size(struct dp_packet *b, uint32_t v)
     411                 :            : {
     412                 :            :     /* netdev-dpdk does not currently support segmentation; consequently, for
     413                 :            :      * all intents and purposes, 'data_len' (16 bit) and 'pkt_len' (32 bit) may
     414                 :            :      * be used interchangably.
     415                 :            :      *
     416                 :            :      * On the datapath, it is expected that the size of packets
     417                 :            :      * (and thus 'v') will always be <= UINT16_MAX; this means that there is no
     418                 :            :      * loss of accuracy in assigning 'v' to 'data_len'.
     419                 :            :      */
     420                 :            :     b->mbuf.data_len = (uint16_t)v;  /* Current seg length. */
     421                 :            :     b->mbuf.pkt_len = v;             /* Total length of all segments linked to
     422                 :            :                                       * this segment. */
     423                 :            : }
     424                 :            : 
     425                 :            : static inline uint16_t
     426                 :            : __packet_data(const struct dp_packet *b)
     427                 :            : {
     428                 :            :     return b->mbuf.data_off;
     429                 :            : }
     430                 :            : 
     431                 :            : static inline void
     432                 :            : __packet_set_data(struct dp_packet *b, uint16_t v)
     433                 :            : {
     434                 :            :     b->mbuf.data_off = v;
     435                 :            : }
     436                 :            : 
     437                 :            : static inline uint16_t
     438                 :            : dp_packet_get_allocated(const struct dp_packet *b)
     439                 :            : {
     440                 :            :     return b->mbuf.buf_len;
     441                 :            : }
     442                 :            : 
     443                 :            : static inline void
     444                 :            : dp_packet_set_allocated(struct dp_packet *b, uint16_t s)
     445                 :            : {
     446                 :            :     b->mbuf.buf_len = s;
     447                 :            : }
     448                 :            : #else
     449                 :            : static inline void *
     450                 :    1960482 : dp_packet_base(const struct dp_packet *b)
     451                 :            : {
     452                 :    1960482 :     return b->base_;
     453                 :            : }
     454                 :            : 
     455                 :            : static inline void
     456                 :     106578 : dp_packet_set_base(struct dp_packet *b, void *d)
     457                 :            : {
     458                 :     106578 :     b->base_ = d;
     459                 :     106578 : }
     460                 :            : 
     461                 :            : static inline uint32_t
     462                 :    1639075 : dp_packet_size(const struct dp_packet *b)
     463                 :            : {
     464                 :    1639075 :     return b->size_;
     465                 :            : }
     466                 :            : 
     467                 :            : static inline void
     468                 :     465314 : dp_packet_set_size(struct dp_packet *b, uint32_t v)
     469                 :            : {
     470                 :     465314 :     b->size_ = v;
     471                 :     465314 : }
     472                 :            : 
     473                 :            : static inline uint16_t
     474                 :    2380298 : __packet_data(const struct dp_packet *b)
     475                 :            : {
     476                 :    2380298 :     return b->data_ofs;
     477                 :            : }
     478                 :            : 
     479                 :            : static inline void
     480                 :     209494 : __packet_set_data(struct dp_packet *b, uint16_t v)
     481                 :            : {
     482                 :     209494 :     b->data_ofs = v;
     483                 :     209494 : }
     484                 :            : 
     485                 :            : static inline uint16_t
     486                 :     450125 : dp_packet_get_allocated(const struct dp_packet *b)
     487                 :            : {
     488                 :     450125 :     return b->allocated_;
     489                 :            : }
     490                 :            : 
     491                 :            : static inline void
     492                 :     105721 : dp_packet_set_allocated(struct dp_packet *b, uint16_t s)
     493                 :            : {
     494                 :     105721 :     b->allocated_ = s;
     495                 :     105721 : }
     496                 :            : #endif
     497                 :            : 
     498                 :            : static inline void
     499                 :     100942 : dp_packet_reset_cutlen(struct dp_packet *b)
     500                 :            : {
     501                 :     100942 :     b->cutlen = 0;
     502                 :     100942 : }
     503                 :            : 
     504                 :            : static inline uint32_t
     505                 :        588 : dp_packet_set_cutlen(struct dp_packet *b, uint32_t max_len)
     506                 :            : {
     507         [ -  + ]:        588 :     if (max_len < ETH_HEADER_LEN) {
     508                 :          0 :         max_len = ETH_HEADER_LEN;
     509                 :            :     }
     510                 :            : 
     511         [ +  + ]:        588 :     if (max_len >= dp_packet_size(b)) {
     512                 :        562 :         b->cutlen = 0;
     513                 :            :     } else {
     514                 :         26 :         b->cutlen = dp_packet_size(b) - max_len;
     515                 :            :     }
     516                 :        588 :     return b->cutlen;
     517                 :            : }
     518                 :            : 
     519                 :            : static inline uint32_t
     520                 :      15908 : dp_packet_get_cutlen(struct dp_packet *b)
     521                 :            : {
     522                 :            :     /* Always in valid range if user uses dp_packet_set_cutlen. */
     523                 :      15908 :     return b->cutlen;
     524                 :            : }
     525                 :            : 
     526                 :            : static inline void *
     527                 :    1192863 : dp_packet_data(const struct dp_packet *b)
     528                 :            : {
     529                 :    2385726 :     return __packet_data(b) != UINT16_MAX
     530         [ +  + ]:    1192863 :            ? (char *) dp_packet_base(b) + __packet_data(b) : NULL;
     531                 :            : }
     532                 :            : 
     533                 :            : static inline void
     534                 :     209494 : dp_packet_set_data(struct dp_packet *b, void *data)
     535                 :            : {
     536         [ +  + ]:     209494 :     if (data) {
     537                 :     205917 :         __packet_set_data(b, (char *) data - (char *) dp_packet_base(b));
     538                 :            :     } else {
     539                 :       3577 :         __packet_set_data(b, UINT16_MAX);
     540                 :            :     }
     541                 :     209494 : }
     542                 :            : 
     543                 :            : static inline void
     544                 :       1930 : dp_packet_reset_packet(struct dp_packet *b, int off)
     545                 :            : {
     546                 :       1930 :     dp_packet_set_size(b, dp_packet_size(b) - off);
     547                 :       1930 :     dp_packet_set_data(b, ((unsigned char *) dp_packet_data(b) + off));
     548                 :       1930 :     dp_packet_reset_offsets(b);
     549                 :       1930 : }
     550                 :            : 
     551                 :            : /* Returns the RSS hash of the packet 'p'.  Note that the returned value is
     552                 :            :  * correct only if 'dp_packet_rss_valid(p)' returns true */
     553                 :            : static inline uint32_t
     554                 :       6483 : dp_packet_get_rss_hash(struct dp_packet *p)
     555                 :            : {
     556                 :            : #ifdef DPDK_NETDEV
     557                 :            :     return p->mbuf.hash.rss;
     558                 :            : #else
     559                 :       6483 :     return p->rss_hash;
     560                 :            : #endif
     561                 :            : }
     562                 :            : 
     563                 :            : static inline void
     564                 :      17184 : dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash)
     565                 :            : {
     566                 :            : #ifdef DPDK_NETDEV
     567                 :            :     p->mbuf.hash.rss = hash;
     568                 :            :     p->mbuf.ol_flags |= PKT_RX_RSS_HASH;
     569                 :            : #else
     570                 :      17184 :     p->rss_hash = hash;
     571                 :      17184 :     p->rss_hash_valid = true;
     572                 :            : #endif
     573                 :      17184 : }
     574                 :            : 
     575                 :            : static inline bool
     576                 :      25059 : dp_packet_rss_valid(struct dp_packet *p)
     577                 :            : {
     578                 :            : #ifdef DPDK_NETDEV
     579                 :            :     return p->mbuf.ol_flags & PKT_RX_RSS_HASH;
     580                 :            : #else
     581                 :      25059 :     return p->rss_hash_valid;
     582                 :            : #endif
     583                 :            : }
     584                 :            : 
     585                 :            : static inline void
     586                 :     100917 : dp_packet_rss_invalidate(struct dp_packet *p)
     587                 :            : {
     588                 :            : #ifdef DPDK_NETDEV
     589                 :            :     p->mbuf.ol_flags &= ~PKT_RX_RSS_HASH;
     590                 :            : #else
     591                 :     100917 :     p->rss_hash_valid = false;
     592                 :            : #endif
     593                 :     100917 : }
     594                 :            : 
     595                 :            : enum { NETDEV_MAX_BURST = 32 }; /* Maximum number packets in a batch. */
     596                 :            : 
     597                 :            : struct dp_packet_batch {
     598                 :            :     int count;
     599                 :            :     bool trunc; /* true if the batch needs truncate. */
     600                 :            :     struct dp_packet *packets[NETDEV_MAX_BURST];
     601                 :            : };
     602                 :            : 
     603                 :   26387304 : static inline void dp_packet_batch_init(struct dp_packet_batch *b)
     604                 :            : {
     605                 :   26387304 :     b->count = 0;
     606                 :   26387304 :     b->trunc = false;
     607                 :   26387304 : }
     608                 :            : 
     609                 :            : static inline void
     610                 :       1232 : dp_packet_batch_clone(struct dp_packet_batch *dst,
     611                 :            :                       struct dp_packet_batch *src)
     612                 :            : {
     613                 :            :     int i;
     614                 :            : 
     615         [ +  + ]:       2464 :     for (i = 0; i < src->count; i++) {
     616                 :       1232 :         dst->packets[i] = dp_packet_clone(src->packets[i]);
     617                 :            :     }
     618                 :       1232 :     dst->count = src->count;
     619                 :       1232 :     dst->trunc = src->trunc;
     620                 :       1232 : }
     621                 :            : 
     622                 :            : static inline void
     623                 :      10365 : packet_batch_init_packet(struct dp_packet_batch *b, struct dp_packet *p)
     624                 :            : {
     625                 :      10365 :     b->count = 1;
     626                 :      10365 :     b->trunc = false;
     627                 :      10365 :     b->packets[0] = p;
     628                 :      10365 : }
     629                 :            : 
     630                 :            : static inline void
     631                 :      15756 : dp_packet_delete_batch(struct dp_packet_batch *batch, bool may_steal)
     632                 :            : {
     633         [ +  + ]:      15756 :     if (may_steal) {
     634                 :            :         int i;
     635                 :            : 
     636         [ +  + ]:      18558 :         for (i = 0; i < batch->count; i++) {
     637                 :       9279 :             dp_packet_delete(batch->packets[i]);
     638                 :            :         }
     639                 :            :     }
     640                 :      15756 : }
     641                 :            : 
     642                 :            : static inline void
     643                 :       3859 : dp_packet_batch_apply_cutlen(struct dp_packet_batch *pktb)
     644                 :            : {
     645                 :            :     int i;
     646                 :            : 
     647         [ +  + ]:       3859 :     if (!pktb->trunc)
     648                 :       3857 :         return;
     649                 :            : 
     650         [ +  + ]:          4 :     for (i = 0; i < pktb->count; i++) {
     651                 :          2 :         uint32_t cutlen = dp_packet_get_cutlen(pktb->packets[i]);
     652                 :            : 
     653                 :          2 :         dp_packet_set_size(pktb->packets[i],
     654                 :          2 :                     dp_packet_size(pktb->packets[i]) - cutlen);
     655                 :          2 :         dp_packet_reset_cutlen(pktb->packets[i]);
     656                 :            :     }
     657                 :          2 :     pktb->trunc = false;
     658                 :            : }
     659                 :            : 
     660                 :            : static inline void
     661                 :       6280 : dp_packet_batch_reset_cutlen(struct dp_packet_batch *pktb)
     662                 :            : {
     663                 :            :     int i;
     664                 :            : 
     665         [ +  + ]:       6280 :     if (!pktb->trunc)
     666                 :       6264 :         return;
     667                 :            : 
     668                 :         16 :     pktb->trunc = false;
     669         [ +  + ]:         32 :     for (i = 0; i < pktb->count; i++) {
     670                 :         16 :         dp_packet_reset_cutlen(pktb->packets[i]);
     671                 :            :     }
     672                 :            : }
     673                 :            : 
     674                 :            : #ifdef  __cplusplus
     675                 :            : }
     676                 :            : #endif
     677                 :            : 
     678                 :            : #endif /* dp-packet.h */

Generated by: LCOV version 1.12