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 rx_msgs;
  22        unsigned long long rx_bytes;
  23        unsigned int rx_mem_fail;
  24        unsigned int rx_need_more_hdr;
  25        unsigned int rx_msg_too_big;
  26        unsigned int rx_msg_timeouts;
  27        unsigned int rx_bad_hdr_len;
  28};
  29
  30struct strp_aggr_stats {
  31        unsigned long long rx_msgs;
  32        unsigned long long rx_bytes;
  33        unsigned int rx_mem_fail;
  34        unsigned int rx_need_more_hdr;
  35        unsigned int rx_msg_too_big;
  36        unsigned int rx_msg_timeouts;
  37        unsigned int rx_bad_hdr_len;
  38        unsigned int rx_aborts;
  39        unsigned int rx_interrupted;
  40        unsigned int rx_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};
  52
  53struct strp_rx_msg {
  54        int full_len;
  55        int offset;
  56};
  57
  58static inline struct strp_rx_msg *strp_rx_msg(struct sk_buff *skb)
  59{
  60        return (struct strp_rx_msg *)((void *)skb->cb +
  61                offsetof(struct qdisc_skb_cb, data));
  62}
  63
  64/* Structure for an attached lower socket */
  65struct strparser {
  66        struct sock *sk;
  67
  68        u32 rx_stopped : 1;
  69        u32 rx_paused : 1;
  70        u32 rx_aborted : 1;
  71        u32 rx_interrupted : 1;
  72        u32 rx_unrecov_intr : 1;
  73
  74        struct sk_buff **rx_skb_nextp;
  75        struct timer_list rx_msg_timer;
  76        struct sk_buff *rx_skb_head;
  77        unsigned int rx_need_bytes;
  78        struct delayed_work rx_delayed_work;
  79        struct work_struct rx_work;
  80        struct strp_stats stats;
  81        struct strp_callbacks cb;
  82};
  83
  84/* Must be called with lock held for attached socket */
  85static inline void strp_pause(struct strparser *strp)
  86{
  87        strp->rx_paused = 1;
  88}
  89
  90/* May be called without holding lock for attached socket */
  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(rx_msgs);
 101        SAVE_PSOCK_STATS(rx_bytes);
 102        SAVE_PSOCK_STATS(rx_mem_fail);
 103        SAVE_PSOCK_STATS(rx_need_more_hdr);
 104        SAVE_PSOCK_STATS(rx_msg_too_big);
 105        SAVE_PSOCK_STATS(rx_msg_timeouts);
 106        SAVE_PSOCK_STATS(rx_bad_hdr_len);
 107#undef SAVE_PSOCK_STATS
 108
 109        if (strp->rx_aborted)
 110                agg_stats->rx_aborts++;
 111        if (strp->rx_interrupted)
 112                agg_stats->rx_interrupted++;
 113        if (strp->rx_unrecov_intr)
 114                agg_stats->rx_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(rx_msgs);
 122        SAVE_PSOCK_STATS(rx_bytes);
 123        SAVE_PSOCK_STATS(rx_mem_fail);
 124        SAVE_PSOCK_STATS(rx_need_more_hdr);
 125        SAVE_PSOCK_STATS(rx_msg_too_big);
 126        SAVE_PSOCK_STATS(rx_msg_timeouts);
 127        SAVE_PSOCK_STATS(rx_bad_hdr_len);
 128        SAVE_PSOCK_STATS(rx_aborts);
 129        SAVE_PSOCK_STATS(rx_interrupted);
 130        SAVE_PSOCK_STATS(rx_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 *csk,
 139              struct strp_callbacks *cb);
 140void strp_data_ready(struct strparser *strp);
 141
 142#endif /* __NET_STRPARSER_H_ */
 143