Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Kernel Connection Multiplexor
0004  *
0005  * Copyright (c) 2016 Tom Herbert <tom@herbertland.com>
0006  */
0007 
0008 #ifndef __NET_KCM_H_
0009 #define __NET_KCM_H_
0010 
0011 #include <linux/skbuff.h>
0012 #include <net/sock.h>
0013 #include <net/strparser.h>
0014 #include <uapi/linux/kcm.h>
0015 
0016 extern unsigned int kcm_net_id;
0017 
0018 #define KCM_STATS_ADD(stat, count) ((stat) += (count))
0019 #define KCM_STATS_INCR(stat) ((stat)++)
0020 
0021 struct kcm_psock_stats {
0022     unsigned long long tx_msgs;
0023     unsigned long long tx_bytes;
0024     unsigned long long reserved;
0025     unsigned long long unreserved;
0026     unsigned int tx_aborts;
0027 };
0028 
0029 struct kcm_mux_stats {
0030     unsigned long long rx_msgs;
0031     unsigned long long rx_bytes;
0032     unsigned long long tx_msgs;
0033     unsigned long long tx_bytes;
0034     unsigned int rx_ready_drops;
0035     unsigned int tx_retries;
0036     unsigned int psock_attach;
0037     unsigned int psock_unattach_rsvd;
0038     unsigned int psock_unattach;
0039 };
0040 
0041 struct kcm_stats {
0042     unsigned long long rx_msgs;
0043     unsigned long long rx_bytes;
0044     unsigned long long tx_msgs;
0045     unsigned long long tx_bytes;
0046 };
0047 
0048 struct kcm_tx_msg {
0049     unsigned int sent;
0050     unsigned int fragidx;
0051     unsigned int frag_offset;
0052     unsigned int msg_flags;
0053     struct sk_buff *frag_skb;
0054     struct sk_buff *last_skb;
0055 };
0056 
0057 /* Socket structure for KCM client sockets */
0058 struct kcm_sock {
0059     struct sock sk;
0060     struct kcm_mux *mux;
0061     struct list_head kcm_sock_list;
0062     int index;
0063     u32 done : 1;
0064     struct work_struct done_work;
0065 
0066     struct kcm_stats stats;
0067 
0068     /* Transmit */
0069     struct kcm_psock *tx_psock;
0070     struct work_struct tx_work;
0071     struct list_head wait_psock_list;
0072     struct sk_buff *seq_skb;
0073     u32 tx_stopped : 1;
0074 
0075     /* Don't use bit fields here, these are set under different locks */
0076     bool tx_wait;
0077     bool tx_wait_more;
0078 
0079     /* Receive */
0080     struct kcm_psock *rx_psock;
0081     struct list_head wait_rx_list; /* KCMs waiting for receiving */
0082     bool rx_wait;
0083     u32 rx_disabled : 1;
0084 };
0085 
0086 struct bpf_prog;
0087 
0088 /* Structure for an attached lower socket */
0089 struct kcm_psock {
0090     struct sock *sk;
0091     struct strparser strp;
0092     struct kcm_mux *mux;
0093     int index;
0094 
0095     u32 tx_stopped : 1;
0096     u32 done : 1;
0097     u32 unattaching : 1;
0098 
0099     void (*save_state_change)(struct sock *sk);
0100     void (*save_data_ready)(struct sock *sk);
0101     void (*save_write_space)(struct sock *sk);
0102 
0103     struct list_head psock_list;
0104 
0105     struct kcm_psock_stats stats;
0106 
0107     /* Receive */
0108     struct list_head psock_ready_list;
0109     struct bpf_prog *bpf_prog;
0110     struct kcm_sock *rx_kcm;
0111     unsigned long long saved_rx_bytes;
0112     unsigned long long saved_rx_msgs;
0113     struct sk_buff *ready_rx_msg;
0114 
0115     /* Transmit */
0116     struct kcm_sock *tx_kcm;
0117     struct list_head psock_avail_list;
0118     unsigned long long saved_tx_bytes;
0119     unsigned long long saved_tx_msgs;
0120 };
0121 
0122 /* Per net MUX list */
0123 struct kcm_net {
0124     struct mutex mutex;
0125     struct kcm_psock_stats aggregate_psock_stats;
0126     struct kcm_mux_stats aggregate_mux_stats;
0127     struct strp_aggr_stats aggregate_strp_stats;
0128     struct list_head mux_list;
0129     int count;
0130 };
0131 
0132 /* Structure for a MUX */
0133 struct kcm_mux {
0134     struct list_head kcm_mux_list;
0135     struct rcu_head rcu;
0136     struct kcm_net *knet;
0137 
0138     struct list_head kcm_socks; /* All KCM sockets on MUX */
0139     int kcm_socks_cnt;      /* Total KCM socket count for MUX */
0140     struct list_head psocks;    /* List of all psocks on MUX */
0141     int psocks_cnt;     /* Total attached sockets */
0142 
0143     struct kcm_mux_stats stats;
0144     struct kcm_psock_stats aggregate_psock_stats;
0145     struct strp_aggr_stats aggregate_strp_stats;
0146 
0147     /* Receive */
0148     spinlock_t rx_lock ____cacheline_aligned_in_smp;
0149     struct list_head kcm_rx_waiters; /* KCMs waiting for receiving */
0150     struct list_head psocks_ready;  /* List of psocks with a msg ready */
0151     struct sk_buff_head rx_hold_queue;
0152 
0153     /* Transmit */
0154     spinlock_t  lock ____cacheline_aligned_in_smp;  /* TX and mux locking */
0155     struct list_head psocks_avail;  /* List of available psocks */
0156     struct list_head kcm_tx_waiters; /* KCMs waiting for a TX psock */
0157 };
0158 
0159 #ifdef CONFIG_PROC_FS
0160 int kcm_proc_init(void);
0161 void kcm_proc_exit(void);
0162 #else
0163 static inline int kcm_proc_init(void) { return 0; }
0164 static inline void kcm_proc_exit(void) { }
0165 #endif
0166 
0167 static inline void aggregate_psock_stats(struct kcm_psock_stats *stats,
0168                      struct kcm_psock_stats *agg_stats)
0169 {
0170     /* Save psock statistics in the mux when psock is being unattached. */
0171 
0172 #define SAVE_PSOCK_STATS(_stat) (agg_stats->_stat += stats->_stat)
0173     SAVE_PSOCK_STATS(tx_msgs);
0174     SAVE_PSOCK_STATS(tx_bytes);
0175     SAVE_PSOCK_STATS(reserved);
0176     SAVE_PSOCK_STATS(unreserved);
0177     SAVE_PSOCK_STATS(tx_aborts);
0178 #undef SAVE_PSOCK_STATS
0179 }
0180 
0181 static inline void aggregate_mux_stats(struct kcm_mux_stats *stats,
0182                        struct kcm_mux_stats *agg_stats)
0183 {
0184     /* Save psock statistics in the mux when psock is being unattached. */
0185 
0186 #define SAVE_MUX_STATS(_stat) (agg_stats->_stat += stats->_stat)
0187     SAVE_MUX_STATS(rx_msgs);
0188     SAVE_MUX_STATS(rx_bytes);
0189     SAVE_MUX_STATS(tx_msgs);
0190     SAVE_MUX_STATS(tx_bytes);
0191     SAVE_MUX_STATS(rx_ready_drops);
0192     SAVE_MUX_STATS(psock_attach);
0193     SAVE_MUX_STATS(psock_unattach_rsvd);
0194     SAVE_MUX_STATS(psock_unattach);
0195 #undef SAVE_MUX_STATS
0196 }
0197 
0198 #endif /* __NET_KCM_H_ */