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