1*4524b259SArnaldo Carvalho de Melo /* 2*4524b259SArnaldo Carvalho de Melo * net/dccp/packet_history.h 3*4524b259SArnaldo Carvalho de Melo * 4*4524b259SArnaldo Carvalho de Melo * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. 5*4524b259SArnaldo Carvalho de Melo * 6*4524b259SArnaldo Carvalho de Melo * An implementation of the DCCP protocol 7*4524b259SArnaldo Carvalho de Melo * 8*4524b259SArnaldo Carvalho de Melo * This code has been developed by the University of Waikato WAND 9*4524b259SArnaldo Carvalho de Melo * research group. For further information please see http://www.wand.net.nz/ 10*4524b259SArnaldo Carvalho de Melo * or e-mail Ian McDonald - iam4@cs.waikato.ac.nz 11*4524b259SArnaldo Carvalho de Melo * 12*4524b259SArnaldo Carvalho de Melo * This code also uses code from Lulea University, rereleased as GPL by its 13*4524b259SArnaldo Carvalho de Melo * authors: 14*4524b259SArnaldo Carvalho de Melo * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon 15*4524b259SArnaldo Carvalho de Melo * 16*4524b259SArnaldo Carvalho de Melo * Changes to meet Linux coding standards, to make it meet latest ccid3 draft 17*4524b259SArnaldo Carvalho de Melo * and to make it work as a loadable module in the DCCP stack written by 18*4524b259SArnaldo Carvalho de Melo * Arnaldo Carvalho de Melo <acme@conectiva.com.br>. 19*4524b259SArnaldo Carvalho de Melo * 20*4524b259SArnaldo Carvalho de Melo * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 21*4524b259SArnaldo Carvalho de Melo * 22*4524b259SArnaldo Carvalho de Melo * This program is free software; you can redistribute it and/or modify 23*4524b259SArnaldo Carvalho de Melo * it under the terms of the GNU General Public License as published by 24*4524b259SArnaldo Carvalho de Melo * the Free Software Foundation; either version 2 of the License, or 25*4524b259SArnaldo Carvalho de Melo * (at your option) any later version. 26*4524b259SArnaldo Carvalho de Melo * 27*4524b259SArnaldo Carvalho de Melo * This program is distributed in the hope that it will be useful, 28*4524b259SArnaldo Carvalho de Melo * but WITHOUT ANY WARRANTY; without even the implied warranty of 29*4524b259SArnaldo Carvalho de Melo * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30*4524b259SArnaldo Carvalho de Melo * GNU General Public License for more details. 31*4524b259SArnaldo Carvalho de Melo * 32*4524b259SArnaldo Carvalho de Melo * You should have received a copy of the GNU General Public License 33*4524b259SArnaldo Carvalho de Melo * along with this program; if not, write to the Free Software 34*4524b259SArnaldo Carvalho de Melo * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 35*4524b259SArnaldo Carvalho de Melo */ 36*4524b259SArnaldo Carvalho de Melo 37*4524b259SArnaldo Carvalho de Melo #ifndef _DCCP_PKT_HIST_ 38*4524b259SArnaldo Carvalho de Melo #define _DCCP_PKT_HIST_ 39*4524b259SArnaldo Carvalho de Melo 40*4524b259SArnaldo Carvalho de Melo #include <linux/config.h> 41*4524b259SArnaldo Carvalho de Melo #include <linux/list.h> 42*4524b259SArnaldo Carvalho de Melo #include <linux/slab.h> 43*4524b259SArnaldo Carvalho de Melo #include <linux/time.h> 44*4524b259SArnaldo Carvalho de Melo 45*4524b259SArnaldo Carvalho de Melo #include "../../dccp.h" 46*4524b259SArnaldo Carvalho de Melo 47*4524b259SArnaldo Carvalho de Melo struct dccp_tx_hist_entry { 48*4524b259SArnaldo Carvalho de Melo struct list_head dccphtx_node; 49*4524b259SArnaldo Carvalho de Melo u64 dccphtx_seqno:48, 50*4524b259SArnaldo Carvalho de Melo dccphtx_ccval:4, 51*4524b259SArnaldo Carvalho de Melo dccphtx_sent:1; 52*4524b259SArnaldo Carvalho de Melo u32 dccphtx_rtt; 53*4524b259SArnaldo Carvalho de Melo struct timeval dccphtx_tstamp; 54*4524b259SArnaldo Carvalho de Melo }; 55*4524b259SArnaldo Carvalho de Melo 56*4524b259SArnaldo Carvalho de Melo struct dccp_rx_hist_entry { 57*4524b259SArnaldo Carvalho de Melo struct list_head dccphrx_node; 58*4524b259SArnaldo Carvalho de Melo u64 dccphrx_seqno:48, 59*4524b259SArnaldo Carvalho de Melo dccphrx_ccval:4, 60*4524b259SArnaldo Carvalho de Melo dccphrx_type:4; 61*4524b259SArnaldo Carvalho de Melo u32 dccphrx_ndp; /* In fact it is from 8 to 24 bits */ 62*4524b259SArnaldo Carvalho de Melo struct timeval dccphrx_tstamp; 63*4524b259SArnaldo Carvalho de Melo }; 64*4524b259SArnaldo Carvalho de Melo 65*4524b259SArnaldo Carvalho de Melo struct dccp_tx_hist { 66*4524b259SArnaldo Carvalho de Melo kmem_cache_t *dccptxh_slab; 67*4524b259SArnaldo Carvalho de Melo }; 68*4524b259SArnaldo Carvalho de Melo 69*4524b259SArnaldo Carvalho de Melo extern struct dccp_tx_hist *dccp_tx_hist_new(const char *name); 70*4524b259SArnaldo Carvalho de Melo extern void dccp_tx_hist_delete(struct dccp_tx_hist *hist); 71*4524b259SArnaldo Carvalho de Melo 72*4524b259SArnaldo Carvalho de Melo struct dccp_rx_hist { 73*4524b259SArnaldo Carvalho de Melo kmem_cache_t *dccprxh_slab; 74*4524b259SArnaldo Carvalho de Melo }; 75*4524b259SArnaldo Carvalho de Melo 76*4524b259SArnaldo Carvalho de Melo extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name); 77*4524b259SArnaldo Carvalho de Melo extern void dccp_rx_hist_delete(struct dccp_rx_hist *hist); 78*4524b259SArnaldo Carvalho de Melo extern struct dccp_rx_hist_entry * 79*4524b259SArnaldo Carvalho de Melo dccp_rx_hist_find_data_packet(const struct list_head *list); 80*4524b259SArnaldo Carvalho de Melo 81*4524b259SArnaldo Carvalho de Melo static inline struct dccp_tx_hist_entry * 82*4524b259SArnaldo Carvalho de Melo dccp_tx_hist_entry_new(struct dccp_tx_hist *hist, 83*4524b259SArnaldo Carvalho de Melo const unsigned int __nocast prio) 84*4524b259SArnaldo Carvalho de Melo { 85*4524b259SArnaldo Carvalho de Melo struct dccp_tx_hist_entry *entry = kmem_cache_alloc(hist->dccptxh_slab, 86*4524b259SArnaldo Carvalho de Melo prio); 87*4524b259SArnaldo Carvalho de Melo 88*4524b259SArnaldo Carvalho de Melo if (entry != NULL) 89*4524b259SArnaldo Carvalho de Melo entry->dccphtx_sent = 0; 90*4524b259SArnaldo Carvalho de Melo 91*4524b259SArnaldo Carvalho de Melo return entry; 92*4524b259SArnaldo Carvalho de Melo } 93*4524b259SArnaldo Carvalho de Melo 94*4524b259SArnaldo Carvalho de Melo static inline void dccp_tx_hist_entry_delete(struct dccp_tx_hist *hist, 95*4524b259SArnaldo Carvalho de Melo struct dccp_tx_hist_entry *entry) 96*4524b259SArnaldo Carvalho de Melo { 97*4524b259SArnaldo Carvalho de Melo if (entry != NULL) 98*4524b259SArnaldo Carvalho de Melo kmem_cache_free(hist->dccptxh_slab, entry); 99*4524b259SArnaldo Carvalho de Melo } 100*4524b259SArnaldo Carvalho de Melo 101*4524b259SArnaldo Carvalho de Melo extern struct dccp_tx_hist_entry * 102*4524b259SArnaldo Carvalho de Melo dccp_tx_hist_find_entry(const struct list_head *list, 103*4524b259SArnaldo Carvalho de Melo const u64 seq); 104*4524b259SArnaldo Carvalho de Melo 105*4524b259SArnaldo Carvalho de Melo static inline void dccp_tx_hist_add_entry(struct list_head *list, 106*4524b259SArnaldo Carvalho de Melo struct dccp_tx_hist_entry *entry) 107*4524b259SArnaldo Carvalho de Melo { 108*4524b259SArnaldo Carvalho de Melo list_add(&entry->dccphtx_node, list); 109*4524b259SArnaldo Carvalho de Melo } 110*4524b259SArnaldo Carvalho de Melo 111*4524b259SArnaldo Carvalho de Melo extern void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist, 112*4524b259SArnaldo Carvalho de Melo struct list_head *list, 113*4524b259SArnaldo Carvalho de Melo struct dccp_tx_hist_entry *next); 114*4524b259SArnaldo Carvalho de Melo 115*4524b259SArnaldo Carvalho de Melo extern void dccp_tx_hist_purge(struct dccp_tx_hist *hist, 116*4524b259SArnaldo Carvalho de Melo struct list_head *list); 117*4524b259SArnaldo Carvalho de Melo 118*4524b259SArnaldo Carvalho de Melo static inline struct dccp_tx_hist_entry * 119*4524b259SArnaldo Carvalho de Melo dccp_tx_hist_head(struct list_head *list) 120*4524b259SArnaldo Carvalho de Melo { 121*4524b259SArnaldo Carvalho de Melo struct dccp_tx_hist_entry *head = NULL; 122*4524b259SArnaldo Carvalho de Melo 123*4524b259SArnaldo Carvalho de Melo if (!list_empty(list)) 124*4524b259SArnaldo Carvalho de Melo head = list_entry(list->next, struct dccp_tx_hist_entry, 125*4524b259SArnaldo Carvalho de Melo dccphtx_node); 126*4524b259SArnaldo Carvalho de Melo return head; 127*4524b259SArnaldo Carvalho de Melo } 128*4524b259SArnaldo Carvalho de Melo 129*4524b259SArnaldo Carvalho de Melo static inline struct dccp_rx_hist_entry * 130*4524b259SArnaldo Carvalho de Melo dccp_rx_hist_entry_new(struct dccp_rx_hist *hist, 131*4524b259SArnaldo Carvalho de Melo const u32 ndp, 132*4524b259SArnaldo Carvalho de Melo const struct sk_buff *skb, 133*4524b259SArnaldo Carvalho de Melo const unsigned int __nocast prio) 134*4524b259SArnaldo Carvalho de Melo { 135*4524b259SArnaldo Carvalho de Melo struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab, 136*4524b259SArnaldo Carvalho de Melo prio); 137*4524b259SArnaldo Carvalho de Melo 138*4524b259SArnaldo Carvalho de Melo if (entry != NULL) { 139*4524b259SArnaldo Carvalho de Melo const struct dccp_hdr *dh = dccp_hdr(skb); 140*4524b259SArnaldo Carvalho de Melo 141*4524b259SArnaldo Carvalho de Melo entry->dccphrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq; 142*4524b259SArnaldo Carvalho de Melo entry->dccphrx_ccval = dh->dccph_ccval; 143*4524b259SArnaldo Carvalho de Melo entry->dccphrx_type = dh->dccph_type; 144*4524b259SArnaldo Carvalho de Melo entry->dccphrx_ndp = ndp; 145*4524b259SArnaldo Carvalho de Melo do_gettimeofday(&(entry->dccphrx_tstamp)); 146*4524b259SArnaldo Carvalho de Melo } 147*4524b259SArnaldo Carvalho de Melo 148*4524b259SArnaldo Carvalho de Melo return entry; 149*4524b259SArnaldo Carvalho de Melo } 150*4524b259SArnaldo Carvalho de Melo 151*4524b259SArnaldo Carvalho de Melo static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist, 152*4524b259SArnaldo Carvalho de Melo struct dccp_rx_hist_entry *entry) 153*4524b259SArnaldo Carvalho de Melo { 154*4524b259SArnaldo Carvalho de Melo if (entry != NULL) 155*4524b259SArnaldo Carvalho de Melo kmem_cache_free(hist->dccprxh_slab, entry); 156*4524b259SArnaldo Carvalho de Melo } 157*4524b259SArnaldo Carvalho de Melo 158*4524b259SArnaldo Carvalho de Melo extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist, 159*4524b259SArnaldo Carvalho de Melo struct list_head *list); 160*4524b259SArnaldo Carvalho de Melo 161*4524b259SArnaldo Carvalho de Melo static inline void dccp_rx_hist_add_entry(struct list_head *list, 162*4524b259SArnaldo Carvalho de Melo struct dccp_rx_hist_entry *entry) 163*4524b259SArnaldo Carvalho de Melo { 164*4524b259SArnaldo Carvalho de Melo list_add(&entry->dccphrx_node, list); 165*4524b259SArnaldo Carvalho de Melo } 166*4524b259SArnaldo Carvalho de Melo 167*4524b259SArnaldo Carvalho de Melo static inline struct dccp_rx_hist_entry * 168*4524b259SArnaldo Carvalho de Melo dccp_rx_hist_head(struct list_head *list) 169*4524b259SArnaldo Carvalho de Melo { 170*4524b259SArnaldo Carvalho de Melo struct dccp_rx_hist_entry *head = NULL; 171*4524b259SArnaldo Carvalho de Melo 172*4524b259SArnaldo Carvalho de Melo if (!list_empty(list)) 173*4524b259SArnaldo Carvalho de Melo head = list_entry(list->next, struct dccp_rx_hist_entry, 174*4524b259SArnaldo Carvalho de Melo dccphrx_node); 175*4524b259SArnaldo Carvalho de Melo return head; 176*4524b259SArnaldo Carvalho de Melo } 177*4524b259SArnaldo Carvalho de Melo 178*4524b259SArnaldo Carvalho de Melo static inline int 179*4524b259SArnaldo Carvalho de Melo dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry) 180*4524b259SArnaldo Carvalho de Melo { 181*4524b259SArnaldo Carvalho de Melo return entry->dccphrx_type == DCCP_PKT_DATA || 182*4524b259SArnaldo Carvalho de Melo entry->dccphrx_type == DCCP_PKT_DATAACK; 183*4524b259SArnaldo Carvalho de Melo } 184*4524b259SArnaldo Carvalho de Melo 185*4524b259SArnaldo Carvalho de Melo #endif /* _DCCP_PKT_HIST_ */ 186