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 20 struct 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 30 struct 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 43 struct strparser; 44 45 /* Callbacks are called with lock held for the attached socket */ 46 struct 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 55 struct strp_msg { 56 int full_len; 57 int offset; 58 }; 59 60 static 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 */ 67 struct 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 */ 86 static inline void strp_pause(struct strparser *strp) 87 { 88 strp->paused = 1; 89 } 90 91 /* May be called without holding lock for attached socket */ 92 void strp_unpause(struct strparser *strp); 93 /* Must be called with process lock held (lock_sock) */ 94 void __strp_unpause(struct strparser *strp); 95 96 static 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 120 static 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 138 void strp_done(struct strparser *strp); 139 void strp_stop(struct strparser *strp); 140 void strp_check_rcv(struct strparser *strp); 141 int strp_init(struct strparser *strp, struct sock *sk, 142 const struct strp_callbacks *cb); 143 void strp_data_ready(struct strparser *strp); 144 int 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