at v5.4 3.8 kB view raw
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_ */