at v4.18 3.9 kB view raw
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 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 30struct 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 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 void (*lock)(struct strparser *strp); 52 void (*unlock)(struct strparser *strp); 53}; 54 55struct strp_msg { 56 int full_len; 57 int offset; 58}; 59 60static 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 */ 67struct 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 */ 86static inline void strp_pause(struct strparser *strp) 87{ 88 strp->paused = 1; 89} 90 91/* May be called without holding lock for attached socket */ 92void strp_unpause(struct strparser *strp); 93/* Must be called with process lock held (lock_sock) */ 94void __strp_unpause(struct strparser *strp); 95 96static 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 120static 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 138void strp_done(struct strparser *strp); 139void strp_stop(struct strparser *strp); 140void strp_check_rcv(struct strparser *strp); 141int strp_init(struct strparser *strp, struct sock *sk, 142 const struct strp_callbacks *cb); 143void strp_data_ready(struct strparser *strp); 144int 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_ */