linux/include/net/strparser.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Stream Parser
   4 *
   5 * Copyright (c) 2016 Tom Herbert <tom@herbertland.com>
   6 */
   7
   8#ifndef __NET_STRPARSER_H_
   9#define __NET_STRPARSER_H_
  10
  11#include <linux/skbuff.h>
  12#include <net/sock.h>
  13
  14#define STRP_STATS_ADD(stat, count) ((stat) += (count))
  15#define STRP_STATS_INCR(stat) ((stat)++)
  16
  17struct strp_stats {
  18        unsigned long long msgs;
  19        unsigned long long bytes;
  20        unsigned int mem_fail;
  21        unsigned int need_more_hdr;
  22        unsigned int msg_too_big;
  23        unsigned int msg_timeouts;
  24        unsigned int bad_hdr_len;
  25};
  26
  27struct strp_aggr_stats {
  28        unsigned long long msgs;
  29        unsigned long long bytes;
  30        unsigned int mem_fail;
  31        unsigned int need_more_hdr;
  32        unsigned int msg_too_big;
  33        unsigned int msg_timeouts;
  34        unsigned int bad_hdr_len;
  35        unsigned int aborts;
  36        unsigned int interrupted;
  37        unsigned int unrecov_intr;
  38};
  39
  40struct strparser;
  41
  42/* Callbacks are called with lock held for the attached socket */
  43struct strp_callbacks {
  44        int (*parse_msg)(struct strparser *strp, struct sk_buff *skb);
  45        void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb);
  46        int (*read_sock_done)(struct strparser *strp, int err);
  47        void (*abort_parser)(struct strparser *strp, int err);
  48        void (*lock)(struct strparser *strp);
  49        void (*unlock)(struct strparser *strp);
  50};
  51
  52struct strp_msg {
  53        int full_len;
  54        int offset;
  55};
  56
  57static inline struct strp_msg *strp_msg(struct sk_buff *skb)
  58{
  59        return (struct strp_msg *)((void *)skb->cb +
  60                offsetof(struct qdisc_skb_cb, data));
  61}
  62
  63/* Structure for an attached lower socket */
  64struct strparser {
  65        struct sock *sk;
  66
  67        u32 stopped : 1;
  68        u32 paused : 1;
  69        u32 aborted : 1;
  70        u32 interrupted : 1;
  71        u32 unrecov_intr : 1;
  72
  73        struct sk_buff **skb_nextp;
  74        struct sk_buff *skb_head;
  75        unsigned int need_bytes;
  76        struct delayed_work msg_timer_work;
  77        struct work_struct work;
  78        struct strp_stats stats;
  79        struct strp_callbacks cb;
  80};
  81
  82/* Must be called with lock held for attached socket */
  83static inline void strp_pause(struct strparser *strp)
  84{
  85        strp->paused = 1;
  86}
  87
  88/* May be called without holding lock for attached socket */
  89void strp_unpause(struct strparser *strp);
  90/* Must be called with process lock held (lock_sock) */
  91void __strp_unpause(struct strparser *strp);
  92
  93static inline void save_strp_stats(struct strparser *strp,
  94                                   struct strp_aggr_stats *agg_stats)
  95{
  96        /* Save psock statistics in the mux when psock is being unattached. */
  97
  98#define SAVE_PSOCK_STATS(_stat) (agg_stats->_stat +=            \
  99                                 strp->stats._stat)
 100        SAVE_PSOCK_STATS(msgs);
 101        SAVE_PSOCK_STATS(bytes);
 102        SAVE_PSOCK_STATS(mem_fail);
 103        SAVE_PSOCK_STATS(need_more_hdr);
 104        SAVE_PSOCK_STATS(msg_too_big);
 105        SAVE_PSOCK_STATS(msg_timeouts);
 106        SAVE_PSOCK_STATS(bad_hdr_len);
 107#undef SAVE_PSOCK_STATS
 108
 109        if (strp->aborted)
 110                agg_stats->aborts++;
 111        if (strp->interrupted)
 112                agg_stats->interrupted++;
 113        if (strp->unrecov_intr)
 114                agg_stats->unrecov_intr++;
 115}
 116
 117static inline void aggregate_strp_stats(struct strp_aggr_stats *stats,
 118                                        struct strp_aggr_stats *agg_stats)
 119{
 120#define SAVE_PSOCK_STATS(_stat) (agg_stats->_stat += stats->_stat)
 121        SAVE_PSOCK_STATS(msgs);
 122        SAVE_PSOCK_STATS(bytes);
 123        SAVE_PSOCK_STATS(mem_fail);
 124        SAVE_PSOCK_STATS(need_more_hdr);
 125        SAVE_PSOCK_STATS(msg_too_big);
 126        SAVE_PSOCK_STATS(msg_timeouts);
 127        SAVE_PSOCK_STATS(bad_hdr_len);
 128        SAVE_PSOCK_STATS(aborts);
 129        SAVE_PSOCK_STATS(interrupted);
 130        SAVE_PSOCK_STATS(unrecov_intr);
 131#undef SAVE_PSOCK_STATS
 132
 133}
 134
 135void strp_done(struct strparser *strp);
 136void strp_stop(struct strparser *strp);
 137void strp_check_rcv(struct strparser *strp);
 138int strp_init(struct strparser *strp, struct sock *sk,
 139              const struct strp_callbacks *cb);
 140void strp_data_ready(struct strparser *strp);
 141int strp_process(struct strparser *strp, struct sk_buff *orig_skb,
 142                 unsigned int orig_offset, size_t orig_len,
 143                 size_t max_msg_size, long timeo);
 144
 145#endif /* __NET_STRPARSER_H_ */
 146