feat.h 4.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#ifndef _DCCP_FEAT_H
#define _DCCP_FEAT_H
/*
 *  net/dccp/feat.h
 *
 *  An implementation of the DCCP protocol
 *  Copyright (c) 2005 Andrea Bittau <a.bittau@cs.ucl.ac.uk>
 *
 *	This program is free software; you can redistribute it and/or modify it
 *	under the terms of the GNU General Public License version 2 as
 *	published by the Free Software Foundation.
 */

#include <linux/types.h>
15
#include "dccp.h"
16

17 18 19 20 21 22 23 24 25
/*
 * Known limit values
 */
/* Ack Ratio takes 2-byte integer values (11.3) */
#define DCCPF_ACK_RATIO_MAX	0xFFFF
/* Wmin=32 and Wmax=2^46-1 from 7.5.2 */
#define DCCPF_SEQ_WMIN		32
#define DCCPF_SEQ_WMAX		0x3FFFFFFFFFFFull

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
enum dccp_feat_type {
	FEAT_AT_RX   = 1,	/* located at RX side of half-connection  */
	FEAT_AT_TX   = 2,	/* located at TX side of half-connection  */
	FEAT_SP      = 4,	/* server-priority reconciliation (6.3.1) */
	FEAT_NN	     = 8,	/* non-negotiable reconciliation (6.3.2)  */
	FEAT_UNKNOWN = 0xFF	/* not understood or invalid feature	  */
};

enum dccp_feat_state {
	FEAT_DEFAULT = 0,	/* using default values from 6.4 */
	FEAT_INITIALISING,	/* feature is being initialised  */
	FEAT_CHANGING,		/* Change sent but not confirmed yet */
	FEAT_UNSTABLE,		/* local modification in state CHANGING */
	FEAT_STABLE		/* both ends (think they) agree */
};

/**
 * dccp_feat_val  -  Container for SP or NN feature values
 * @nn:     single NN value
 * @sp.vec: single SP value plus optional preference list
 * @sp.len: length of @sp.vec in bytes
 */
typedef union {
	u64 nn;
	struct {
		u8	*vec;
		u8	len;
	}   sp;
} dccp_feat_val;

/**
 * struct feat_entry  -  Data structure to perform feature negotiation
 * @val: feature's current value (SP features may have preference list)
 * @state: feature's current state
 * @feat_num: one of %dccp_feature_numbers
 * @needs_mandatory: whether Mandatory options should be sent
 * @needs_confirm: whether to send a Confirm instead of a Change
 * @empty_confirm: whether to send an empty Confirm (depends on @needs_confirm)
 * @is_local: feature location (1) or feature-remote (0)
 * @node: list pointers, entries arranged in FIFO order
 */
struct dccp_feat_entry {
	dccp_feat_val           val;
	enum dccp_feat_state    state:8;
	u8                      feat_num;

	bool			needs_mandatory,
				needs_confirm,
				empty_confirm,
				is_local;

	struct list_head	node;
};

static inline u8 dccp_feat_genopt(struct dccp_feat_entry *entry)
{
	if (entry->needs_confirm)
		return entry->is_local ? DCCPO_CONFIRM_L : DCCPO_CONFIRM_R;
	return entry->is_local ? DCCPO_CHANGE_L : DCCPO_CHANGE_R;
}

87 88 89 90 91 92 93 94 95 96 97 98 99 100
/**
 * struct ccid_dependency  -  Track changes resulting from choosing a CCID
 * @dependent_feat: one of %dccp_feature_numbers
 * @is_local: local (1) or remote (0) @dependent_feat
 * @is_mandatory: whether presence of @dependent_feat is mission-critical or not
 * @val: corresponding default value for @dependent_feat (u8 is sufficient here)
 */
struct ccid_dependency {
	u8	dependent_feat;
	bool	is_local:1,
		is_mandatory:1;
	u8	val;
};

101 102 103 104 105 106 107 108 109 110 111 112
#ifdef CONFIG_IP_DCCP_DEBUG
extern const char *dccp_feat_typename(const u8 type);
extern const char *dccp_feat_name(const u8 feat);

static inline void dccp_feat_debug(const u8 type, const u8 feat, const u8 val)
{
	dccp_pr_debug("%s(%s (%d), %d)\n", dccp_feat_typename(type),
					   dccp_feat_name(feat), feat, val);
}
#else
#define dccp_feat_debug(type, feat, val)
#endif /* CONFIG_IP_DCCP_DEBUG */
113

114 115 116
extern int  dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
				  u8 const *list, u8 len);
extern int  dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val);
117 118 119 120
extern int  dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature,
				  u8 *val, u8 len);
extern int  dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
				   u8 *val, u8 len);
121
extern void dccp_feat_clean(struct dccp_minisock *dmsk);
122
extern int  dccp_feat_clone(struct sock *oldsk, struct sock *newsk);
123
extern int  dccp_feat_clone_list(struct list_head const *, struct list_head *);
124
extern int  dccp_feat_init(struct sock *sk);
125 126

#endif /* _DCCP_FEAT_H */