1afe00251SAndrea Bittau #ifndef _DCCP_FEAT_H 2afe00251SAndrea Bittau #define _DCCP_FEAT_H 3afe00251SAndrea Bittau /* 4afe00251SAndrea Bittau * net/dccp/feat.h 5afe00251SAndrea Bittau * 6*63b8e286SGerrit Renker * Feature negotiation for the DCCP protocol (RFC 4340, section 6) 7*63b8e286SGerrit Renker * Copyright (c) 2008 Gerrit Renker <gerrit@erg.abdn.ac.uk> 8afe00251SAndrea Bittau * Copyright (c) 2005 Andrea Bittau <a.bittau@cs.ucl.ac.uk> 9afe00251SAndrea Bittau * 10afe00251SAndrea Bittau * This program is free software; you can redistribute it and/or modify it 11afe00251SAndrea Bittau * under the terms of the GNU General Public License version 2 as 12afe00251SAndrea Bittau * published by the Free Software Foundation. 13afe00251SAndrea Bittau */ 14afe00251SAndrea Bittau #include <linux/types.h> 15c02fdc0eSGerrit Renker #include "dccp.h" 16afe00251SAndrea Bittau 17e8ef967aSGerrit Renker /* 18e8ef967aSGerrit Renker * Known limit values 19e8ef967aSGerrit Renker */ 20e8ef967aSGerrit Renker /* Ack Ratio takes 2-byte integer values (11.3) */ 21e8ef967aSGerrit Renker #define DCCPF_ACK_RATIO_MAX 0xFFFF 22e8ef967aSGerrit Renker /* Wmin=32 and Wmax=2^46-1 from 7.5.2 */ 23e8ef967aSGerrit Renker #define DCCPF_SEQ_WMIN 32 24e8ef967aSGerrit Renker #define DCCPF_SEQ_WMAX 0x3FFFFFFFFFFFull 25b20a9c24SGerrit Renker /* Maximum number of SP values that fit in a single (Confirm) option */ 26b20a9c24SGerrit Renker #define DCCP_FEAT_MAX_SP_VALS (DCCP_SINGLE_OPT_MAXLEN - 2) 27e8ef967aSGerrit Renker 28bd012f2eSGerrit Renker enum dccp_feat_type { 29bd012f2eSGerrit Renker FEAT_AT_RX = 1, /* located at RX side of half-connection */ 30bd012f2eSGerrit Renker FEAT_AT_TX = 2, /* located at TX side of half-connection */ 31bd012f2eSGerrit Renker FEAT_SP = 4, /* server-priority reconciliation (6.3.1) */ 32bd012f2eSGerrit Renker FEAT_NN = 8, /* non-negotiable reconciliation (6.3.2) */ 33bd012f2eSGerrit Renker FEAT_UNKNOWN = 0xFF /* not understood or invalid feature */ 34bd012f2eSGerrit Renker }; 35bd012f2eSGerrit Renker 36bd012f2eSGerrit Renker enum dccp_feat_state { 37bd012f2eSGerrit Renker FEAT_DEFAULT = 0, /* using default values from 6.4 */ 38bd012f2eSGerrit Renker FEAT_INITIALISING, /* feature is being initialised */ 39bd012f2eSGerrit Renker FEAT_CHANGING, /* Change sent but not confirmed yet */ 40bd012f2eSGerrit Renker FEAT_UNSTABLE, /* local modification in state CHANGING */ 41bd012f2eSGerrit Renker FEAT_STABLE /* both ends (think they) agree */ 42bd012f2eSGerrit Renker }; 43bd012f2eSGerrit Renker 44bd012f2eSGerrit Renker /** 45bd012f2eSGerrit Renker * dccp_feat_val - Container for SP or NN feature values 46bd012f2eSGerrit Renker * @nn: single NN value 47bd012f2eSGerrit Renker * @sp.vec: single SP value plus optional preference list 48bd012f2eSGerrit Renker * @sp.len: length of @sp.vec in bytes 49bd012f2eSGerrit Renker */ 50bd012f2eSGerrit Renker typedef union { 51bd012f2eSGerrit Renker u64 nn; 52bd012f2eSGerrit Renker struct { 53bd012f2eSGerrit Renker u8 *vec; 54bd012f2eSGerrit Renker u8 len; 55bd012f2eSGerrit Renker } sp; 56bd012f2eSGerrit Renker } dccp_feat_val; 57bd012f2eSGerrit Renker 58bd012f2eSGerrit Renker /** 59bd012f2eSGerrit Renker * struct feat_entry - Data structure to perform feature negotiation 60bd012f2eSGerrit Renker * @val: feature's current value (SP features may have preference list) 61bd012f2eSGerrit Renker * @state: feature's current state 62bd012f2eSGerrit Renker * @feat_num: one of %dccp_feature_numbers 63bd012f2eSGerrit Renker * @needs_mandatory: whether Mandatory options should be sent 64bd012f2eSGerrit Renker * @needs_confirm: whether to send a Confirm instead of a Change 65bd012f2eSGerrit Renker * @empty_confirm: whether to send an empty Confirm (depends on @needs_confirm) 66bd012f2eSGerrit Renker * @is_local: feature location (1) or feature-remote (0) 67bd012f2eSGerrit Renker * @node: list pointers, entries arranged in FIFO order 68bd012f2eSGerrit Renker */ 69bd012f2eSGerrit Renker struct dccp_feat_entry { 70bd012f2eSGerrit Renker dccp_feat_val val; 71bd012f2eSGerrit Renker enum dccp_feat_state state:8; 72bd012f2eSGerrit Renker u8 feat_num; 73bd012f2eSGerrit Renker 74bd012f2eSGerrit Renker bool needs_mandatory, 75bd012f2eSGerrit Renker needs_confirm, 76bd012f2eSGerrit Renker empty_confirm, 77bd012f2eSGerrit Renker is_local; 78bd012f2eSGerrit Renker 79bd012f2eSGerrit Renker struct list_head node; 80bd012f2eSGerrit Renker }; 81bd012f2eSGerrit Renker 82bd012f2eSGerrit Renker static inline u8 dccp_feat_genopt(struct dccp_feat_entry *entry) 83bd012f2eSGerrit Renker { 84bd012f2eSGerrit Renker if (entry->needs_confirm) 85bd012f2eSGerrit Renker return entry->is_local ? DCCPO_CONFIRM_L : DCCPO_CONFIRM_R; 86bd012f2eSGerrit Renker return entry->is_local ? DCCPO_CHANGE_L : DCCPO_CHANGE_R; 87bd012f2eSGerrit Renker } 88bd012f2eSGerrit Renker 89e8ef967aSGerrit Renker /** 90e8ef967aSGerrit Renker * struct ccid_dependency - Track changes resulting from choosing a CCID 91e8ef967aSGerrit Renker * @dependent_feat: one of %dccp_feature_numbers 92e8ef967aSGerrit Renker * @is_local: local (1) or remote (0) @dependent_feat 93e8ef967aSGerrit Renker * @is_mandatory: whether presence of @dependent_feat is mission-critical or not 94e8ef967aSGerrit Renker * @val: corresponding default value for @dependent_feat (u8 is sufficient here) 95e8ef967aSGerrit Renker */ 96e8ef967aSGerrit Renker struct ccid_dependency { 97e8ef967aSGerrit Renker u8 dependent_feat; 98e8ef967aSGerrit Renker bool is_local:1, 99e8ef967aSGerrit Renker is_mandatory:1; 100e8ef967aSGerrit Renker u8 val; 101e8ef967aSGerrit Renker }; 102e8ef967aSGerrit Renker 103c02fdc0eSGerrit Renker #ifdef CONFIG_IP_DCCP_DEBUG 104c02fdc0eSGerrit Renker extern const char *dccp_feat_typename(const u8 type); 105c02fdc0eSGerrit Renker extern const char *dccp_feat_name(const u8 feat); 106c02fdc0eSGerrit Renker 107c02fdc0eSGerrit Renker static inline void dccp_feat_debug(const u8 type, const u8 feat, const u8 val) 108c02fdc0eSGerrit Renker { 109c02fdc0eSGerrit Renker dccp_pr_debug("%s(%s (%d), %d)\n", dccp_feat_typename(type), 110c02fdc0eSGerrit Renker dccp_feat_name(feat), feat, val); 111c02fdc0eSGerrit Renker } 112c02fdc0eSGerrit Renker #else 113c02fdc0eSGerrit Renker #define dccp_feat_debug(type, feat, val) 114c02fdc0eSGerrit Renker #endif /* CONFIG_IP_DCCP_DEBUG */ 115afe00251SAndrea Bittau 11649aebc66SGerrit Renker extern int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local, 11749aebc66SGerrit Renker u8 const *list, u8 len); 11849aebc66SGerrit Renker extern int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val); 119e77b8363SGerrit Renker extern int dccp_feat_parse_options(struct sock *, struct dccp_request_sock *, 120e77b8363SGerrit Renker u8 mand, u8 opt, u8 feat, u8 *val, u8 len); 121ac75773cSGerrit Renker extern int dccp_feat_clone_list(struct list_head const *, struct list_head *); 122e8ef967aSGerrit Renker extern int dccp_feat_init(struct sock *sk); 123afe00251SAndrea Bittau 12402fa460eSGerrit Renker /* 12502fa460eSGerrit Renker * Encoding variable-length options and their maximum length. 12602fa460eSGerrit Renker * 12702fa460eSGerrit Renker * This affects NN options (SP options are all u8) and other variable-length 12802fa460eSGerrit Renker * options (see table 3 in RFC 4340). The limit is currently given the Sequence 12902fa460eSGerrit Renker * Window NN value (sec. 7.5.2) and the NDP count (sec. 7.7) option, all other 13002fa460eSGerrit Renker * options consume less than 6 bytes (timestamps are 4 bytes). 13102fa460eSGerrit Renker * When updating this constant (e.g. due to new internet drafts / RFCs), make 13202fa460eSGerrit Renker * sure that you also update all code which refers to it. 13302fa460eSGerrit Renker */ 13402fa460eSGerrit Renker #define DCCP_OPTVAL_MAXLEN 6 13502fa460eSGerrit Renker 13602fa460eSGerrit Renker extern void dccp_encode_value_var(const u64 value, u8 *to, const u8 len); 13702fa460eSGerrit Renker extern u64 dccp_decode_value_var(const u8 *bf, const u8 len); 138d3710566SGerrit Renker 139d3710566SGerrit Renker extern int dccp_insert_option_mandatory(struct sk_buff *skb); 1408c862c23SGerrit Renker extern int dccp_insert_fn_opt(struct sk_buff *skb, u8 type, u8 feat, 1418c862c23SGerrit Renker u8 *val, u8 len, bool repeat_first); 142afe00251SAndrea Bittau #endif /* _DCCP_FEAT_H */ 143