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)(struct strparser *strp, read_descriptor_t *desc, 47 sk_read_actor_t recv_actor); 48 int (*read_sock_done)(struct strparser *strp, int err); 49 void (*abort_parser)(struct strparser *strp, int err); 50 void (*lock)(struct strparser *strp); 51 void (*unlock)(struct strparser *strp); 52 }; 53 54 struct strp_msg { 55 int full_len; 56 int offset; 57 }; 58 59 struct _strp_msg { 60 /* Internal cb structure. struct strp_msg must be first for passing 61 * to upper layer. 62 */ 63 struct strp_msg strp; 64 int accum_len; 65 }; 66 67 struct sk_skb_cb { 68 #define SK_SKB_CB_PRIV_LEN 20 69 unsigned char data[SK_SKB_CB_PRIV_LEN]; 70 /* align strp on cache line boundary within skb->cb[] */ 71 unsigned char pad[4]; 72 struct _strp_msg strp; 73 74 /* strp users' data follows */ 75 struct tls_msg { 76 u8 control; 77 } tls; 78 /* temp_reg is a temporary register used for bpf_convert_data_end_access 79 * when dst_reg == src_reg. 80 */ 81 u64 temp_reg; 82 }; 83 84 static inline struct strp_msg *strp_msg(struct sk_buff *skb) 85 { 86 return (struct strp_msg *)((void *)skb->cb + 87 offsetof(struct sk_skb_cb, strp)); 88 } 89 90 /* Structure for an attached lower socket */ 91 struct strparser { 92 struct sock *sk; 93 94 u32 stopped : 1; 95 u32 paused : 1; 96 u32 aborted : 1; 97 u32 interrupted : 1; 98 u32 unrecov_intr : 1; 99 100 struct sk_buff **skb_nextp; 101 struct sk_buff *skb_head; 102 unsigned int need_bytes; 103 struct delayed_work msg_timer_work; 104 struct work_struct work; 105 struct strp_stats stats; 106 struct strp_callbacks cb; 107 }; 108 109 /* Must be called with lock held for attached socket */ 110 static inline void strp_pause(struct strparser *strp) 111 { 112 strp->paused = 1; 113 } 114 115 /* May be called without holding lock for attached socket */ 116 void strp_unpause(struct strparser *strp); 117 118 static inline void save_strp_stats(struct strparser *strp, 119 struct strp_aggr_stats *agg_stats) 120 { 121 /* Save psock statistics in the mux when psock is being unattached. */ 122 123 #define SAVE_PSOCK_STATS(_stat) (agg_stats->_stat += \ 124 strp->stats._stat) 125 SAVE_PSOCK_STATS(msgs); 126 SAVE_PSOCK_STATS(bytes); 127 SAVE_PSOCK_STATS(mem_fail); 128 SAVE_PSOCK_STATS(need_more_hdr); 129 SAVE_PSOCK_STATS(msg_too_big); 130 SAVE_PSOCK_STATS(msg_timeouts); 131 SAVE_PSOCK_STATS(bad_hdr_len); 132 #undef SAVE_PSOCK_STATS 133 134 if (strp->aborted) 135 agg_stats->aborts++; 136 if (strp->interrupted) 137 agg_stats->interrupted++; 138 if (strp->unrecov_intr) 139 agg_stats->unrecov_intr++; 140 } 141 142 static inline void aggregate_strp_stats(struct strp_aggr_stats *stats, 143 struct strp_aggr_stats *agg_stats) 144 { 145 #define SAVE_PSOCK_STATS(_stat) (agg_stats->_stat += stats->_stat) 146 SAVE_PSOCK_STATS(msgs); 147 SAVE_PSOCK_STATS(bytes); 148 SAVE_PSOCK_STATS(mem_fail); 149 SAVE_PSOCK_STATS(need_more_hdr); 150 SAVE_PSOCK_STATS(msg_too_big); 151 SAVE_PSOCK_STATS(msg_timeouts); 152 SAVE_PSOCK_STATS(bad_hdr_len); 153 SAVE_PSOCK_STATS(aborts); 154 SAVE_PSOCK_STATS(interrupted); 155 SAVE_PSOCK_STATS(unrecov_intr); 156 #undef SAVE_PSOCK_STATS 157 158 } 159 160 void strp_done(struct strparser *strp); 161 void strp_stop(struct strparser *strp); 162 void strp_check_rcv(struct strparser *strp); 163 int strp_init(struct strparser *strp, struct sock *sk, 164 const struct strp_callbacks *cb); 165 void strp_data_ready(struct strparser *strp); 166 int strp_process(struct strparser *strp, struct sk_buff *orig_skb, 167 unsigned int orig_offset, size_t orig_len, 168 size_t max_msg_size, long timeo); 169 170 #endif /* __NET_STRPARSER_H_ */ 171