Line data Source code
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 : 17 : struct 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 : 27 : struct 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 : 40 : struct strparser; 41 : 42 : /* Callbacks are called with lock held for the attached socket */ 43 : struct 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 : 52 : struct strp_msg { 53 : int full_len; 54 : int offset; 55 : }; 56 : 57 0 : static inline struct strp_msg *strp_msg(struct sk_buff *skb) 58 : { 59 0 : return (struct strp_msg *)((void *)skb->cb + 60 : offsetof(struct qdisc_skb_cb, data)); 61 : } 62 : 63 : /* Structure for an attached lower socket */ 64 : struct 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 */ 83 : static inline void strp_pause(struct strparser *strp) 84 : { 85 : strp->paused = 1; 86 : } 87 : 88 : /* May be called without holding lock for attached socket */ 89 : void strp_unpause(struct strparser *strp); 90 : /* Must be called with process lock held (lock_sock) */ 91 : void __strp_unpause(struct strparser *strp); 92 : 93 : static 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 : 117 : static 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 : 135 : void strp_done(struct strparser *strp); 136 : void strp_stop(struct strparser *strp); 137 : void strp_check_rcv(struct strparser *strp); 138 : int strp_init(struct strparser *strp, struct sock *sk, 139 : const struct strp_callbacks *cb); 140 : void strp_data_ready(struct strparser *strp); 141 : int 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_ */