diff options
Diffstat (limited to 'include/net')
54 files changed, 1943 insertions, 276 deletions
| diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index a7fb54808a23..156c26bb8bd7 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -86,6 +86,10 @@ do { \  /**   * enum p9_msg_t - 9P message types + * @P9_TSTATFS: file system status request + * @P9_RSTATFS: file system status response + * @P9_TRENAME: rename request + * @P9_RRENAME: rename response   * @P9_TVERSION: version handshake request   * @P9_RVERSION: version handshake response   * @P9_TAUTH: request to establish authentication channel @@ -125,6 +129,10 @@ do { \   */  enum p9_msg_t { +	P9_TSTATFS = 8, +	P9_RSTATFS, +	P9_TRENAME = 20, +	P9_RRENAME,  	P9_TVERSION = 100,  	P9_RVERSION,  	P9_TAUTH = 102, @@ -350,6 +358,31 @@ struct p9_wstat {  };  /* Structures for Protocol Operations */ +struct p9_tstatfs { +	u32 fid; +}; + +struct p9_rstatfs { +	u32 type; +	u32 bsize; +	u64 blocks; +	u64 bfree; +	u64 bavail; +	u64 files; +	u64 ffree; +	u64 fsid; +	u32 namelen; +}; + +struct p9_trename { +	u32 fid; +	u32 newdirfid; +	struct p9_str name; +}; + +struct p9_rrename { +}; +  struct p9_tversion {  	u32 msize;  	struct p9_str version; diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 4f3760afc20f..7dd3ed85c782 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -195,6 +195,8 @@ struct p9_fid {  	struct list_head dlist;	/* list of all fids attached to a dentry */  }; +int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); +int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name);  int p9_client_version(struct p9_client *);  struct p9_client *p9_client_create(const char *dev_name, char *options);  void p9_client_destroy(struct p9_client *clnt); diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 1614d78c60ed..20725e213aee 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -30,7 +30,7 @@ struct unix_skb_parms {  #endif  }; -#define UNIXCB(skb) 	(*(struct unix_skb_parms*)&((skb)->cb)) +#define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))  #define UNIXCREDS(skb)	(&UNIXCB((skb)).creds)  #define UNIXSID(skb)	(&UNIXCB((skb)).secid) @@ -45,21 +45,23 @@ struct unix_skb_parms {  struct unix_sock {  	/* WARNING: sk has to be the first member */  	struct sock		sk; -        struct unix_address     *addr; -        struct dentry		*dentry; -        struct vfsmount		*mnt; +	struct unix_address     *addr; +	struct dentry		*dentry; +	struct vfsmount		*mnt;  	struct mutex		readlock; -        struct sock		*peer; -        struct sock		*other; +	struct sock		*peer; +	struct sock		*other;  	struct list_head	link; -        atomic_long_t           inflight; -        spinlock_t		lock; +	atomic_long_t		inflight; +	spinlock_t		lock;  	unsigned int		gc_candidate : 1;  	unsigned int		gc_maybe_cycle : 1; -        wait_queue_head_t       peer_wait; +	struct socket_wq	peer_wq;  };  #define unix_sk(__sk) ((struct unix_sock *)__sk) +#define peer_wait peer_wq.wait +  #ifdef CONFIG_SYSCTL  extern int unix_sysctl_register(struct net *net);  extern void unix_sysctl_unregister(struct net *net); diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index ce3c99e5fa25..e42f6ed5421c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -107,6 +107,8 @@ struct hci_dev {  	unsigned long	acl_last_tx;  	unsigned long	sco_last_tx; +	struct workqueue_struct	*workqueue; +  	struct tasklet_struct	cmd_task;  	struct tasklet_struct	rx_task;  	struct tasklet_struct	tx_task; @@ -636,8 +638,8 @@ int hci_register_notifier(struct notifier_block *nb);  int hci_unregister_notifier(struct notifier_block *nb);  int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); -int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags); -int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); +void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags); +void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);  void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 17a689f27a6a..7c695bfd853c 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -30,11 +30,12 @@  #define L2CAP_DEFAULT_MIN_MTU		48  #define L2CAP_DEFAULT_FLUSH_TO		0xffff  #define L2CAP_DEFAULT_TX_WINDOW		63 -#define L2CAP_DEFAULT_NUM_TO_ACK        (L2CAP_DEFAULT_TX_WINDOW/5)  #define L2CAP_DEFAULT_MAX_TX		3  #define L2CAP_DEFAULT_RETRANS_TO	1000    /* 1 second */  #define L2CAP_DEFAULT_MONITOR_TO	12000   /* 12 seconds */  #define L2CAP_DEFAULT_MAX_PDU_SIZE	672 +#define L2CAP_DEFAULT_ACK_TO		200 +#define L2CAP_LOCAL_BUSY_TRIES		12  #define L2CAP_CONN_TIMEOUT	(40000) /* 40 seconds */  #define L2CAP_INFO_TIMEOUT	(4000)  /*  4 seconds */ @@ -55,6 +56,8 @@ struct l2cap_options {  	__u16 flush_to;  	__u8  mode;  	__u8  fcs; +	__u8  max_tx; +	__u16 txwin_size;  };  #define L2CAP_CONNINFO	0x02 @@ -292,6 +295,7 @@ struct l2cap_conn {  #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)  #define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue)  #define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue) +#define BUSY_QUEUE(sk) (&l2cap_pi(sk)->busy_queue)  #define SREJ_LIST(sk) (&l2cap_pi(sk)->srej_l.list)  struct srej_list { @@ -320,7 +324,7 @@ struct l2cap_pinfo {  	__u8		conf_req[64];  	__u8		conf_len;  	__u8		conf_state; -	__u8		conn_state; +	__u16		conn_state;  	__u8		next_tx_seq;  	__u8		expected_ack_seq; @@ -328,27 +332,35 @@ struct l2cap_pinfo {  	__u8		buffer_seq;  	__u8		buffer_seq_srej;  	__u8		srej_save_reqseq; +	__u8		frames_sent;  	__u8		unacked_frames;  	__u8		retry_count; -	__u8		num_to_ack; +	__u8		num_acked;  	__u16		sdu_len;  	__u16		partial_sdu_len;  	struct sk_buff	*sdu;  	__u8		ident; +	__u8		tx_win; +	__u8		max_tx;  	__u8		remote_tx_win;  	__u8		remote_max_tx;  	__u16		retrans_timeout;  	__u16		monitor_timeout; -	__u16		max_pdu_size; +	__u16		remote_mps; +	__u16		mps;  	__le16		sport; +	spinlock_t		send_lock;  	struct timer_list	retrans_timer;  	struct timer_list	monitor_timer; +	struct timer_list	ack_timer;  	struct sk_buff_head	tx_queue;  	struct sk_buff_head	srej_queue; +	struct sk_buff_head	busy_queue; +	struct work_struct	busy_work;  	struct srej_list	srej_l;  	struct l2cap_conn	*conn;  	struct sock		*next_c; @@ -367,19 +379,24 @@ struct l2cap_pinfo {  #define L2CAP_CONF_MAX_CONF_REQ 2  #define L2CAP_CONF_MAX_CONF_RSP 2 -#define L2CAP_CONN_SAR_SDU         0x01 -#define L2CAP_CONN_SREJ_SENT       0x02 -#define L2CAP_CONN_WAIT_F          0x04 -#define L2CAP_CONN_SREJ_ACT        0x08 -#define L2CAP_CONN_SEND_PBIT       0x10 -#define L2CAP_CONN_REMOTE_BUSY     0x20 -#define L2CAP_CONN_LOCAL_BUSY      0x40 -#define L2CAP_CONN_REJ_ACT         0x80 +#define L2CAP_CONN_SAR_SDU         0x0001 +#define L2CAP_CONN_SREJ_SENT       0x0002 +#define L2CAP_CONN_WAIT_F          0x0004 +#define L2CAP_CONN_SREJ_ACT        0x0008 +#define L2CAP_CONN_SEND_PBIT       0x0010 +#define L2CAP_CONN_REMOTE_BUSY     0x0020 +#define L2CAP_CONN_LOCAL_BUSY      0x0040 +#define L2CAP_CONN_REJ_ACT         0x0080 +#define L2CAP_CONN_SEND_FBIT       0x0100 +#define L2CAP_CONN_RNR_SENT        0x0200 +#define L2CAP_CONN_SAR_RETRY       0x0400  #define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \  		jiffies +  msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));  #define __mod_monitor_timer() mod_timer(&l2cap_pi(sk)->monitor_timer, \  		jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO)); +#define __mod_ack_timer() mod_timer(&l2cap_pi(sk)->ack_timer, \ +		jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));  static inline int l2cap_tx_window_full(struct sock *sk)  { diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h new file mode 100644 index 000000000000..318ab9478a44 --- /dev/null +++ b/include/net/caif/caif_dev.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland/ sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CAIF_DEV_H_ +#define CAIF_DEV_H_ + +#include <net/caif/caif_layer.h> +#include <net/caif/cfcnfg.h> +#include <linux/caif/caif_socket.h> +#include <linux/if.h> + +/** + * struct caif_param - CAIF parameters. + * @size:	Length of data + * @data:	Binary Data Blob + */ +struct caif_param { +	u16  size; +	u8   data[256]; +}; + +/** + * struct caif_connect_request - Request data for CAIF channel setup. + * @protocol:		Type of CAIF protocol to use (at, datagram etc) + * @sockaddr:		Socket address to connect. + * @priority:		Priority of the connection. + * @link_selector:	Link selector (high bandwidth or low latency) + * @link_name:		Name of the CAIF Link Layer to use. + * @param:		Connect Request parameters (CAIF_SO_REQ_PARAM). + * + * This struct is used when connecting a CAIF channel. + * It contains all CAIF channel configuration options. + */ +struct caif_connect_request { +	enum caif_protocol_type protocol; +	struct sockaddr_caif sockaddr; +	enum caif_channel_priority priority; +	enum caif_link_selector link_selector; +	char link_name[16]; +	struct caif_param param; +}; + +/** + * caif_connect_client - Connect a client to CAIF Core Stack. + * @config:		Channel setup parameters, specifying what address + *			to connect on the Modem. + * @client_layer:	User implementation of client layer. This layer + *			MUST have receive and control callback functions + *			implemented. + * + * This function connects a CAIF channel. The Client must implement + * the struct cflayer. This layer represents the Client layer and holds + * receive functions and control callback functions. Control callback + * function will receive information about connect/disconnect responses, + * flow control etc (see enum caif_control). + * E.g. CAIF Socket will call this function for each socket it connects + * and have one client_layer instance for each socket. + */ +int caif_connect_client(struct caif_connect_request *config, +			   struct cflayer *client_layer); + +/** + * caif_disconnect_client - Disconnects a client from the CAIF stack. + * + * @client_layer: Client layer to be removed. + */ +int caif_disconnect_client(struct cflayer *client_layer); + +/** + * caif_release_client - Release adaptation layer reference to client. + * + * @client_layer: Client layer. + * + * Releases a client/adaptation layer use of the caif stack. + * This function must be used after caif_disconnect_client to + * decrease the reference count of the service layer. + */ +void caif_release_client(struct cflayer *client_layer); + +/** + * connect_req_to_link_param - Translate configuration parameters + *				from socket format to internal format. + * @cnfg:	Pointer to configuration handler + * @con_req:	Configuration parameters supplied in function + *		caif_connect_client + * @channel_setup_param: Parameters supplied to the CAIF Core stack for + *			 setting up channels. + * + */ +int connect_req_to_link_param(struct cfcnfg *cnfg, +				struct caif_connect_request *con_req, +				struct cfctrl_link_param *channel_setup_param); + +/** + * get_caif_conf() - Get the configuration handler. + */ +struct cfcnfg *get_caif_conf(void); + + +#endif /* CAIF_DEV_H_ */ diff --git a/include/net/caif/caif_device.h b/include/net/caif/caif_device.h new file mode 100644 index 000000000000..d02f044adb8a --- /dev/null +++ b/include/net/caif/caif_device.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland/ sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CAIF_DEVICE_H_ +#define CAIF_DEVICE_H_ +#include <linux/kernel.h> +#include <linux/net.h> +#include <linux/netdevice.h> +#include <linux/caif/caif_socket.h> +#include <net/caif/caif_device.h> + +/** + * struct caif_dev_common - data shared between CAIF drivers and stack. + * @flowctrl:		Flow Control callback function. This function is + *                      supplied by CAIF Core Stack and is used by CAIF + *                      Link Layer to send flow-stop to CAIF Core. + *                      The flow information will be distributed to all + *                      clients of CAIF. + * + * @link_select:	Profile of device, either high-bandwidth or + *			low-latency. This member is set by CAIF Link + *			Layer Device in	order to indicate if this device + *			is a high bandwidth or low latency device. + * + * @use_frag:		CAIF Frames may be fragmented. + *			Is set by CAIF Link Layer in order to indicate if the + *			interface receives fragmented frames that must be + *			assembled by CAIF Core Layer. + * + * @use_fcs:		Indicate if Frame CheckSum (fcs) is used. + *			Is set if the physical interface is + *			using Frame Checksum on the CAIF Frames. + * + * @use_stx:		Indicate STart of frame eXtension (stx) in use. + *			Is set if the CAIF Link Layer expects + *			CAIF Frames to start with the STX byte. + * + * This structure is shared between the CAIF drivers and the CAIF stack. + * It is used by the device to register its behavior. + * CAIF Core layer must set the member flowctrl in order to supply + * CAIF Link Layer with the flow control function. + * + */ + struct caif_dev_common { +	void (*flowctrl)(struct net_device *net, int on); +	enum caif_link_selector link_select; +	int use_frag; +	int use_fcs; +	int use_stx; +}; + +#endif	/* CAIF_DEVICE_H_ */ diff --git a/include/net/caif/caif_layer.h b/include/net/caif/caif_layer.h new file mode 100644 index 000000000000..25c472f0e5b8 --- /dev/null +++ b/include/net/caif/caif_layer.h @@ -0,0 +1,283 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland / sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CAIF_LAYER_H_ +#define CAIF_LAYER_H_ + +#include <linux/list.h> + +struct cflayer; +struct cfpkt; +struct cfpktq; +struct caif_payload_info; +struct caif_packet_funcs; + +#define CAIF_MAX_FRAMESIZE 4096 +#define CAIF_MAX_PAYLOAD_SIZE (4096 - 64) +#define CAIF_NEEDED_HEADROOM (10) +#define CAIF_NEEDED_TAILROOM (2) + +#define CAIF_LAYER_NAME_SZ 16 +#define CAIF_SUCCESS	1 +#define CAIF_FAILURE	0 + +/** + * caif_assert() - Assert function for CAIF. + * @assert: expression to evaluate. + * + * This function will print a error message and a do WARN_ON if the + * assertion failes. Normally this will do a stack up at the current location. + */ +#define caif_assert(assert)					\ +do {								\ +	if (!(assert)) {					\ +		pr_err("caif:Assert detected:'%s'\n", #assert); \ +		WARN_ON(!(assert));				\ +	}							\ +} while (0) + + +/** + * enum caif_ctrlcmd - CAIF Stack Control Signaling sent in layer.ctrlcmd(). + * + * @CAIF_CTRLCMD_FLOW_OFF_IND:		Flow Control is OFF, transmit function + *					should stop sending data + * + * @CAIF_CTRLCMD_FLOW_ON_IND:		Flow Control is ON, transmit function + *					can start sending data + * + * @CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:	Remote end modem has decided to close + *					down channel + * + * @CAIF_CTRLCMD_INIT_RSP:		Called initially when the layer below + *					has finished initialization + * + * @CAIF_CTRLCMD_DEINIT_RSP:		Called when de-initialization is + *					complete + * + * @CAIF_CTRLCMD_INIT_FAIL_RSP:		Called if initialization fails + * + * @_CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND:	CAIF Link layer temporarily cannot + *					send more packets. + * @_CAIF_CTRLCMD_PHYIF_FLOW_ON_IND:	Called if CAIF Link layer is able + *					to send packets again. + * @_CAIF_CTRLCMD_PHYIF_DOWN_IND:	Called if CAIF Link layer is going + *					down. + * + * These commands are sent upwards in the CAIF stack to the CAIF Client. + * They are used for signaling originating from the modem or CAIF Link Layer. + * These are either responses (*_RSP) or events (*_IND). + */ +enum caif_ctrlcmd { +	CAIF_CTRLCMD_FLOW_OFF_IND, +	CAIF_CTRLCMD_FLOW_ON_IND, +	CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, +	CAIF_CTRLCMD_INIT_RSP, +	CAIF_CTRLCMD_DEINIT_RSP, +	CAIF_CTRLCMD_INIT_FAIL_RSP, +	_CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND, +	_CAIF_CTRLCMD_PHYIF_FLOW_ON_IND, +	_CAIF_CTRLCMD_PHYIF_DOWN_IND, +}; + +/** + * enum caif_modemcmd -	 Modem Control Signaling, sent from CAIF Client + *			 to the CAIF Link Layer or modem. + * + * @CAIF_MODEMCMD_FLOW_ON_REQ:		Flow Control is ON, transmit function + *					can start sending data. + * + * @CAIF_MODEMCMD_FLOW_OFF_REQ:		Flow Control is OFF, transmit function + *					should stop sending data. + * + * @_CAIF_MODEMCMD_PHYIF_USEFULL:	Notify physical layer that it is in use + * + * @_CAIF_MODEMCMD_PHYIF_USELESS:	Notify physical layer that it is + *					no longer in use. + * + * These are requests sent 'downwards' in the stack. + * Flow ON, OFF can be indicated to the modem. + */ +enum caif_modemcmd { +	CAIF_MODEMCMD_FLOW_ON_REQ = 0, +	CAIF_MODEMCMD_FLOW_OFF_REQ = 1, +	_CAIF_MODEMCMD_PHYIF_USEFULL = 3, +	_CAIF_MODEMCMD_PHYIF_USELESS = 4 +}; + +/** + * enum caif_direction - CAIF Packet Direction. + * Indicate if a packet is to be sent out or to be received in. + * @CAIF_DIR_IN:		Incoming packet received. + * @CAIF_DIR_OUT:		Outgoing packet to be transmitted. + */ +enum caif_direction { +	CAIF_DIR_IN = 0, +	CAIF_DIR_OUT = 1 +}; + +/** + * struct cflayer - CAIF Stack layer. + * Defines the framework for the CAIF Core Stack. + * @up:		Pointer up to the layer above. + * @dn:		Pointer down to the layer below. + * @node:	List node used when layer participate in a list. + * @receive:	Packet receive function. + * @transmit:	Packet transmit funciton. + * @ctrlcmd:	Used for control signalling upwards in the stack. + * @modemcmd:	Used for control signaling downwards in the stack. + * @prio:	Priority of this layer. + * @id:		The identity of this layer + * @type:	The type of this layer + * @name:	Name of the layer. + * + *  This structure defines the layered structure in CAIF. + * + *  It defines CAIF layering structure, used by all CAIF Layers and the + *  layers interfacing CAIF. + * + *  In order to integrate with CAIF an adaptation layer on top of the CAIF stack + *  and PHY layer below the CAIF stack + *  must be implemented. These layer must follow the design principles below. + * + *  Principles for layering of protocol layers: + *    - All layers must use this structure. If embedding it, then place this + *	structure first in the layer specific structure. + * + *    - Each layer should not depend on any others layer private data. + * + *    - In order to send data upwards do + *	layer->up->receive(layer->up, packet); + * + *    - In order to send data downwards do + *	layer->dn->transmit(layer->dn, info, packet); + */ +struct cflayer { +	struct cflayer *up; +	struct cflayer *dn; +	struct list_head node; + +	/* +	 *  receive() - Receive Function. +	 *  Contract: Each layer must implement a receive function passing the +	 *  CAIF packets upwards in the stack. +	 *	Packet handling rules: +	 *	      - The CAIF packet (cfpkt) cannot be accessed after +	 *		     passing it to the next layer using up->receive(). +	 *	      - If parsing of the packet fails, the packet must be +	 *		     destroyed and -1 returned from the function. +	 *	      - If parsing succeeds (and above layers return OK) then +	 *		      the function must return a value > 0. +	 * +	 *  Returns result < 0 indicates an error, 0 or positive value +	 *	     indicates success. +	 * +	 *  @layr: Pointer to the current layer the receive function is +	 *		implemented for (this pointer). +	 *  @cfpkt: Pointer to CaifPacket to be handled. +	 */ +	int (*receive)(struct cflayer *layr, struct cfpkt *cfpkt); + +	/* +	 *  transmit() - Transmit Function. +	 *  Contract: Each layer must implement a transmit function passing the +	 *	CAIF packet downwards in the stack. +	 *	Packet handling rules: +	 *	      - The CAIF packet (cfpkt) ownership is passed to the +	 *		transmit function. This means that the the packet +	 *		cannot be accessed after passing it to the below +	 *		layer using dn->transmit(). +	 * +	 *	      - If transmit fails, however, the ownership is returned +	 *		to thecaller. The caller of "dn->transmit()" must +	 *		destroy or resend packet. +	 * +	 *	      - Return value less than zero means error, zero or +	 *		greater than zero means OK. +	 * +	 *	 result < 0 indicates an error, 0 or positive value +	 *	 indicate success. +	 * +	 *  @layr:	Pointer to the current layer the receive function +	 *		isimplemented for (this pointer). +	 *  @cfpkt:	 Pointer to CaifPacket to be handled. +	 */ +	int (*transmit) (struct cflayer *layr, struct cfpkt *cfpkt); + +	/* +	 *  cttrlcmd() - Control Function upwards in CAIF Stack. +	 *  Used for signaling responses (CAIF_CTRLCMD_*_RSP) +	 *  and asynchronous events from the modem  (CAIF_CTRLCMD_*_IND) +	 * +	 *  @layr:	Pointer to the current layer the receive function +	 *		is implemented for (this pointer). +	 *  @ctrl:	Control Command. +	 */ +	void (*ctrlcmd) (struct cflayer *layr, enum caif_ctrlcmd ctrl, +			 int phyid); + +	/* +	 *  modemctrl() - Control Function used for controlling the modem. +	 *  Used to signal down-wards in the CAIF stack. +	 *  Returns 0 on success, < 0 upon failure. +	 * +	 *  @layr:	Pointer to the current layer the receive function +	 *		is implemented for (this pointer). +	 *  @ctrl:  Control Command. +	 */ +	int (*modemcmd) (struct cflayer *layr, enum caif_modemcmd ctrl); + +	unsigned short prio; +	unsigned int id; +	unsigned int type; +	char name[CAIF_LAYER_NAME_SZ]; +}; + +/** + * layer_set_up() - Set the up pointer for a specified layer. + *  @layr: Layer where up pointer shall be set. + *  @above: Layer above. + */ +#define layer_set_up(layr, above) ((layr)->up = (struct cflayer *)(above)) + +/** + *  layer_set_dn() - Set the down pointer for a specified layer. + *  @layr:  Layer where down pointer shall be set. + *  @below: Layer below. + */ +#define layer_set_dn(layr, below) ((layr)->dn = (struct cflayer *)(below)) + +/** + * struct dev_info - Physical Device info information about physical layer. + * @dev:	Pointer to native physical device. + * @id:		Physical ID of the physical connection used by the + *		logical CAIF connection. Used by service layers to + *		identify their physical id to Caif MUX (CFMUXL)so + *		that the MUX can add the correct physical ID to the + *		packet. + */ +struct dev_info { +	void *dev; +	unsigned int id; +}; + +/** + * struct caif_payload_info - Payload information embedded in packet (sk_buff). + * + * @dev_info:	Information about the receiving device. + * + * @hdr_len:	Header length, used to align pay load on 32bit boundary. + * + * @channel_id: Channel ID of the logical CAIF connection. + *		Used by mux to insert channel id into the caif packet. + */ +struct caif_payload_info { +	struct dev_info *dev_info; +	unsigned short hdr_len; +	unsigned short channel_id; +}; + +#endif	/* CAIF_LAYER_H_ */ diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h new file mode 100644 index 000000000000..9fc2fc20b884 --- /dev/null +++ b/include/net/caif/cfcnfg.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CFCNFG_H_ +#define CFCNFG_H_ +#include <linux/spinlock.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfctrl.h> + +struct cfcnfg; + +/** + * enum cfcnfg_phy_type -  Types of physical layers defined in CAIF Stack + * + * @CFPHYTYPE_FRAG:	Fragmented frames physical interface. + * @CFPHYTYPE_CAIF:	Generic CAIF physical interface + */ +enum cfcnfg_phy_type { +	CFPHYTYPE_FRAG = 1, +	CFPHYTYPE_CAIF, +	CFPHYTYPE_MAX +}; + +/** + * enum cfcnfg_phy_preference - Physical preference HW Abstraction + * + * @CFPHYPREF_UNSPECIFIED:	Default physical interface + * + * @CFPHYPREF_LOW_LAT:		Default physical interface for low-latency + *				traffic + * @CFPHYPREF_HIGH_BW:		Default physical interface for high-bandwidth + *				traffic + * @CFPHYPREF_LOOP:		TEST only Loopback interface simulating modem + *				responses. + * + */ +enum cfcnfg_phy_preference { +	CFPHYPREF_UNSPECIFIED, +	CFPHYPREF_LOW_LAT, +	CFPHYPREF_HIGH_BW, +	CFPHYPREF_LOOP +}; + +/** + * cfcnfg_create() - Create the CAIF configuration object. + */ +struct cfcnfg *cfcnfg_create(void); + +/** + * cfcnfg_remove() -  Remove the CFCNFG object + * @cfg: config object + */ +void cfcnfg_remove(struct cfcnfg *cfg); + +/** + * cfcnfg_add_phy_layer() - Adds a physical layer to the CAIF stack. + * @cnfg:	Pointer to a CAIF configuration object, created by + *		cfcnfg_create(). + * @phy_type:	Specifies the type of physical interface, e.g. + *			CFPHYTYPE_FRAG. + * @dev:	Pointer to link layer device + * @phy_layer:	Specify the physical layer. The transmit function + *		MUST be set in the structure. + * @phyid:	The assigned physical ID for this layer, used in + *		cfcnfg_add_adapt_layer to specify PHY for the link. + * @pref:	The phy (link layer) preference. + * @fcs:	Specify if checksum is used in CAIF Framing Layer. + * @stx:	Specify if Start Of Frame eXtention is used. + */ + +void +cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, +		     void *dev, struct cflayer *phy_layer, u16 *phyid, +		     enum cfcnfg_phy_preference pref, +		     bool fcs, bool stx); + +/** + * cfcnfg_del_phy_layer - Deletes an phy layer from the CAIF stack. + * + * @cnfg:	Pointer to a CAIF configuration object, created by + *		cfcnfg_create(). + * @phy_layer:	Adaptation layer to be removed. + */ +int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer); + +/** + * cfcnfg_disconn_adapt_layer - Disconnects an adaptation layer. + * + * @cnfg:	Pointer to a CAIF configuration object, created by + *		cfcnfg_create(). + * @adap_layer: Adaptation layer to be removed. + */ +int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, +			struct cflayer *adap_layer); + +/** + * cfcnfg_release_adap_layer - Used by client to release the adaptation layer. + * + * @adap_layer: Adaptation layer. + */ +void cfcnfg_release_adap_layer(struct cflayer *adap_layer); + +/** + * cfcnfg_add_adaptation_layer - Add an adaptation layer to the CAIF stack. + * + * The adaptation Layer is where the interface to application or higher-level + * driver functionality is implemented. + * + * @cnfg:		Pointer to a CAIF configuration object, created by + *			cfcnfg_create(). + * @param:		Link setup parameters. + * @adap_layer:		Specify the adaptation layer; the receive and + *			flow-control functions MUST be set in the structure. + * + */ +int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, +			    struct cfctrl_link_param *param, +			    struct cflayer *adap_layer); + +/** + * cfcnfg_get_phyid() - Get physical ID, given type. + * Returns one of the physical interfaces matching the given type. + * Zero if no match is found. + * @cnfg:	Configuration object + * @phy_pref:	Caif Link Layer preference + */ +struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, +		     enum cfcnfg_phy_preference phy_pref); + +/** + * cfcnfg_get_named() - Get the Physical Identifier of CAIF Link Layer + * @cnfg:	Configuration object + * @name:	Name of the Physical Layer (Caif Link Layer) + */ +int cfcnfg_get_named(struct cfcnfg *cnfg, char *name); + +#endif				/* CFCNFG_H_ */ diff --git a/include/net/caif/cfctrl.h b/include/net/caif/cfctrl.h new file mode 100644 index 000000000000..9402543fc20d --- /dev/null +++ b/include/net/caif/cfctrl.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CFCTRL_H_ +#define CFCTRL_H_ +#include <net/caif/caif_layer.h> +#include <net/caif/cfsrvl.h> + +/* CAIF Control packet commands */ +enum cfctrl_cmd { +	CFCTRL_CMD_LINK_SETUP = 0, +	CFCTRL_CMD_LINK_DESTROY = 1, +	CFCTRL_CMD_LINK_ERR = 2, +	CFCTRL_CMD_ENUM = 3, +	CFCTRL_CMD_SLEEP = 4, +	CFCTRL_CMD_WAKE = 5, +	CFCTRL_CMD_LINK_RECONF = 6, +	CFCTRL_CMD_START_REASON = 7, +	CFCTRL_CMD_RADIO_SET = 8, +	CFCTRL_CMD_MODEM_SET = 9, +	CFCTRL_CMD_MASK = 0xf +}; + +/* Channel types */ +enum cfctrl_srv { +	CFCTRL_SRV_DECM = 0, +	CFCTRL_SRV_VEI = 1, +	CFCTRL_SRV_VIDEO = 2, +	CFCTRL_SRV_DBG = 3, +	CFCTRL_SRV_DATAGRAM = 4, +	CFCTRL_SRV_RFM = 5, +	CFCTRL_SRV_UTIL = 6, +	CFCTRL_SRV_MASK = 0xf +}; + +#define CFCTRL_RSP_BIT 0x20 +#define CFCTRL_ERR_BIT 0x10 + +struct cfctrl_rsp { +	void (*linksetup_rsp)(struct cflayer *layer, u8 linkid, +			      enum cfctrl_srv serv, u8 phyid, +			      struct cflayer *adapt_layer); +	void (*linkdestroy_rsp)(struct cflayer *layer, u8 linkid); +	void (*linkerror_ind)(void); +	void (*enum_rsp)(void); +	void (*sleep_rsp)(void); +	void (*wake_rsp)(void); +	void (*restart_rsp)(void); +	void (*radioset_rsp)(void); +	void (*reject_rsp)(struct cflayer *layer, u8 linkid, +				struct cflayer *client_layer);; +}; + +/* Link Setup Parameters for CAIF-Links. */ +struct cfctrl_link_param { +	enum cfctrl_srv linktype;/* (T3,T0) Type of Channel */ +	u8 priority;		  /* (P4,P0) Priority of the channel */ +	u8 phyid;		  /* (U2-U0) Physical interface to connect */ +	u8 endpoint;		  /* (E1,E0) Endpoint for data channels */ +	u8 chtype;		  /* (H1,H0) Channel-Type, applies to +				   *            VEI, DEBUG */ +	union { +		struct { +			u8 connid;	/*  (D7,D0) Video LinkId */ +		} video; + +		struct { +			u32 connid;	/* (N31,Ngit0) Connection ID used +					 *  for Datagram */ +		} datagram; + +		struct { +			u32 connid;	/* Connection ID used for RFM */ +			char volume[20];	/* Volume to mount for RFM */ +		} rfm;		/* Configuration for RFM */ + +		struct { +			u16 fifosize_kb;	/* Psock FIFO size in KB */ +			u16 fifosize_bufs;	/* Psock # signal buffers */ +			char name[16];	/* Name of the PSOCK service */ +			u8 params[255];	/* Link setup Parameters> */ +			u16 paramlen;	/* Length of Link Setup +						 *   Parameters */ +		} utility;	/* Configuration for Utility Links (Psock) */ +	} u; +}; + +/* This structure is used internally in CFCTRL */ +struct cfctrl_request_info { +	int sequence_no; +	enum cfctrl_cmd cmd; +	u8 channel_id; +	struct cfctrl_link_param param; +	struct cflayer *client_layer; +	struct list_head list; +}; + +struct cfctrl { +	struct cfsrvl serv; +	struct cfctrl_rsp res; +	atomic_t req_seq_no; +	atomic_t rsp_seq_no; +	struct list_head list; +	/* Protects from simultaneous access to first_req list */ +	spinlock_t info_list_lock; +#ifndef CAIF_NO_LOOP +	u8 loop_linkid; +	int loop_linkused[256]; +	/* Protects simultaneous access to loop_linkid and loop_linkused */ +	spinlock_t loop_linkid_lock; +#endif + +}; + +void cfctrl_enum_req(struct cflayer *cfctrl, u8 physlinkid); +int cfctrl_linkup_request(struct cflayer *cfctrl, +			   struct cfctrl_link_param *param, +			   struct cflayer *user_layer); +int  cfctrl_linkdown_req(struct cflayer *cfctrl, u8 linkid, +			 struct cflayer *client); +void cfctrl_sleep_req(struct cflayer *cfctrl); +void cfctrl_wake_req(struct cflayer *cfctrl); +void cfctrl_getstartreason_req(struct cflayer *cfctrl); +struct cflayer *cfctrl_create(void); +void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn); +void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up); +struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer); +bool cfctrl_req_eq(struct cfctrl_request_info *r1, +		   struct cfctrl_request_info *r2); +void cfctrl_insert_req(struct cfctrl *ctrl, +			      struct cfctrl_request_info *req); +struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, +					      struct cfctrl_request_info *req); +void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer); + +#endif				/* CFCTRL_H_ */ diff --git a/include/net/caif/cffrml.h b/include/net/caif/cffrml.h new file mode 100644 index 000000000000..3f14d2e1ce61 --- /dev/null +++ b/include/net/caif/cffrml.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CFFRML_H_ +#define CFFRML_H_ +#include <net/caif/caif_layer.h> + +struct cffrml; +struct cflayer *cffrml_create(u16 phyid, bool DoFCS); +void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up); +void cffrml_set_dnlayer(struct cflayer *this, struct cflayer *dn); + +#endif /* CFFRML_H_ */ diff --git a/include/net/caif/cfmuxl.h b/include/net/caif/cfmuxl.h new file mode 100644 index 000000000000..4e1b4f33423e --- /dev/null +++ b/include/net/caif/cfmuxl.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CFMUXL_H_ +#define CFMUXL_H_ +#include <net/caif/caif_layer.h> + +struct cfsrvl; +struct cffrml; + +struct cflayer *cfmuxl_create(void); +int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid); +struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid); +int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *up, u8 phyid); +struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 linkid); +bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid); +u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id); + +#endif				/* CFMUXL_H_ */ diff --git a/include/net/caif/cfpkt.h b/include/net/caif/cfpkt.h new file mode 100644 index 000000000000..fbc681beff52 --- /dev/null +++ b/include/net/caif/cfpkt.h @@ -0,0 +1,274 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CFPKT_H_ +#define CFPKT_H_ +#include <net/caif/caif_layer.h> +#include <linux/types.h> +struct cfpkt; + +/* Create a CAIF packet. + * len: Length of packet to be created + * @return New packet. + */ +struct cfpkt *cfpkt_create(u16 len); + +/* Create a CAIF packet. + * data Data to copy. + * len Length of packet to be created + * @return New packet. + */ +struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len); +/* + * Destroy a CAIF Packet. + * pkt Packet to be destoyed. + */ +void cfpkt_destroy(struct cfpkt *pkt); + +/* + * Extract header from packet. + * + * pkt Packet to extract header data from. + * data Pointer to copy the header data into. + * len Length of head data to copy. + * @return zero on success and error code upon failure + */ +int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len); + +/* + * Peek header from packet. + * Reads data from packet without changing packet. + * + * pkt Packet to extract header data from. + * data Pointer to copy the header data into. + * len Length of head data to copy. + * @return zero on success and error code upon failure + */ +int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len); + +/* + * Extract header from trailer (end of packet). + * + * pkt Packet to extract header data from. + * data Pointer to copy the trailer data into. + * len Length of header data to copy. + * @return zero on success and error code upon failure + */ +int cfpkt_extr_trail(struct cfpkt *pkt, void *data, u16 len); + +/* + * Add header to packet. + * + * + * pkt Packet to add header data to. + * data Pointer to data to copy into the header. + * len Length of header data to copy. + * @return zero on success and error code upon failure + */ +int cfpkt_add_head(struct cfpkt *pkt, const void *data, u16 len); + +/* + * Add trailer to packet. + * + * + * pkt Packet to add trailer data to. + * data Pointer to data to copy into the trailer. + * len Length of trailer data to copy. + * @return zero on success and error code upon failure + */ +int cfpkt_add_trail(struct cfpkt *pkt, const void *data, u16 len); + +/* + * Pad trailer on packet. + * Moves data pointer in packet, no content copied. + * + * pkt Packet in which to pad trailer. + * len Length of padding to add. + * @return zero on success and error code upon failure + */ +int cfpkt_pad_trail(struct cfpkt *pkt, u16 len); + +/* + * Add a single byte to packet body (tail). + * + * pkt Packet in which to add byte. + * data Byte to add. + * @return zero on success and error code upon failure + */ +int cfpkt_addbdy(struct cfpkt *pkt, const u8 data); + +/* + * Add a data to packet body (tail). + * + * pkt Packet in which to add data. + * data Pointer to data to copy into the packet body. + * len Length of data to add. + * @return zero on success and error code upon failure + */ +int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len); + +/* + * Checks whether there are more data to process in packet. + * pkt Packet to check. + * @return true if more data are available in packet false otherwise + */ +bool cfpkt_more(struct cfpkt *pkt); + +/* + * Checks whether the packet is erroneous, + * i.e. if it has been attempted to extract more data than available in packet + * or writing more data than has been allocated in cfpkt_create(). + * pkt Packet to check. + * @return true on error false otherwise + */ +bool cfpkt_erroneous(struct cfpkt *pkt); + +/* + * Get the packet length. + * pkt Packet to get length from. + * @return Number of bytes in packet. + */ +u16 cfpkt_getlen(struct cfpkt *pkt); + +/* + * Set the packet length, by adjusting the trailer pointer according to length. + * pkt Packet to set length. + * len Packet length. + * @return Number of bytes in packet. + */ +int cfpkt_setlen(struct cfpkt *pkt, u16 len); + +/* + * cfpkt_append - Appends a packet's data to another packet. + * dstpkt:    Packet to append data into, WILL BE FREED BY THIS FUNCTION + * addpkt:    Packet to be appended and automatically released, + *            WILL BE FREED BY THIS FUNCTION. + * expectlen: Packet's expected total length. This should be considered + *            as a hint. + * NB: Input packets will be destroyed after appending and cannot be used + * after calling this function. + * @return    The new appended packet. + */ +struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, struct cfpkt *addpkt, +		      u16 expectlen); + +/* + * cfpkt_split - Split a packet into two packets at the specified split point. + * pkt: Packet to be split (will contain the first part of the data on exit) + * pos: Position to split packet in two parts. + * @return The new packet, containing the second part of the data. + */ +struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos); + +/* + * Iteration function, iterates the packet buffers from start to end. + * + * Checksum iteration function used to iterate buffers + * (we may have packets consisting of a chain of buffers) + * pkt:       Packet to calculate checksum for + * iter_func: Function pointer to iteration function + * chks:      Checksum calculated so far. + * buf:       Pointer to the buffer to checksum + * len:       Length of buf. + * data:      Initial checksum value. + * @return    Checksum of buffer. + */ + +u16 cfpkt_iterate(struct cfpkt *pkt, +		u16 (*iter_func)(u16 chks, void *buf, u16 len), +		u16 data); + +/* Append by giving user access to packet buffer + * cfpkt Packet to append to + * buf Buffer inside pkt that user shall copy data into + * buflen Length of buffer and number of bytes added to packet + * @return 0 on error, 1 on success + */ +int cfpkt_raw_append(struct cfpkt *cfpkt, void **buf, unsigned int buflen); + +/* Extract by giving user access to packet buffer + * cfpkt Packet to extract from + * buf Buffer inside pkt that user shall copy data from + * buflen Length of buffer and number of bytes removed from packet + * @return 0 on error, 1 on success + */ +int cfpkt_raw_extract(struct cfpkt *cfpkt, void **buf, unsigned int buflen); + +/* Map from a "native" packet (e.g. Linux Socket Buffer) to a CAIF packet. + *  dir - Direction indicating whether this packet is to be sent or received. + *  nativepkt  - The native packet to be transformed to a CAIF packet + *  @return The mapped CAIF Packet CFPKT. + */ +struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt); + +/* Map from a CAIF packet to a "native" packet (e.g. Linux Socket Buffer). + *  pkt  - The CAIF packet to be transformed into a "native" packet. + *  @return The native packet transformed from a CAIF packet. + */ +void *cfpkt_tonative(struct cfpkt *pkt); + +/* + * Insert a packet in the packet queue. + * pktq Packet queue to insert into + * pkt Packet to be inserted in queue + * prio Priority of packet + */ +void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt, +		 unsigned short prio); + +/* + * Remove a packet from the packet queue. + * pktq Packet queue to fetch packets from. + * @return Dequeued packet. + */ +struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq); + +/* + * Peek into a packet from the packet queue. + * pktq Packet queue to fetch packets from. + * @return Peeked packet. + */ +struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq); + +/* + * Initiates the packet queue. + * @return Pointer to new packet queue. + */ +struct cfpktq *cfpktq_create(void); + +/* + * Get the number of packets in the queue. + * pktq Packet queue to fetch count from. + * @return Number of packets in queue. + */ +int cfpkt_qcount(struct cfpktq *pktq); + +/* + * Put content of packet into buffer for debuging purposes. + * pkt Packet to copy data from + * buf Buffer to copy data into + * buflen Length of data to copy + * @return Pointer to copied data + */ +char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen); + +/* + * Clones a packet and releases the original packet. + * This is used for taking ownership of a packet e.g queueing. + * pkt Packet to clone and release. + * @return Cloned packet. + */ +struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt); + + +/* + * Returns packet information for a packet. + * pkt Packet to get info from; + * @return Packet information + */ +struct caif_payload_info *cfpkt_info(struct cfpkt *pkt); +/*! @} */ +#endif				/* CFPKT_H_ */ diff --git a/include/net/caif/cfserl.h b/include/net/caif/cfserl.h new file mode 100644 index 000000000000..b8374321b362 --- /dev/null +++ b/include/net/caif/cfserl.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CFSERL_H_ +#define CFSERL_H_ +#include <net/caif/caif_layer.h> + +struct cflayer *cfserl_create(int type, int instance, bool use_stx); +#endif				/* CFSERL_H_ */ diff --git a/include/net/caif/cfsrvl.h b/include/net/caif/cfsrvl.h new file mode 100644 index 000000000000..2dc9eb193ecf --- /dev/null +++ b/include/net/caif/cfsrvl.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CFSRVL_H_ +#define CFSRVL_H_ +#include <linux/list.h> +#include <linux/stddef.h> +#include <linux/types.h> +#include <linux/kref.h> + +struct cfsrvl { +	struct cflayer layer; +	bool open; +	bool phy_flow_on; +	bool modem_flow_on; +	struct dev_info dev_info; +	struct kref ref; +}; + +void cfsrvl_release(struct kref *kref); +struct cflayer *cfvei_create(u8 linkid, struct dev_info *dev_info); +struct cflayer *cfdgml_create(u8 linkid, struct dev_info *dev_info); +struct cflayer *cfutill_create(u8 linkid, struct dev_info *dev_info); +struct cflayer *cfvidl_create(u8 linkid, struct dev_info *dev_info); +struct cflayer *cfrfml_create(u8 linkid, struct dev_info *dev_info); +struct cflayer *cfdbgl_create(u8 linkid, struct dev_info *dev_info); +bool cfsrvl_phyid_match(struct cflayer *layer, int phyid); +void cfservl_destroy(struct cflayer *layer); +void cfsrvl_init(struct cfsrvl *service, +		 u8 channel_id, +		 struct dev_info *dev_info); +bool cfsrvl_ready(struct cfsrvl *service, int *err); +u8 cfsrvl_getphyid(struct cflayer *layer); + +static inline void cfsrvl_get(struct cflayer *layr) +{ +	struct cfsrvl *s; +	if (layr == NULL) +		return; +	s = container_of(layr, struct cfsrvl, layer); +	kref_get(&s->ref); +} + +static inline void cfsrvl_put(struct cflayer *layr) +{ +	struct cfsrvl *s; +	if (layr == NULL) +		return; +	s = container_of(layr, struct cfsrvl, layer); +	kref_put(&s->ref, cfsrvl_release); +} + +#endif				/* CFSRVL_H_ */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 3d134a1fb96b..b44a2e5321a3 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -511,6 +511,7 @@ struct mpath_info {   * @basic_rates: basic rates in IEEE 802.11 format   *	(or NULL for no change)   * @basic_rates_len: number of basic rates + * @ap_isolate: do not forward packets between connected stations   */  struct bss_parameters {  	int use_cts_prot; @@ -518,6 +519,7 @@ struct bss_parameters {  	int use_short_slot_time;  	u8 *basic_rates;  	u8 basic_rates_len; +	int ap_isolate;  };  struct mesh_config { @@ -704,6 +706,10 @@ struct cfg80211_crypto_settings {   * @key_len: length of WEP key for shared key authentication   * @key_idx: index of WEP key for shared key authentication   * @key: WEP key for shared key authentication + * @local_state_change: This is a request for a local state only, i.e., no + *	Authentication frame is to be transmitted and authentication state is + *	to be changed without having to wait for a response from the peer STA + *	(AP).   */  struct cfg80211_auth_request {  	struct cfg80211_bss *bss; @@ -712,6 +718,7 @@ struct cfg80211_auth_request {  	enum nl80211_auth_type auth_type;  	const u8 *key;  	u8 key_len, key_idx; +	bool local_state_change;  };  /** @@ -744,12 +751,15 @@ struct cfg80211_assoc_request {   * @ie: Extra IEs to add to Deauthentication frame or %NULL   * @ie_len: Length of ie buffer in octets   * @reason_code: The reason code for the deauthentication + * @local_state_change: This is a request for a local state only, i.e., no + *	Deauthentication frame is to be transmitted.   */  struct cfg80211_deauth_request {  	struct cfg80211_bss *bss;  	const u8 *ie;  	size_t ie_len;  	u16 reason_code; +	bool local_state_change;  };  /** @@ -762,12 +772,15 @@ struct cfg80211_deauth_request {   * @ie: Extra IEs to add to Disassociation frame or %NULL   * @ie_len: Length of ie buffer in octets   * @reason_code: The reason code for the disassociation + * @local_state_change: This is a request for a local state only, i.e., no + *	Disassociation frame is to be transmitted.   */  struct cfg80211_disassoc_request {  	struct cfg80211_bss *bss;  	const u8 *ie;  	size_t ie_len;  	u16 reason_code; +	bool local_state_change;  };  /** @@ -953,7 +966,11 @@ struct cfg80211_pmksa {   *   * @set_txq_params: Set TX queue parameters   * - * @set_channel: Set channel + * @set_channel: Set channel for a given wireless interface. Some devices + *	may support multi-channel operation (by channel hopping) so cfg80211 + *	doesn't verify much. Note, however, that the passed netdev may be + *	%NULL as well if the user requested changing the channel for the + *	device itself, or for a monitor interface.   *   * @scan: Request to do a scan. If returning zero, the scan request is given   *	the driver, and will be valid until passed to cfg80211_scan_done(). @@ -1007,6 +1024,9 @@ struct cfg80211_pmksa {   *	RSN IE. It allows for faster roaming between WPA2 BSSIDs.   * @del_pmksa: Delete a cached PMKID.   * @flush_pmksa: Flush all cached PMKIDs. + * @set_power_mgmt: Configure WLAN power management. A timeout value of -1 + *	allows the driver to adjust the dynamic ps timeout value. + * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.   *   */  struct cfg80211_ops { @@ -1079,7 +1099,7 @@ struct cfg80211_ops {  	int	(*set_txq_params)(struct wiphy *wiphy,  				  struct ieee80211_txq_params *params); -	int	(*set_channel)(struct wiphy *wiphy, +	int	(*set_channel)(struct wiphy *wiphy, struct net_device *dev,  			       struct ieee80211_channel *chan,  			       enum nl80211_channel_type channel_type); @@ -1152,6 +1172,10 @@ struct cfg80211_ops {  	int	(*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,  				  bool enabled, int timeout); + +	int	(*set_cqm_rssi_config)(struct wiphy *wiphy, +				       struct net_device *dev, +				       s32 rssi_thold, u32 rssi_hyst);  };  /* @@ -1441,6 +1465,8 @@ struct cfg80211_cached_keys;   * @list: (private) Used to collect the interfaces   * @netdev: (private) Used to reference back to the netdev   * @current_bss: (private) Used by the internal configuration code + * @channel: (private) Used by the internal configuration code to track + *	user-set AP, monitor and WDS channels for wireless extensions   * @bssid: (private) Used by the internal configuration code   * @ssid: (private) Used by the internal configuration code   * @ssid_len: (private) Used by the internal configuration code @@ -1487,6 +1513,7 @@ struct wireless_dev {  	struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES];  	struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];  	struct cfg80211_internal_bss *current_bss; /* associated / joined */ +	struct ieee80211_channel *channel;  	bool ps;  	int ps_timeout; @@ -1627,7 +1654,7 @@ struct ieee80211_radiotap_iterator {  	const struct ieee80211_radiotap_namespace *current_namespace;  	unsigned char *_arg, *_next_ns_data; -	uint32_t *_next_bitmap; +	__le32 *_next_bitmap;  	unsigned char *this_arg;  	int this_arg_index; @@ -2337,4 +2364,18 @@ bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf,  void cfg80211_action_tx_status(struct net_device *dev, u64 cookie,  			       const u8 *buf, size_t len, bool ack, gfp_t gfp); + +/** + * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event + * @dev: network device + * @rssi_event: the triggered RSSI event + * @gfp: context flags + * + * This function is called when a configured connection quality monitoring + * rssi threshold reached event occurs. + */ +void cfg80211_cqm_rssi_notify(struct net_device *dev, +			      enum nl80211_cqm_rssi_threshold_event rssi_event, +			      gfp_t gfp); +  #endif /* __NET_CFG80211_H */ diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h new file mode 100644 index 000000000000..6cf44866cecd --- /dev/null +++ b/include/net/cls_cgroup.h @@ -0,0 +1,63 @@ +/* + * cls_cgroup.h			Control Group Classifier + * + * Authors:	Thomas Graf <tgraf@suug.ch> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ + +#ifndef _NET_CLS_CGROUP_H +#define _NET_CLS_CGROUP_H + +#include <linux/cgroup.h> +#include <linux/hardirq.h> +#include <linux/rcupdate.h> + +#ifdef CONFIG_CGROUPS +struct cgroup_cls_state +{ +	struct cgroup_subsys_state css; +	u32 classid; +}; + +#ifdef CONFIG_NET_CLS_CGROUP +static inline u32 task_cls_classid(struct task_struct *p) +{ +	if (in_interrupt()) +		return 0; + +	return container_of(task_subsys_state(p, net_cls_subsys_id), +			    struct cgroup_cls_state, css)->classid; +} +#else +extern int net_cls_subsys_id; + +static inline u32 task_cls_classid(struct task_struct *p) +{ +	int id; +	u32 classid; + +	if (in_interrupt()) +		return 0; + +	rcu_read_lock(); +	id = rcu_dereference(net_cls_subsys_id); +	if (id >= 0) +		classid = container_of(task_subsys_state(p, id), +				       struct cgroup_cls_state, css)->classid; +	rcu_read_unlock(); + +	return classid; +} +#endif +#else +static inline u32 task_cls_classid(struct task_struct *p) +{ +	return 0; +} +#endif +#endif  /* _NET_CLS_CGROUP_H */ diff --git a/include/net/dn_fib.h b/include/net/dn_fib.h index 52da6c3dd50d..bbcde3238e58 100644 --- a/include/net/dn_fib.h +++ b/include/net/dn_fib.h @@ -50,10 +50,6 @@ struct dn_fib_info {  	__le16			fib_prefsrc;  	__u32			fib_priority;  	__u32			fib_metrics[RTAX_MAX]; -#define dn_fib_mtu  fib_metrics[RTAX_MTU-1] -#define dn_fib_window fib_metrics[RTAX_WINDOW-1] -#define dn_fib_rtt fib_metrics[RTAX_RTT-1] -#define dn_fib_advmss fib_metrics[RTAX_ADVMSS-1]  	int			fib_nhs;  	int			fib_power;  	struct dn_fib_nh	fib_nh[0]; diff --git a/include/net/dst.h b/include/net/dst.h index ce078cda6b74..612069beda73 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -168,6 +168,12 @@ static inline void dst_use(struct dst_entry *dst, unsigned long time)  	dst->lastuse = time;  } +static inline void dst_use_noref(struct dst_entry *dst, unsigned long time) +{ +	dst->__use++; +	dst->lastuse = time; +} +  static inline  struct dst_entry * dst_clone(struct dst_entry * dst)  { @@ -177,11 +183,67 @@ struct dst_entry * dst_clone(struct dst_entry * dst)  }  extern void dst_release(struct dst_entry *dst); + +static inline void refdst_drop(unsigned long refdst) +{ +	if (!(refdst & SKB_DST_NOREF)) +		dst_release((struct dst_entry *)(refdst & SKB_DST_PTRMASK)); +} + +/** + * skb_dst_drop - drops skb dst + * @skb: buffer + * + * Drops dst reference count if a reference was taken. + */  static inline void skb_dst_drop(struct sk_buff *skb)  { -	if (skb->_skb_dst) -		dst_release(skb_dst(skb)); -	skb->_skb_dst = 0UL; +	if (skb->_skb_refdst) { +		refdst_drop(skb->_skb_refdst); +		skb->_skb_refdst = 0UL; +	} +} + +static inline void skb_dst_copy(struct sk_buff *nskb, const struct sk_buff *oskb) +{ +	nskb->_skb_refdst = oskb->_skb_refdst; +	if (!(nskb->_skb_refdst & SKB_DST_NOREF)) +		dst_clone(skb_dst(nskb)); +} + +/** + * skb_dst_force - makes sure skb dst is refcounted + * @skb: buffer + * + * If dst is not yet refcounted, let's do it + */ +static inline void skb_dst_force(struct sk_buff *skb) +{ +	if (skb_dst_is_noref(skb)) { +		WARN_ON(!rcu_read_lock_held()); +		skb->_skb_refdst &= ~SKB_DST_NOREF; +		dst_clone(skb_dst(skb)); +	} +} + + +/** + *	skb_tunnel_rx - prepare skb for rx reinsert + *	@skb: buffer + *	@dev: tunnel device + * + *	After decapsulation, packet is going to re-enter (netif_rx()) our stack, + *	so make some cleanups, and perform accounting. + */ +static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) +{ +	skb->dev = dev; +	/* TODO : stats should be SMP safe */ +	dev->stats.rx_packets++; +	dev->stats.rx_bytes += skb->len; +	skb->rxhash = 0; +	skb_dst_drop(skb); +	nf_reset(skb);  }  /* Children define the path of the packet through the @@ -225,21 +287,6 @@ static inline void dst_confirm(struct dst_entry *dst)  		neigh_confirm(dst->neighbour);  } -static inline void dst_negative_advice(struct dst_entry **dst_p, -				       struct sock *sk) -{ -	struct dst_entry * dst = *dst_p; -	if (dst && dst->ops->negative_advice) { -		*dst_p = dst->ops->negative_advice(dst); - -		if (dst != *dst_p) { -			extern void sk_reset_txq(struct sock *sk); - -			sk_reset_txq(sk); -		} -	} -} -  static inline void dst_link_failure(struct sk_buff *skb)  {  	struct dst_entry *dst = skb_dst(skb); diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index c49086d2bc7d..e8923bc20f9f 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -104,7 +104,7 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)  	return frh->table;  } -extern struct fib_rules_ops *fib_rules_register(struct fib_rules_ops *, struct net *); +extern struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *, struct net *);  extern void fib_rules_unregister(struct fib_rules_ops *);  extern void                     fib_rules_cleanup_ops(struct fib_rules_ops *); @@ -114,4 +114,5 @@ extern int			fib_rules_lookup(struct fib_rules_ops *,  extern int			fib_default_rule_add(struct fib_rules_ops *,  						     u32 pref, u32 table,  						     u32 flags); +extern u32			fib_default_rule_pref(struct fib_rules_ops *ops);  #endif diff --git a/include/net/flow.h b/include/net/flow.h index 809970b7dfee..bb08692a20b0 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -86,11 +86,26 @@ struct flowi {  struct net;  struct sock; -typedef int (*flow_resolve_t)(struct net *net, struct flowi *key, u16 family, -			      u8 dir, void **objp, atomic_t **obj_refp); +struct flow_cache_ops; + +struct flow_cache_object { +	const struct flow_cache_ops *ops; +}; + +struct flow_cache_ops { +	struct flow_cache_object *(*get)(struct flow_cache_object *); +	int (*check)(struct flow_cache_object *); +	void (*delete)(struct flow_cache_object *); +}; + +typedef struct flow_cache_object *(*flow_resolve_t)( +		struct net *net, struct flowi *key, u16 family, +		u8 dir, struct flow_cache_object *oldobj, void *ctx); + +extern struct flow_cache_object *flow_cache_lookup( +		struct net *net, struct flowi *key, u16 family, +		u8 dir, flow_resolve_t resolver, void *ctx); -extern void *flow_cache_lookup(struct net *net, struct flowi *key, u16 family, -			       u8 dir, flow_resolve_t resolver);  extern void flow_cache_flush(void);  extern atomic_t flow_cache_genid; diff --git a/include/net/icmp.h b/include/net/icmp.h index 15b3dfe9fce8..6e991e0d0d6f 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h @@ -48,15 +48,4 @@ extern void	icmp_out_count(struct net *net, unsigned char type);  /* Move into dst.h ? */  extern int 	xrlim_allow(struct dst_entry *dst, int timeout); -struct raw_sock { -	/* inet_sock has to be the first member */ -	struct inet_sock   inet; -	struct icmp_filter filter; -}; - -static inline struct raw_sock *raw_sk(const struct sock *sk) -{ -	return (struct raw_sock *)sk; -} -  #endif	/* _ICMP_H */ diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 545d8b059bef..f95ff8d9aa47 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -32,6 +32,13 @@  #ifdef __KERNEL__ +enum { +	INET6_IFADDR_STATE_DAD, +	INET6_IFADDR_STATE_POSTDAD, +	INET6_IFADDR_STATE_UP, +	INET6_IFADDR_STATE_DEAD, +}; +  struct inet6_ifaddr {  	struct in6_addr		addr;  	__u32			prefix_len; @@ -40,6 +47,9 @@ struct inet6_ifaddr {  	__u32			prefered_lft;  	atomic_t		refcnt;  	spinlock_t		lock; +	spinlock_t		state_lock; + +	int			state;  	__u8			probes;  	__u8			flags; @@ -54,16 +64,15 @@ struct inet6_ifaddr {  	struct inet6_dev	*idev;  	struct rt6_info		*rt; -	struct inet6_ifaddr	*lst_next;      /* next addr in addr_lst */ -	struct inet6_ifaddr	*if_next;       /* next addr in inet6_dev */ +	struct hlist_node	addr_lst; +	struct list_head	if_list;  #ifdef CONFIG_IPV6_PRIVACY -	struct inet6_ifaddr	*tmp_next;	/* next addr in tempaddr_lst */ +	struct list_head	tmp_list;  	struct inet6_ifaddr	*ifpub;  	int			regen_count;  #endif - -	int			dead; +	struct rcu_head		rcu;  };  struct ip6_sf_socklist { @@ -151,9 +160,9 @@ struct ipv6_devstat {  };  struct inet6_dev { -	struct net_device		*dev; +	struct net_device	*dev; -	struct inet6_ifaddr	*addr_list; +	struct list_head	addr_list;  	struct ifmcaddr6	*mc_list;  	struct ifmcaddr6	*mc_tomb; @@ -175,7 +184,7 @@ struct inet6_dev {  #ifdef CONFIG_IPV6_PRIVACY  	u8			rndid[8];  	struct timer_list	regen_timer; -	struct inet6_ifaddr	*tempaddr_list; +	struct list_head	tempaddr_list;  #endif  	struct neigh_parms	*nd_parms; diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h index f13ddc2543b1..aae08f686633 100644 --- a/include/net/inet6_connection_sock.h +++ b/include/net/inet6_connection_sock.h @@ -38,5 +38,5 @@ extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk,  extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); -extern int inet6_csk_xmit(struct sk_buff *skb, int ipfragok); +extern int inet6_csk_xmit(struct sk_buff *skb);  #endif /* _INET6_CONNECTION_SOCK_H */ diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 696d6e4ce68a..b6d3b55da19b 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -36,9 +36,8 @@ struct tcp_congestion_ops;   * (i.e. things that depend on the address family)   */  struct inet_connection_sock_af_ops { -	int	    (*queue_xmit)(struct sk_buff *skb, int ipfragok); -	void	    (*send_check)(struct sock *sk, int len, -				  struct sk_buff *skb); +	int	    (*queue_xmit)(struct sk_buff *skb); +	void	    (*send_check)(struct sock *sk, struct sk_buff *skb);  	int	    (*rebuild_header)(struct sock *sk);  	int	    (*conn_request)(struct sock *sk, struct sk_buff *skb);  	struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb, diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 83fd34437cf1..1653de515cee 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -21,6 +21,7 @@  #include <linux/string.h>  #include <linux/types.h>  #include <linux/jhash.h> +#include <linux/netdevice.h>  #include <net/flow.h>  #include <net/sock.h> diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 79f67eae8a7e..a066fdd50da6 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -224,7 +224,9 @@ static inline  struct net *twsk_net(const struct inet_timewait_sock *twsk)  {  #ifdef CONFIG_NET_NS -	return rcu_dereference(twsk->tw_net); +	return rcu_dereference_raw(twsk->tw_net); /* protected by locking, */ +						  /* reference counting, */ +						  /* initialization, or RCU. */  #else  	return &init_net;  #endif diff --git a/include/net/ip.h b/include/net/ip.h index 503994a38ed1..452f229c380a 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -101,7 +101,7 @@ extern int		ip_do_nat(struct sk_buff *skb);  extern void		ip_send_check(struct iphdr *ip);  extern int		__ip_local_out(struct sk_buff *skb);  extern int		ip_local_out(struct sk_buff *skb); -extern int		ip_queue_xmit(struct sk_buff *skb, int ipfragok); +extern int		ip_queue_xmit(struct sk_buff *skb);  extern void		ip_init(void);  extern int		ip_append_data(struct sock *sk,  				       int getfrag(void *from, char *to, int offset, int len, @@ -184,6 +184,12 @@ extern struct local_ports {  } sysctl_local_ports;  extern void inet_get_local_port_range(int *low, int *high); +extern unsigned long *sysctl_local_reserved_ports; +static inline int inet_is_reserved_local_port(int port) +{ +	return test_bit(port, sysctl_local_reserved_ports); +} +  extern int sysctl_ip_default_ttl;  extern int sysctl_ip_nonlocal_bind; @@ -352,11 +358,11 @@ enum ip_defrag_users {  	IP_DEFRAG_LOCAL_DELIVER,  	IP_DEFRAG_CALL_RA_CHAIN,  	IP_DEFRAG_CONNTRACK_IN, -	__IP_DEFRAG_CONNTRACK_IN_END	= IP_DEFRAG_CONNTRACK_IN + USHORT_MAX, +	__IP_DEFRAG_CONNTRACK_IN_END	= IP_DEFRAG_CONNTRACK_IN + USHRT_MAX,  	IP_DEFRAG_CONNTRACK_OUT, -	__IP_DEFRAG_CONNTRACK_OUT_END	= IP_DEFRAG_CONNTRACK_OUT + USHORT_MAX, +	__IP_DEFRAG_CONNTRACK_OUT_END	= IP_DEFRAG_CONNTRACK_OUT + USHRT_MAX,  	IP_DEFRAG_CONNTRACK_BRIDGE_IN, -	__IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHORT_MAX, +	__IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX,  	IP_DEFRAG_VS_IN,  	IP_DEFRAG_VS_OUT,  	IP_DEFRAG_VS_FWD @@ -393,6 +399,7 @@ extern int ip_options_rcv_srr(struct sk_buff *skb);   *	Functions provided by ip_sockglue.c   */ +extern int	ip_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);  extern void	ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb);  extern int	ip_cmsg_send(struct net *net,  			     struct msghdr *msg, struct ipcm_cookie *ipc); diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 86f46c49e318..4b1dc1161c37 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -88,34 +88,37 @@ struct rt6_info {  		struct dst_entry	dst;  	} u; -	struct inet6_dev		*rt6i_idev; -  #define rt6i_dev			u.dst.dev  #define rt6i_nexthop			u.dst.neighbour  #define rt6i_expires			u.dst.expires +	/* +	 * Tail elements of dst_entry (__refcnt etc.) +	 * and these elements (rarely used in hot path) are in +	 * the same cache line. +	 */ +	struct fib6_table		*rt6i_table;  	struct fib6_node		*rt6i_node;  	struct in6_addr			rt6i_gateway; -	 -	u32				rt6i_flags; -	u32				rt6i_metric; -	atomic_t			rt6i_ref; -	/* more non-fragment space at head required */ -	unsigned short			rt6i_nfheader_len; - -	u8				rt6i_protocol; +	atomic_t			rt6i_ref; -	struct fib6_table		*rt6i_table; +	/* These are in a separate cache line. */ +	struct rt6key			rt6i_dst ____cacheline_aligned_in_smp; +	u32				rt6i_flags; +	struct rt6key			rt6i_src; +	u32				rt6i_metric; -	struct rt6key			rt6i_dst; +	struct inet6_dev		*rt6i_idev;  #ifdef CONFIG_XFRM  	u32				rt6i_flow_cache_genid;  #endif +	/* more non-fragment space at head required */ +	unsigned short			rt6i_nfheader_len; -	struct rt6key			rt6i_src; +	u8				rt6i_protocol;  };  static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 68f67836e146..278312c95f96 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -152,9 +152,9 @@ static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst,  static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,  				 struct in6_addr *daddr, struct in6_addr *saddr)  { -	write_lock(&sk->sk_dst_lock); +	spin_lock(&sk->sk_dst_lock);  	__ip6_dst_store(sk, dst, daddr, saddr); -	write_unlock(&sk->sk_dst_lock); +	spin_unlock(&sk->sk_dst_lock);  }  static inline int ipv6_unicast_destination(struct sk_buff *skb) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index e72fb10ce573..2600b69757b8 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -354,11 +354,11 @@ struct inet_frag_queue;  enum ip6_defrag_users {  	IP6_DEFRAG_LOCAL_DELIVER,  	IP6_DEFRAG_CONNTRACK_IN, -	__IP6_DEFRAG_CONNTRACK_IN	= IP6_DEFRAG_CONNTRACK_IN + USHORT_MAX, +	__IP6_DEFRAG_CONNTRACK_IN	= IP6_DEFRAG_CONNTRACK_IN + USHRT_MAX,  	IP6_DEFRAG_CONNTRACK_OUT, -	__IP6_DEFRAG_CONNTRACK_OUT	= IP6_DEFRAG_CONNTRACK_OUT + USHORT_MAX, +	__IP6_DEFRAG_CONNTRACK_OUT	= IP6_DEFRAG_CONNTRACK_OUT + USHRT_MAX,  	IP6_DEFRAG_CONNTRACK_BRIDGE_IN, -	__IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHORT_MAX, +	__IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX,  };  struct ip6_create_arg { @@ -422,7 +422,7 @@ static inline int __ipv6_addr_diff(const void *token1, const void *token2, int a  	for (i = 0; i < addrlen; i++) {  		__be32 xb = a1[i] ^ a2[i];  		if (xb) -			return i * 32 + 32 - fls(ntohl(xb)); +			return i * 32 + 31 - __fls(ntohl(xb));  	}  	/* @@ -482,8 +482,7 @@ extern int			ip6_rcv_finish(struct sk_buff *skb);  extern int			ip6_xmit(struct sock *sk,  					 struct sk_buff *skb,  					 struct flowi *fl, -					 struct ipv6_txoptions *opt, -					 int ipfragok); +					 struct ipv6_txoptions *opt);  extern int			ip6_nd_hdr(struct sock *sk,  					   struct sk_buff *skb, @@ -504,7 +503,8 @@ extern int			ip6_append_data(struct sock *sk,  						struct ipv6_txoptions *opt,  						struct flowi *fl,  						struct rt6_info *rt, -						unsigned int flags); +						unsigned int flags, +						int dontfrag);  extern int			ip6_push_pending_frames(struct sock *sk); @@ -578,9 +578,11 @@ extern int			ip6_datagram_connect(struct sock *sk,  						     struct sockaddr *addr, int addr_len);  extern int 			ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len); +extern int 			ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);  extern void			ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,  						u32 info, u8 *payload);  extern void			ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info); +extern void			ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu);  extern int inet6_release(struct socket *sock);  extern int inet6_bind(struct socket *sock, struct sockaddr *uaddr,  diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index b2b98f3fa265..3afdb21cc31d 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h @@ -323,7 +323,7 @@ typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,  struct iw_handler_def {  	/* Array of handlers for standard ioctls -	 * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWCOMMIT] +	 * We will call dev->wireless_handlers->standard[ioctl - SIOCIWFIRST]  	 */  	const iw_handler *	standard;  	/* Number of handlers defined (more precisely, index of the diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 45d7d44d7cbe..de22cbfef232 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -144,6 +144,8 @@ struct ieee80211_low_level_stats {   *	new beacon (beaconing modes)   * @BSS_CHANGED_BEACON_ENABLED: Beaconing should be   *	enabled/disabled (beaconing modes) + * @BSS_CHANGED_CQM: Connection quality monitor config changed + * @BSS_CHANGED_IBSS: IBSS join status changed   */  enum ieee80211_bss_change {  	BSS_CHANGED_ASSOC		= 1<<0, @@ -156,6 +158,10 @@ enum ieee80211_bss_change {  	BSS_CHANGED_BSSID		= 1<<7,  	BSS_CHANGED_BEACON		= 1<<8,  	BSS_CHANGED_BEACON_ENABLED	= 1<<9, +	BSS_CHANGED_CQM			= 1<<10, +	BSS_CHANGED_IBSS		= 1<<11, + +	/* when adding here, make sure to change ieee80211_reconfig */  };  /** @@ -165,6 +171,8 @@ enum ieee80211_bss_change {   * to that BSS) that can change during the lifetime of the BSS.   *   * @assoc: association status + * @ibss_joined: indicates whether this station is part of an IBSS + *	or not   * @aid: association ID number, valid only when @assoc is true   * @use_cts_prot: use CTS protection   * @use_short_preamble: use 802.11b short preamble; @@ -183,13 +191,19 @@ enum ieee80211_bss_change {   *	the current band.   * @bssid: The BSSID for this BSS   * @enable_beacon: whether beaconing should be enabled or not + * @channel_type: Channel type for this BSS -- the hardware might be + *	configured for HT40+ while this BSS only uses no-HT, for + *	example.   * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info).   *	This field is only valid when the channel type is one of the HT types. + * @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value + *	implies disabled + * @cqm_rssi_hyst: Connection quality monitor RSSI hysteresis   */  struct ieee80211_bss_conf {  	const u8 *bssid;  	/* association related data */ -	bool assoc; +	bool assoc, ibss_joined;  	u16 aid;  	/* erp related data */  	bool use_cts_prot; @@ -202,6 +216,9 @@ struct ieee80211_bss_conf {  	u64 timestamp;  	u32 basic_rates;  	u16 ht_operation_mode; +	s32 cqm_rssi_thold; +	u32 cqm_rssi_hyst; +	enum nl80211_channel_type channel_type;  };  /** @@ -267,6 +284,9 @@ struct ieee80211_bss_conf {   * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211   *	MLME command (internal to mac80211 to figure out whether to send TX   *	status to user space) + * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame + * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this + *	frame and selects the maximum number of streams that it can use.   */  enum mac80211_tx_control_flags {  	IEEE80211_TX_CTL_REQ_TX_STATUS		= BIT(0), @@ -290,6 +310,9 @@ enum mac80211_tx_control_flags {  	IEEE80211_TX_INTFL_RETRANSMISSION	= BIT(19),  	IEEE80211_TX_INTFL_HAS_RADIOTAP		= BIT(20),  	IEEE80211_TX_INTFL_NL80211_FRAME_TX	= BIT(21), +	IEEE80211_TX_CTL_LDPC			= BIT(22), +	IEEE80211_TX_CTL_STBC			= BIT(23) | BIT(24), +#define IEEE80211_TX_CTL_STBC_SHIFT		23  };  /** @@ -388,11 +411,11 @@ struct ieee80211_tx_rate {   * @status: union for status data   * @driver_data: array of driver_data pointers   * @ampdu_ack_len: number of acked aggregated frames. - * 	relevant only if IEEE80211_TX_STATUS_AMPDU was set. + * 	relevant only if IEEE80211_TX_STAT_AMPDU was set.   * @ampdu_ack_map: block ack bit map for the aggregation. - * 	relevant only if IEEE80211_TX_STATUS_AMPDU was set. + * 	relevant only if IEEE80211_TX_STAT_AMPDU was set.   * @ampdu_len: number of aggregated frames. - * 	relevant only if IEEE80211_TX_STATUS_AMPDU was set. + * 	relevant only if IEEE80211_TX_STAT_AMPDU was set.   * @ack_signal: signal strength of the ACK frame   */  struct ieee80211_tx_info { @@ -543,7 +566,6 @@ enum mac80211_rx_flags {   * @signal: signal strength when receiving this frame, either in dBm, in dB or   *	unspecified depending on the hardware capabilities flags   *	@IEEE80211_HW_SIGNAL_* - * @noise: noise when receiving this frame, in dBm.   * @antenna: antenna used   * @rate_idx: index of data rate into band's supported rates or MCS index if   *	HT rates are use (RX_FLAG_HT) @@ -554,7 +576,6 @@ struct ieee80211_rx_status {  	enum ieee80211_band band;  	int freq;  	int signal; -	int noise;  	int antenna;  	int rate_idx;  	int flag; @@ -580,11 +601,15 @@ struct ieee80211_rx_status {   *	may turn the device off as much as possible. Typically, this flag will   *	be set when an interface is set UP but not associated or scanning, but   *	it can also be unset in that case when monitor interfaces are active. + * @IEEE80211_CONF_QOS: Enable 802.11e QoS also know as WMM (Wireless + *      Multimedia). On some drivers (iwlwifi is one of know) we have + *      to enable/disable QoS explicitly.   */  enum ieee80211_conf_flags {  	IEEE80211_CONF_MONITOR		= (1<<0),  	IEEE80211_CONF_PS		= (1<<1),  	IEEE80211_CONF_IDLE		= (1<<2), +	IEEE80211_CONF_QOS		= (1<<3),  }; @@ -599,6 +624,7 @@ enum ieee80211_conf_flags {   * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed   * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed   * @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed + * @IEEE80211_CONF_CHANGE_QOS: Quality of service was enabled or disabled   */  enum ieee80211_conf_changed {  	IEEE80211_CONF_CHANGE_SMPS		= BIT(1), @@ -609,6 +635,7 @@ enum ieee80211_conf_changed {  	IEEE80211_CONF_CHANGE_CHANNEL		= BIT(6),  	IEEE80211_CONF_CHANGE_RETRY_LIMITS	= BIT(7),  	IEEE80211_CONF_CHANGE_IDLE		= BIT(8), +	IEEE80211_CONF_CHANGE_QOS		= BIT(9),  };  /** @@ -649,6 +676,9 @@ enum ieee80211_smps_mode {   * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the   *	powersave documentation below. This variable is valid only when   *	the CONF_PS flag is set. + * @dynamic_ps_forced_timeout: The dynamic powersave timeout (in ms) configured + *	by cfg80211 (essentially, wext) If set, this value overrules the value + *	chosen by mac80211 based on ps qos network latency.   *   * @power_level: requested transmit power (in dBm)   * @@ -668,7 +698,7 @@ enum ieee80211_smps_mode {   */  struct ieee80211_conf {  	u32 flags; -	int power_level, dynamic_ps_timeout; +	int power_level, dynamic_ps_timeout, dynamic_ps_forced_timeout;  	int max_sleep_period;  	u16 listen_interval; @@ -682,6 +712,28 @@ struct ieee80211_conf {  };  /** + * struct ieee80211_channel_switch - holds the channel switch data + * + * The information provided in this structure is required for channel switch + * operation. + * + * @timestamp: value in microseconds of the 64-bit Time Synchronization + *	Function (TSF) timer when the frame containing the channel switch + *	announcement was received. This is simply the rx.mactime parameter + *	the driver passed into mac80211. + * @block_tx: Indicates whether transmission must be blocked before the + *	scheduled channel switch, as indicated by the AP. + * @channel: the new channel to switch to + * @count: the number of TBTT's until the channel switch event + */ +struct ieee80211_channel_switch { +	u64 timestamp; +	bool block_tx; +	struct ieee80211_channel *channel; +	u8 count; +}; + +/**   * struct ieee80211_vif - per-interface data   *   * Data in this structure is continually present for driver @@ -763,6 +815,7 @@ enum ieee80211_key_flags {   *	encrypted in hardware.   * @alg: The key algorithm.   * @flags: key flags, see &enum ieee80211_key_flags. + * @ap_addr: AP's MAC address   * @keyidx: the key index (0-3)   * @keylen: key material length   * @key: key material. For ALG_TKIP the key is encoded as a 256-bit (32 byte) @@ -907,10 +960,6 @@ enum ieee80211_tkip_key_type {   *	one milliwatt. This is the preferred method since it is standardized   *	between different devices. @max_signal does not need to be set.   * - * @IEEE80211_HW_NOISE_DBM: - *	Hardware can provide noise (radio interference) values in units dBm, - *      decibel difference from one milliwatt. - *   * @IEEE80211_HW_SPECTRUM_MGMT:   * 	Hardware supports spectrum management defined in 802.11h   * 	Measurement, Channel Switch, Quieting, TPC @@ -954,6 +1003,17 @@ enum ieee80211_tkip_key_type {   *	Hardware can provide ack status reports of Tx frames to   *	the stack.   * + * @IEEE80211_HW_CONNECTION_MONITOR: + *      The hardware performs its own connection monitoring, including + *      periodic keep-alives to the AP and probing the AP on beacon loss. + *      When this flag is set, signaling beacon-loss will cause an immediate + *      change to disassociated state. + * + * @IEEE80211_HW_SUPPORTS_CQM_RSSI: + *	Hardware can do connection quality monitoring - i.e. it can monitor + *	connection quality related parameters, such as the RSSI level and + *	provide notifications if configured trigger levels are reached. + *   */  enum ieee80211_hw_flags {  	IEEE80211_HW_HAS_RATE_CONTROL			= 1<<0, @@ -963,7 +1023,7 @@ enum ieee80211_hw_flags {  	IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE	= 1<<4,  	IEEE80211_HW_SIGNAL_UNSPEC			= 1<<5,  	IEEE80211_HW_SIGNAL_DBM				= 1<<6, -	IEEE80211_HW_NOISE_DBM				= 1<<7, +	/* use this hole */  	IEEE80211_HW_SPECTRUM_MGMT			= 1<<8,  	IEEE80211_HW_AMPDU_AGGREGATION			= 1<<9,  	IEEE80211_HW_SUPPORTS_PS			= 1<<10, @@ -975,6 +1035,8 @@ enum ieee80211_hw_flags {  	IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS		= 1<<16,  	IEEE80211_HW_SUPPORTS_UAPSD			= 1<<17,  	IEEE80211_HW_REPORTS_TX_ACK_STATUS		= 1<<18, +	IEEE80211_HW_CONNECTION_MONITOR			= 1<<19, +	IEEE80211_HW_SUPPORTS_CQM_RSSI			= 1<<20,  };  /** @@ -1576,6 +1638,8 @@ enum ieee80211_ampdu_mlme_action {   *	Returns a negative error code on failure.   *	The callback must be atomic.   * + * @get_survey: Return per-channel survey information + *   * @rfkill_poll: Poll rfkill hardware state. If you need this, you also   *	need to set wiphy->rfkill_poll to %true before registration,   *	and need to call wiphy_rfkill_set_hw_state() in the callback. @@ -1591,6 +1655,11 @@ enum ieee80211_ampdu_mlme_action {   * @flush: Flush all pending frames from the hardware queue, making sure   *	that the hardware queues are empty. If the parameter @drop is set   *	to %true, pending frames may be dropped. The callback can sleep. + * + * @channel_switch: Drivers that need (or want) to offload the channel + *	switch operation for CSAs received from the AP may implement this + *	callback. They must then call ieee80211_chswitch_done() to indicate + *	completion of the channel switch.   */  struct ieee80211_ops {  	int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); @@ -1606,7 +1675,7 @@ struct ieee80211_ops {  				 struct ieee80211_bss_conf *info,  				 u32 changed);  	u64 (*prepare_multicast)(struct ieee80211_hw *hw, -				 int mc_count, struct dev_addr_list *mc_list); +				 struct netdev_hw_addr_list *mc_list);  	void (*configure_filter)(struct ieee80211_hw *hw,  				 unsigned int changed_flags,  				 unsigned int *total_flags, @@ -1621,7 +1690,7 @@ struct ieee80211_ops {  				struct ieee80211_key_conf *conf,  				struct ieee80211_sta *sta,  				u32 iv32, u16 *phase1key); -	int (*hw_scan)(struct ieee80211_hw *hw, +	int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,  		       struct cfg80211_scan_request *req);  	void (*sw_scan_start)(struct ieee80211_hw *hw);  	void (*sw_scan_complete)(struct ieee80211_hw *hw); @@ -1646,13 +1715,16 @@ struct ieee80211_ops {  			    struct ieee80211_vif *vif,  			    enum ieee80211_ampdu_mlme_action action,  			    struct ieee80211_sta *sta, u16 tid, u16 *ssn); - +	int (*get_survey)(struct ieee80211_hw *hw, int idx, +		struct survey_info *survey);  	void (*rfkill_poll)(struct ieee80211_hw *hw);  	void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class);  #ifdef CONFIG_NL80211_TESTMODE  	int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len);  #endif  	void (*flush)(struct ieee80211_hw *hw, bool drop); +	void (*channel_switch)(struct ieee80211_hw *hw, +			       struct ieee80211_channel_switch *ch_switch);  };  /** @@ -1802,7 +1874,10 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw);   * ieee80211_rx - receive frame   *   * Use this function to hand received frames to mac80211. The receive - * buffer in @skb must start with an IEEE 802.11 header. + * buffer in @skb must start with an IEEE 802.11 header. In case of a + * paged @skb is used, the driver is recommended to put the ieee80211 + * header of the frame on the linear part of the @skb to avoid memory + * allocation and/or memcpy by the stack.   *   * This function may not be called in IRQ context. Calls to this function   * for a single hardware must be synchronized against each other. Calls to @@ -2364,12 +2439,52 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,   *   * @vif: &struct ieee80211_vif pointer from the add_interface callback.   * - * When beacon filtering is enabled with IEEE80211_HW_BEACON_FILTERING and - * IEEE80211_CONF_PS is set, the driver needs to inform whenever the + * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING and + * %IEEE80211_CONF_PS is set, the driver needs to inform whenever the   * hardware is not receiving beacons with this function.   */  void ieee80211_beacon_loss(struct ieee80211_vif *vif); +/** + * ieee80211_connection_loss - inform hardware has lost connection to the AP + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * + * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING, and + * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver + * needs to inform if the connection to the AP has been lost. + * + * This function will cause immediate change to disassociated state, + * without connection recovery attempts. + */ +void ieee80211_connection_loss(struct ieee80211_vif *vif); + +/** + * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring + *	rssi threshold triggered + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @rssi_event: the RSSI trigger event type + * @gfp: context flags + * + * When the %IEEE80211_HW_SUPPORTS_CQM_RSSI is set, and a connection quality + * monitoring is configured with an rssi threshold, the driver will inform + * whenever the rssi level reaches the threshold. + */ +void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, +			       enum nl80211_cqm_rssi_threshold_event rssi_event, +			       gfp_t gfp); + +/** + * ieee80211_chswitch_done - Complete channel switch process + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @success: make the channel switch successful or not + * + * Complete the channel switch post-process: set the new operational channel + * and wake up the suspended queues. + */ +void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success); +  /* Rate control API */  /** diff --git a/include/net/mld.h b/include/net/mld.h new file mode 100644 index 000000000000..467143cd4e2f --- /dev/null +++ b/include/net/mld.h @@ -0,0 +1,75 @@ +#ifndef LINUX_MLD_H +#define LINUX_MLD_H + +#include <linux/in6.h> +#include <linux/icmpv6.h> + +/* MLDv1 Query/Report/Done */ +struct mld_msg { +	struct icmp6hdr		mld_hdr; +	struct in6_addr		mld_mca; +}; + +#define mld_type		mld_hdr.icmp6_type +#define mld_code		mld_hdr.icmp6_code +#define mld_cksum		mld_hdr.icmp6_cksum +#define mld_maxdelay		mld_hdr.icmp6_maxdelay +#define mld_reserved		mld_hdr.icmp6_dataun.un_data16[1] + +/* Multicast Listener Discovery version 2 headers */ +/* MLDv2 Report */ +struct mld2_grec { +	__u8		grec_type; +	__u8		grec_auxwords; +	__be16		grec_nsrcs; +	struct in6_addr	grec_mca; +	struct in6_addr	grec_src[0]; +}; + +struct mld2_report { +	struct icmp6hdr		mld2r_hdr; +	struct mld2_grec	mld2r_grec[0]; +}; + +#define mld2r_type		mld2r_hdr.icmp6_type +#define mld2r_resv1		mld2r_hdr.icmp6_code +#define mld2r_cksum		mld2r_hdr.icmp6_cksum +#define mld2r_resv2		mld2r_hdr.icmp6_dataun.un_data16[0] +#define mld2r_ngrec		mld2r_hdr.icmp6_dataun.un_data16[1] + +/* MLDv2 Query */ +struct mld2_query { +	struct icmp6hdr		mld2q_hdr; +	struct in6_addr		mld2q_mca; +#if defined(__LITTLE_ENDIAN_BITFIELD) +	__u8			mld2q_qrv:3, +				mld2q_suppress:1, +				mld2q_resv2:4; +#elif defined(__BIG_ENDIAN_BITFIELD) +	__u8			mld2q_resv2:4, +				mld2q_suppress:1, +				mld2q_qrv:3; +#else +#error "Please fix <asm/byteorder.h>" +#endif +	__u8			mld2q_qqic; +	__be16			mld2q_nsrcs; +	struct in6_addr		mld2q_srcs[0]; +}; + +#define mld2q_type		mld2q_hdr.icmp6_type +#define mld2q_code		mld2q_hdr.icmp6_code +#define mld2q_cksum		mld2q_hdr.icmp6_cksum +#define mld2q_mrc		mld2q_hdr.icmp6_maxdelay +#define mld2q_resv1		mld2q_hdr.icmp6_dataun.un_data16[1] + +/* Max Response Code */ +#define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value)) +#define MLDV2_EXP(thresh, nbmant, nbexp, value) \ +	((value) < (thresh) ? (value) : \ +	((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ +	(MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) + +#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) + +#endif diff --git a/include/net/neighbour.h b/include/net/neighbour.h index da1d58be31b7..eb21340a573b 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -299,6 +299,20 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)  	return 0;  } +#ifdef CONFIG_BRIDGE_NETFILTER +static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb) +{ +	unsigned seq, hh_alen; + +	do { +		seq = read_seqbegin(&hh->hh_lock); +		hh_alen = HH_DATA_ALIGN(ETH_HLEN); +		memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN); +	} while (read_seqretry(&hh->hh_lock, seq)); +	return 0; +} +#endif +  static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)  {  	unsigned seq; diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index dffde8e6920e..3d7524fba194 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h @@ -61,7 +61,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)  	int ret = NF_ACCEPT;  	if (ct && ct != &nf_conntrack_untracked) { -		if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) +		if (!nf_ct_is_confirmed(ct))  			ret = __nf_conntrack_confirm(skb);  		if (likely(ret == NF_ACCEPT))  			nf_ct_deliver_cached_events(ct); diff --git a/include/net/netns/generic.h b/include/net/netns/generic.h index ff4982ab84b6..81a31c0db3e7 100644 --- a/include/net/netns/generic.h +++ b/include/net/netns/generic.h @@ -14,11 +14,8 @@   * The rules are simple:   * 1. set pernet_operations->id.  After register_pernet_device you   *    will have the id of your private pointer. - * 2. Either set pernet_operations->size (to have the code allocate and - *    free a private structure pointed to from struct net ) or  - *    call net_assign_generic() to put the private data on the struct - *    net (most preferably this should be done in the ->init callback - *    of the ops registered); + * 2. set pernet_operations->size to have the code allocate and free + *    a private structure pointed to from struct net.   * 3. do not change this pointer while the net is alive;   * 4. do not try to have any private reference on the net_generic object.   * @@ -46,6 +43,4 @@ static inline void *net_generic(struct net *net, int id)  	return ptr;  } - -extern int net_assign_generic(struct net *net, int id, void *data);  #endif diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 2764994c9136..d68c3f121774 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -55,19 +55,14 @@ struct netns_ipv4 {  	int sysctl_rt_cache_rebuild_count;  	int current_rt_cache_rebuild_count; -	struct timer_list rt_secret_timer;  	atomic_t rt_genid;  #ifdef CONFIG_IP_MROUTE -	struct sock		*mroute_sk; -	struct mfc_cache	**mfc_cache_array; -	struct vif_device	*vif_table; -	int			maxvif; -	atomic_t		cache_resolve_queue_len; -	int			mroute_do_assert; -	int			mroute_do_pim; -#if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) -	int			mroute_reg_vif_num; +#ifndef CONFIG_IP_MROUTE_MULTIPLE_TABLES +	struct mr_table		*mrt; +#else +	struct list_head	mr_tables; +	struct fib_rules_ops	*mr_rules_ops;  #endif  #endif  }; diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 1f11ebc22151..81abfcb2eb4e 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -59,15 +59,11 @@ struct netns_ipv6 {  	struct sock             *tcp_sk;  	struct sock             *igmp_sk;  #ifdef CONFIG_IPV6_MROUTE -	struct sock		*mroute6_sk; -	struct mfc6_cache	**mfc6_cache_array; -	struct mif_device	*vif6_table; -	int			maxvif; -	atomic_t		cache_resolve_queue_len; -	int			mroute_do_assert; -	int			mroute_do_pim; -#ifdef CONFIG_IPV6_PIMSM_V2 -	int			mroute_reg_vif_num; +#ifndef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES +	struct mr6_table	*mrt6; +#else +	struct list_head	mr6_tables; +	struct fib_rules_ops	*mr6_rules_ops;  #endif  #endif  }; diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index b6cdc33b39c1..9d4d87cc970e 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -12,7 +12,7 @@ struct qdisc_walker {  	int	(*fn)(struct Qdisc *, unsigned long cl, struct qdisc_walker *);  }; -#define QDISC_ALIGNTO		32 +#define QDISC_ALIGNTO		64  #define QDISC_ALIGN(len)	(((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1))  static inline void *qdisc_priv(struct Qdisc *q) diff --git a/include/net/raw.h b/include/net/raw.h index 6c14a656357a..43c57502659b 100644 --- a/include/net/raw.h +++ b/include/net/raw.h @@ -19,6 +19,7 @@  #include <net/protocol.h> +#include <linux/icmp.h>  extern struct proto raw_prot; @@ -56,4 +57,16 @@ int raw_seq_open(struct inode *ino, struct file *file,  void raw_hash_sk(struct sock *sk);  void raw_unhash_sk(struct sock *sk); +struct raw_sock { +	/* inet_sock has to be the first member */ +	struct inet_sock   inet; +	struct icmp_filter filter; +	u32		   ipmr_table; +}; + +static inline struct raw_sock *raw_sk(const struct sock *sk) +{ +	return (struct raw_sock *)sk; +} +  #endif	/* _RAW_H */ diff --git a/include/net/route.h b/include/net/route.h index 2c9fba7f7731..af6cf4b4c9dc 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -112,7 +112,22 @@ extern void		rt_cache_flush_batch(void);  extern int		__ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp);  extern int		ip_route_output_key(struct net *, struct rtable **, struct flowi *flp);  extern int		ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); -extern int		ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin); + +extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, +				 u8 tos, struct net_device *devin, bool noref); + +static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src, +				 u8 tos, struct net_device *devin) +{ +	return ip_route_input_common(skb, dst, src, tos, devin, false); +} + +static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src, +				       u8 tos, struct net_device *devin) +{ +	return ip_route_input_common(skb, dst, src, tos, devin, true); +} +  extern unsigned short	ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev);  extern void		ip_rt_send_redirect(struct sk_buff *skb); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 67dc08eaaa45..03ca5d826757 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -73,6 +73,7 @@ struct Qdisc {  	struct sk_buff_head	q;  	struct gnet_stats_basic_packed bstats;  	struct gnet_stats_queue	qstats; +	struct rcu_head     rcu_head;  };  struct Qdisc_class_ops { diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index fa6cde578a1d..65946bc43d00 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -269,7 +269,7 @@ enum {  #define SCTP_MIB_MAX    __SCTP_MIB_MAX  struct sctp_mib {          unsigned long   mibs[SCTP_MIB_MAX]; -} __SNMP_MIB_ALIGN__; +};  /* Print debugging messages.  */ @@ -547,7 +547,7 @@ for (pos = chunk->subh.fwdtsn_hdr->skip;\  #define WORD_ROUND(s) (((s)+3)&~3)  /* Make a new instance of type.  */ -#define t_new(type, flags)	(type *)kmalloc(sizeof(type), flags) +#define t_new(type, flags)	(type *)kzalloc(sizeof(type), flags)  /* Compare two timevals.  */  #define tv_lt(s, t) \ diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 61d73e37d543..4088c89a9055 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -438,7 +438,7 @@ sctp_vtag_verify_either(const struct sctp_chunk *chunk,  	 */          if ((!sctp_test_T_bit(chunk) &&               (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)) || -	    (sctp_test_T_bit(chunk) && +	    (sctp_test_T_bit(chunk) && asoc->c.peer_vtag &&  	     (ntohl(chunk->sctp_hdr->vtag) == asoc->c.peer_vtag))) {                  return 1;  	} diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 219043a67bf7..6173c619913a 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -643,17 +643,15 @@ struct sctp_pf {  struct sctp_datamsg {  	/* Chunks waiting to be submitted to lower layer. */  	struct list_head chunks; -	/* Chunks that have been transmitted. */ -	size_t msg_size;  	/* Reference counting. */  	atomic_t refcnt;  	/* When is this message no longer interesting to the peer? */  	unsigned long expires_at;  	/* Did the messenge fail to send? */  	int send_error; -	char send_failed; -	/* Control whether chunks from this message can be abandoned. */ -	char can_abandon; +	u8 send_failed:1, +	   can_abandon:1,   /* can chunks from this message can be abandoned. */ +	   can_delay;	    /* should this message be Nagle delayed */  };  struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, @@ -757,7 +755,6 @@ struct sctp_chunk {  #define SCTP_NEED_FRTX 0x1  #define SCTP_DONT_FRTX 0x2  	__u16	rtt_in_progress:1,	/* This chunk used for RTT calc? */ -		resent:1,		/* Has this chunk ever been resent. */  		has_tsn:1,		/* Does this chunk have a TSN yet? */  		has_ssn:1,		/* Does this chunk have a SSN yet? */  		singleton:1,		/* Only chunk in the packet? */ @@ -879,7 +876,30 @@ struct sctp_transport {  	/* Reference counting. */  	atomic_t refcnt; -	int	 dead; +	int	 dead:1, +		/* RTO-Pending : A flag used to track if one of the DATA +		 *		chunks sent to this address is currently being +		 *		used to compute a RTT. If this flag is 0, +		 *		the next DATA chunk sent to this destination +		 *		should be used to compute a RTT and this flag +		 *		should be set. Every time the RTT +		 *		calculation completes (i.e. the DATA chunk +		 *		is SACK'd) clear this flag. +		 */ +		 rto_pending:1, + +		/* +		 * hb_sent : a flag that signals that we have a pending +		 * heartbeat. +		 */ +		hb_sent:1, + +		/* Is the Path MTU update pending on this tranport */ +		pmtu_pending:1, + +		/* Is this structure kfree()able? */ +		malloced:1; +  	/* This is the peer's IP address and port. */  	union sctp_addr ipaddr; @@ -909,22 +929,6 @@ struct sctp_transport {  	/* SRTT	       : The current smoothed round trip time.	*/  	__u32 srtt; -	/* RTO-Pending : A flag used to track if one of the DATA -	 *		chunks sent to this address is currently being -	 *		used to compute a RTT. If this flag is 0, -	 *		the next DATA chunk sent to this destination -	 *		should be used to compute a RTT and this flag -	 *		should be set. Every time the RTT -	 *		calculation completes (i.e. the DATA chunk -	 *		is SACK'd) clear this flag. -	 * hb_sent : a flag that signals that we have a pending heartbeat. -	 */ -	__u8 rto_pending; -	__u8 hb_sent; - -	/* Flag to track the current fast recovery state */ -	__u8 fast_recovery; -  	/*  	 * These are the congestion stats.  	 */ @@ -944,9 +948,6 @@ struct sctp_transport {  	__u32 burst_limited;	/* Holds old cwnd when max.burst is applied */ -	/* TSN marking the fast recovery exit point */ -	__u32 fast_recovery_exit; -  	/* Destination */  	struct dst_entry *dst;  	/* Source address. */ @@ -977,9 +978,6 @@ struct sctp_transport {  	 */  	__u16 pathmaxrxt; -	/* is the Path MTU update pending on this tranport */ -	__u8 pmtu_pending; -  	/* PMTU	      : The current known path MTU.  */  	__u32 pathmtu; @@ -1026,8 +1024,6 @@ struct sctp_transport {  	/* This is the list of transports that have chunks to send.  */  	struct list_head send_ready; -	int malloced; /* Is this structure kfree()able? */ -  	/* State information saved for SFR_CACC algorithm. The key  	 * idea in SFR_CACC is to maintain state at the sender on a  	 * per-destination basis when a changeover happens. @@ -1069,7 +1065,7 @@ void sctp_transport_route(struct sctp_transport *, union sctp_addr *,  			  struct sctp_sock *);  void sctp_transport_pmtu(struct sctp_transport *);  void sctp_transport_free(struct sctp_transport *); -void sctp_transport_reset_timers(struct sctp_transport *, int); +void sctp_transport_reset_timers(struct sctp_transport *);  void sctp_transport_hold(struct sctp_transport *);  void sctp_transport_put(struct sctp_transport *);  void sctp_transport_update_rto(struct sctp_transport *, __u32); @@ -1723,6 +1719,12 @@ struct sctp_association {  	/* Highest TSN that is acknowledged by incoming SACKs. */  	__u32 highest_sacked; +	/* TSN marking the fast recovery exit point */ +	__u32 fast_recovery_exit; + +	/* Flag to track the current fast recovery state */ +	__u8 fast_recovery; +  	/* The number of unacknowledged data chunks.  Reported through  	 * the SCTP_STATUS sockopt.  	 */ diff --git a/include/net/snmp.h b/include/net/snmp.h index 692ee0061dc4..92456f1035f5 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -52,26 +52,11 @@ struct snmp_mib {   * count on the 20Gb/s + networks people expect in a few years time!   */ -/*  - * The rule for padding:  - * Best is power of two because then the right structure can be found by a  - * simple shift. The structure should be always cache line aligned. - * gcc needs n=alignto(cachelinesize, popcnt(sizeof(bla_mib))) shift/add  - * instructions to emulate multiply in case it is not power-of-two.  - * Currently n is always <=3 for all sizes so simple cache line alignment  - * is enough.  - *  - * The best solution would be a global CPU local area , especially on 64  - * and 128byte cacheline machine it makes a *lot* of sense -AK - */  - -#define __SNMP_MIB_ALIGN__	____cacheline_aligned -  /* IPstats */  #define IPSTATS_MIB_MAX	__IPSTATS_MIB_MAX  struct ipstats_mib {  	unsigned long	mibs[IPSTATS_MIB_MAX]; -} __SNMP_MIB_ALIGN__; +};  /* ICMP */  #define ICMP_MIB_DUMMY	__ICMP_MIB_MAX @@ -79,36 +64,36 @@ struct ipstats_mib {  struct icmp_mib {  	unsigned long	mibs[ICMP_MIB_MAX]; -} __SNMP_MIB_ALIGN__; +};  #define ICMPMSG_MIB_MAX	__ICMPMSG_MIB_MAX  struct icmpmsg_mib {  	unsigned long	mibs[ICMPMSG_MIB_MAX]; -} __SNMP_MIB_ALIGN__; +};  /* ICMP6 (IPv6-ICMP) */  #define ICMP6_MIB_MAX	__ICMP6_MIB_MAX  struct icmpv6_mib {  	unsigned long	mibs[ICMP6_MIB_MAX]; -} __SNMP_MIB_ALIGN__; +};  #define ICMP6MSG_MIB_MAX  __ICMP6MSG_MIB_MAX  struct icmpv6msg_mib {  	unsigned long	mibs[ICMP6MSG_MIB_MAX]; -} __SNMP_MIB_ALIGN__; +};  /* TCP */  #define TCP_MIB_MAX	__TCP_MIB_MAX  struct tcp_mib {  	unsigned long	mibs[TCP_MIB_MAX]; -} __SNMP_MIB_ALIGN__; +};  /* UDP */  #define UDP_MIB_MAX	__UDP_MIB_MAX  struct udp_mib {  	unsigned long	mibs[UDP_MIB_MAX]; -} __SNMP_MIB_ALIGN__; +};  /* Linux */  #define LINUX_MIB_MAX	__LINUX_MIB_MAX @@ -148,6 +133,8 @@ struct linux_xfrm_mib {  			__this_cpu_add(mib[0]->mibs[field], addend)  #define SNMP_ADD_STATS_USER(mib, field, addend)	\  			this_cpu_add(mib[1]->mibs[field], addend) +#define SNMP_ADD_STATS(mib, field, addend)	\ +			this_cpu_add(mib[0]->mibs[field], addend)  /*   * Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr"   * to make @ptr a non-percpu pointer. diff --git a/include/net/sock.h b/include/net/sock.h index 1ad6435f252e..d2a71b04a5ae 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -159,7 +159,7 @@ struct sock_common {    *	@sk_userlocks: %SO_SNDBUF and %SO_RCVBUF settings    *	@sk_lock:	synchronizer    *	@sk_rcvbuf: size of receive buffer in bytes -  *	@sk_sleep: sock wait queue +  *	@sk_wq: sock wait queue and async head    *	@sk_dst_cache: destination cache    *	@sk_dst_lock: destination cache lock    *	@sk_policy: flow policy @@ -177,6 +177,7 @@ struct sock_common {    *		   %SO_OOBINLINE settings, %SO_TIMESTAMPING settings    *	@sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets    *	@sk_route_caps: route capabilities (e.g. %NETIF_F_TSO) +  *	@sk_route_nocaps: forbidden route capabilities (e.g NETIF_F_GSO_MASK)    *	@sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)    *	@sk_gso_max_size: Maximum GSO segment size to build    *	@sk_lingertime: %SO_LINGER l_linger setting @@ -198,6 +199,7 @@ struct sock_common {    *	@sk_rcvlowat: %SO_RCVLOWAT setting    *	@sk_rcvtimeo: %SO_RCVTIMEO setting    *	@sk_sndtimeo: %SO_SNDTIMEO setting +  *	@sk_rxhash: flow hash received from netif layer    *	@sk_filter: socket filtering instructions    *	@sk_protinfo: private area, net family specific, when not using slab    *	@sk_timer: sock cleanup timer @@ -255,14 +257,13 @@ struct sock {  		struct sk_buff *head;  		struct sk_buff *tail;  		int len; -		int limit;  	} sk_backlog; -	wait_queue_head_t	*sk_sleep; +	struct socket_wq	*sk_wq;  	struct dst_entry	*sk_dst_cache;  #ifdef CONFIG_XFRM  	struct xfrm_policy	*sk_policy[2];  #endif -	rwlock_t		sk_dst_lock; +	spinlock_t		sk_dst_lock;  	atomic_t		sk_rmem_alloc;  	atomic_t		sk_wmem_alloc;  	atomic_t		sk_omem_alloc; @@ -276,9 +277,13 @@ struct sock {  	int			sk_forward_alloc;  	gfp_t			sk_allocation;  	int			sk_route_caps; +	int			sk_route_nocaps;  	int			sk_gso_type;  	unsigned int		sk_gso_max_size;  	int			sk_rcvlowat; +#ifdef CONFIG_RPS +	__u32			sk_rxhash; +#endif  	unsigned long 		sk_flags;  	unsigned long	        sk_lingertime;  	struct sk_buff_head	sk_error_queue; @@ -307,7 +312,7 @@ struct sock {  	void			*sk_security;  #endif  	__u32			sk_mark; -	/* XXX 4 bytes hole on 64 bit */ +	u32			sk_classid;  	void			(*sk_state_change)(struct sock *sk);  	void			(*sk_data_ready)(struct sock *sk, int bytes);  	void			(*sk_write_space)(struct sock *sk); @@ -595,19 +600,32 @@ static inline int sk_stream_memory_free(struct sock *sk)  /* OOB backlog add */  static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)  { -	if (!sk->sk_backlog.tail) { -		sk->sk_backlog.head = sk->sk_backlog.tail = skb; -	} else { +	/* dont let skb dst not refcounted, we are going to leave rcu lock */ +	skb_dst_force(skb); + +	if (!sk->sk_backlog.tail) +		sk->sk_backlog.head = skb; +	else  		sk->sk_backlog.tail->next = skb; -		sk->sk_backlog.tail = skb; -	} + +	sk->sk_backlog.tail = skb;  	skb->next = NULL;  } +/* + * Take into account size of receive queue and backlog queue + */ +static inline bool sk_rcvqueues_full(const struct sock *sk, const struct sk_buff *skb) +{ +	unsigned int qsize = sk->sk_backlog.len + atomic_read(&sk->sk_rmem_alloc); + +	return qsize + skb->truesize > sk->sk_rcvbuf; +} +  /* The per-socket spinlock must be held here. */  static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb)  { -	if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1)) +	if (sk_rcvqueues_full(sk, skb))  		return -ENOBUFS;  	__sk_add_backlog(sk, skb); @@ -620,6 +638,40 @@ static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)  	return sk->sk_backlog_rcv(sk, skb);  } +static inline void sock_rps_record_flow(const struct sock *sk) +{ +#ifdef CONFIG_RPS +	struct rps_sock_flow_table *sock_flow_table; + +	rcu_read_lock(); +	sock_flow_table = rcu_dereference(rps_sock_flow_table); +	rps_record_sock_flow(sock_flow_table, sk->sk_rxhash); +	rcu_read_unlock(); +#endif +} + +static inline void sock_rps_reset_flow(const struct sock *sk) +{ +#ifdef CONFIG_RPS +	struct rps_sock_flow_table *sock_flow_table; + +	rcu_read_lock(); +	sock_flow_table = rcu_dereference(rps_sock_flow_table); +	rps_reset_sock_flow(sock_flow_table, sk->sk_rxhash); +	rcu_read_unlock(); +#endif +} + +static inline void sock_rps_save_rxhash(struct sock *sk, u32 rxhash) +{ +#ifdef CONFIG_RPS +	if (unlikely(sk->sk_rxhash != rxhash)) { +		sock_rps_reset_flow(sk); +		sk->sk_rxhash = rxhash; +	} +#endif +} +  #define sk_wait_event(__sk, __timeo, __condition)			\  	({	int __rc;						\  		release_sock(__sk);					\ @@ -974,6 +1026,16 @@ extern void release_sock(struct sock *sk);  				SINGLE_DEPTH_NESTING)  #define bh_unlock_sock(__sk)	spin_unlock(&((__sk)->sk_lock.slock)) +static inline void lock_sock_bh(struct sock *sk) +{ +	spin_lock_bh(&sk->sk_lock.slock); +} + +static inline void unlock_sock_bh(struct sock *sk) +{ +	spin_unlock_bh(&sk->sk_lock.slock); +} +  extern struct sock		*sk_alloc(struct net *net, int family,  					  gfp_t priority,  					  struct proto *prot); @@ -1012,6 +1074,14 @@ extern void *sock_kmalloc(struct sock *sk, int size,  extern void sock_kfree_s(struct sock *sk, void *mem, int size);  extern void sk_send_sigurg(struct sock *sk); +#ifdef CONFIG_CGROUPS +extern void sock_update_classid(struct sock *sk); +#else +static inline void sock_update_classid(struct sock *sk) +{ +} +#endif +  /*   * Functions to fill in entries in struct proto_ops when a protocol   * does not implement a particular function. @@ -1160,6 +1230,10 @@ static inline void sk_set_socket(struct sock *sk, struct socket *sock)  	sk->sk_socket = sock;  } +static inline wait_queue_head_t *sk_sleep(struct sock *sk) +{ +	return &sk->sk_wq->wait; +}  /* Detach socket from process context.   * Announce socket dead, detach it from wait queue and inode.   * Note that parent inode held reference count on this struct sock, @@ -1172,14 +1246,14 @@ static inline void sock_orphan(struct sock *sk)  	write_lock_bh(&sk->sk_callback_lock);  	sock_set_flag(sk, SOCK_DEAD);  	sk_set_socket(sk, NULL); -	sk->sk_sleep  = NULL; +	sk->sk_wq  = NULL;  	write_unlock_bh(&sk->sk_callback_lock);  }  static inline void sock_graft(struct sock *sk, struct socket *parent)  {  	write_lock_bh(&sk->sk_callback_lock); -	sk->sk_sleep = &parent->wait; +	rcu_assign_pointer(sk->sk_wq, parent->wq);  	parent->sk = sk;  	sk_set_socket(sk, parent);  	security_sock_graft(sk, parent); @@ -1192,7 +1266,9 @@ extern unsigned long sock_i_ino(struct sock *sk);  static inline struct dst_entry *  __sk_dst_get(struct sock *sk)  { -	return sk->sk_dst_cache; +	return rcu_dereference_check(sk->sk_dst_cache, rcu_read_lock_held() || +						       sock_owned_by_user(sk) || +						       lockdep_is_held(&sk->sk_lock.slock));  }  static inline struct dst_entry * @@ -1200,50 +1276,65 @@ sk_dst_get(struct sock *sk)  {  	struct dst_entry *dst; -	read_lock(&sk->sk_dst_lock); -	dst = sk->sk_dst_cache; +	rcu_read_lock(); +	dst = rcu_dereference(sk->sk_dst_cache);  	if (dst)  		dst_hold(dst); -	read_unlock(&sk->sk_dst_lock); +	rcu_read_unlock();  	return dst;  } +extern void sk_reset_txq(struct sock *sk); + +static inline void dst_negative_advice(struct sock *sk) +{ +	struct dst_entry *ndst, *dst = __sk_dst_get(sk); + +	if (dst && dst->ops->negative_advice) { +		ndst = dst->ops->negative_advice(dst); + +		if (ndst != dst) { +			rcu_assign_pointer(sk->sk_dst_cache, ndst); +			sk_reset_txq(sk); +		} +	} +} +  static inline void  __sk_dst_set(struct sock *sk, struct dst_entry *dst)  {  	struct dst_entry *old_dst;  	sk_tx_queue_clear(sk); -	old_dst = sk->sk_dst_cache; -	sk->sk_dst_cache = dst; +	/* +	 * This can be called while sk is owned by the caller only, +	 * with no state that can be checked in a rcu_dereference_check() cond +	 */ +	old_dst = rcu_dereference_raw(sk->sk_dst_cache); +	rcu_assign_pointer(sk->sk_dst_cache, dst);  	dst_release(old_dst);  }  static inline void  sk_dst_set(struct sock *sk, struct dst_entry *dst)  { -	write_lock(&sk->sk_dst_lock); +	spin_lock(&sk->sk_dst_lock);  	__sk_dst_set(sk, dst); -	write_unlock(&sk->sk_dst_lock); +	spin_unlock(&sk->sk_dst_lock);  }  static inline void  __sk_dst_reset(struct sock *sk)  { -	struct dst_entry *old_dst; - -	sk_tx_queue_clear(sk); -	old_dst = sk->sk_dst_cache; -	sk->sk_dst_cache = NULL; -	dst_release(old_dst); +	__sk_dst_set(sk, NULL);  }  static inline void  sk_dst_reset(struct sock *sk)  { -	write_lock(&sk->sk_dst_lock); +	spin_lock(&sk->sk_dst_lock);  	__sk_dst_reset(sk); -	write_unlock(&sk->sk_dst_lock); +	spin_unlock(&sk->sk_dst_lock);  }  extern struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie); @@ -1257,6 +1348,12 @@ static inline int sk_can_gso(const struct sock *sk)  extern void sk_setup_caps(struct sock *sk, struct dst_entry *dst); +static inline void sk_nocaps_add(struct sock *sk, int flags) +{ +	sk->sk_route_nocaps |= flags; +	sk->sk_route_caps &= ~flags; +} +  static inline int skb_copy_to_page(struct sock *sk, char __user *from,  				   struct sk_buff *skb, struct page *page,  				   int off, int copy) @@ -1314,12 +1411,12 @@ static inline int sk_has_allocations(const struct sock *sk)  }  /** - * sk_has_sleeper - check if there are any waiting processes - * @sk: socket + * wq_has_sleeper - check if there are any waiting processes + * @wq: struct socket_wq   * - * Returns true if socket has waiting processes + * Returns true if socket_wq has waiting processes   * - * The purpose of the sk_has_sleeper and sock_poll_wait is to wrap the memory + * The purpose of the wq_has_sleeper and sock_poll_wait is to wrap the memory   * barrier call. They were added due to the race found within the tcp code.   *   * Consider following tcp code paths: @@ -1332,9 +1429,10 @@ static inline int sk_has_allocations(const struct sock *sk)   *   ...                 ...   *   tp->rcv_nxt check   sock_def_readable   *   ...                 { - *   schedule               ... - *                          if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) - *                              wake_up_interruptible(sk->sk_sleep) + *   schedule               rcu_read_lock(); + *                          wq = rcu_dereference(sk->sk_wq); + *                          if (wq && waitqueue_active(&wq->wait)) + *                              wake_up_interruptible(&wq->wait)   *                          ...   *                       }   * @@ -1343,19 +1441,18 @@ static inline int sk_has_allocations(const struct sock *sk)   * could then endup calling schedule and sleep forever if there are no more   * data on the socket.   * - * The sk_has_sleeper is always called right after a call to read_lock, so we - * can use smp_mb__after_lock barrier.   */ -static inline int sk_has_sleeper(struct sock *sk) +static inline bool wq_has_sleeper(struct socket_wq *wq)  { +  	/*  	 * We need to be sure we are in sync with the  	 * add_wait_queue modifications to the wait queue.  	 *  	 * This memory barrier is paired in the sock_poll_wait.  	 */ -	smp_mb__after_lock(); -	return sk->sk_sleep && waitqueue_active(sk->sk_sleep); +	smp_mb(); +	return wq && waitqueue_active(&wq->wait);  }  /** @@ -1364,7 +1461,7 @@ static inline int sk_has_sleeper(struct sock *sk)   * @wait_address:   socket wait queue   * @p:              poll_table   * - * See the comments in the sk_has_sleeper function. + * See the comments in the wq_has_sleeper function.   */  static inline void sock_poll_wait(struct file *filp,  		wait_queue_head_t *wait_address, poll_table *p) @@ -1375,7 +1472,7 @@ static inline void sock_poll_wait(struct file *filp,  		 * We need to be sure we are in sync with the  		 * socket flags modification.  		 * -		 * This memory barrier is paired in the sk_has_sleeper. +		 * This memory barrier is paired in the wq_has_sleeper.  		*/  		smp_mb();  	} @@ -1557,7 +1654,24 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)  		sk->sk_stamp = kt;  } -extern void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb); +extern void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, +				     struct sk_buff *skb); + +static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, +					  struct sk_buff *skb) +{ +#define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL)			| \ +			   (1UL << SOCK_RCVTSTAMP)			| \ +			   (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)	| \ +			   (1UL << SOCK_TIMESTAMPING_SOFTWARE)		| \ +			   (1UL << SOCK_TIMESTAMPING_RAW_HARDWARE) 	| \ +			   (1UL << SOCK_TIMESTAMPING_SYS_HARDWARE)) + +	if (sk->sk_flags & FLAGS_TS_OR_DROPS) +		__sock_recv_ts_and_drops(msg, sk, skb); +	else +		sk->sk_stamp = skb->tstamp; +}  /**   * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped diff --git a/include/net/tcp.h b/include/net/tcp.h index aa04b9a5093b..a1449144848a 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -294,6 +294,7 @@ extern struct proto tcp_prot;  #define TCP_INC_STATS_BH(net, field)	SNMP_INC_STATS_BH((net)->mib.tcp_statistics, field)  #define TCP_DEC_STATS(net, field)	SNMP_DEC_STATS((net)->mib.tcp_statistics, field)  #define TCP_ADD_STATS_USER(net, field, val) SNMP_ADD_STATS_USER((net)->mib.tcp_statistics, field, val) +#define TCP_ADD_STATS(net, field, val)	SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val)  extern void			tcp_v4_err(struct sk_buff *skb, u32); @@ -423,7 +424,7 @@ extern u8			*tcp_parse_md5sig_option(struct tcphdr *th);   *	TCP v4 functions exported for the inet6 API   */ -extern void		       	tcp_v4_send_check(struct sock *sk, int len, +extern void		       	tcp_v4_send_check(struct sock *sk,  						  struct sk_buff *skb);  extern int			tcp_v4_conn_request(struct sock *sk, @@ -939,7 +940,7 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)  		tp->ucopy.memory = 0;  	} else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { -		wake_up_interruptible_sync_poll(sk->sk_sleep, +		wake_up_interruptible_sync_poll(sk_sleep(sk),  					   POLLIN | POLLRDNORM | POLLRDBAND);  		if (!inet_csk_ack_scheduled(sk))  			inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, @@ -1032,6 +1033,14 @@ static inline int keepalive_probes(const struct tcp_sock *tp)  	return tp->keepalive_probes ? : sysctl_tcp_keepalive_probes;  } +static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp) +{ +	const struct inet_connection_sock *icsk = &tp->inet_conn; + +	return min_t(u32, tcp_time_stamp - icsk->icsk_ack.lrcvtime, +			  tcp_time_stamp - tp->rcv_tstamp); +} +  static inline int tcp_fin_time(const struct sock *sk)  {  	int fin_timeout = tcp_sk(sk)->linger2 ? : sysctl_tcp_fin_timeout; diff --git a/include/net/tipc/tipc.h b/include/net/tipc/tipc.h index 9566608c88cf..15af6dca0b49 100644 --- a/include/net/tipc/tipc.h +++ b/include/net/tipc/tipc.h @@ -2,7 +2,7 @@   * include/net/tipc/tipc.h: Main include file for TIPC users   *    * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems + * Copyright (c) 2005,2010 Wind River Systems   * All rights reserved.   *   * Redistribution and use in source and binary forms, with or without @@ -126,7 +126,7 @@ int tipc_createport(unsigned int tipc_user,  		    tipc_msg_event message_cb,   		    tipc_named_msg_event named_message_cb,   		    tipc_conn_msg_event conn_message_cb,  -		    tipc_continue_event continue_event_cb,/* May be zero */ +		    tipc_continue_event continue_event_cb,  		    u32 *portref);  int tipc_deleteport(u32 portref); @@ -145,13 +145,13 @@ int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);  int tipc_publish(u32 portref, unsigned int scope,   		 struct tipc_name_seq const *name_seq);  int tipc_withdraw(u32 portref, unsigned int scope, -		  struct tipc_name_seq const *name_seq); /* 0: all */ +		  struct tipc_name_seq const *name_seq);  int tipc_connect2port(u32 portref, struct tipc_portid const *port);  int tipc_disconnect(u32 portref); -int tipc_shutdown(u32 ref); /* Sends SHUTDOWN msg */ +int tipc_shutdown(u32 ref);  int tipc_isconnected(u32 portref, int *isconnected); @@ -176,7 +176,7 @@ int tipc_send_buf(u32 portref,  int tipc_send2name(u32 portref,   		   struct tipc_name const *name,  -		   u32 domain,	/* 0:own zone */ +		   u32 domain,  		   unsigned int num_sect,  		   struct iovec const *msg_sect); @@ -188,7 +188,7 @@ int tipc_send_buf2name(u32 portref,  int tipc_forward2name(u32 portref,   		      struct tipc_name const *name,  -		      u32 domain,   /*0: own zone */ +		      u32 domain,  		      unsigned int section_count,  		      struct iovec const *msg_sect,  		      struct tipc_portid const *origin, @@ -228,14 +228,14 @@ int tipc_forward_buf2port(u32 portref,  int tipc_multicast(u32 portref,   		   struct tipc_name_seq const *seq,  -		   u32 domain,	/* 0:own zone */ +		   u32 domain,	/* currently unused */  		   unsigned int section_count,  		   struct iovec const *msg);  #if 0  int tipc_multicast_buf(u32 portref,   		       struct tipc_name_seq const *seq,  -		       u32 domain,	/* 0:own zone */ +		       u32 domain,  		       void *buf,  		       unsigned int size);  #endif diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h index d65381cad0fc..42a0eb68b7b6 100644 --- a/include/net/transp_v6.h +++ b/include/net/transp_v6.h @@ -44,7 +44,8 @@ extern int			datagram_send_ctl(struct net *net,  						  struct msghdr *msg,  						  struct flowi *fl,  						  struct ipv6_txoptions *opt, -						  int *hlimit, int *tclass); +						  int *hlimit, int *tclass, +						  int *dontfrag);  #define		LOOPBACK4_IPV6		cpu_to_be32(0x7f000006) diff --git a/include/net/x25.h b/include/net/x25.h index 468551ea4f1d..1479cb4a41fc 100644 --- a/include/net/x25.h +++ b/include/net/x25.h @@ -80,8 +80,6 @@ enum {  #define	X25_DEFAULT_PACKET_SIZE	X25_PS128		/* Default Packet Size */  #define	X25_DEFAULT_THROUGHPUT	0x0A			/* Deafult Throughput */  #define	X25_DEFAULT_REVERSE	0x00			/* Default Reverse Charging */ -#define X25_DENY_ACCPT_APPRV   0x01			/* Default value */ -#define X25_ALLOW_ACCPT_APPRV  0x00			/* Control enabled */  #define X25_SMODULUS 		8  #define	X25_EMODULUS		128 @@ -113,6 +111,11 @@ enum {  #define X25_MAX_AE_LEN 		40			/* Max num of semi-octets in AE - OSI Nw */  #define X25_MAX_DTE_FACIL_LEN	21			/* Max length of DTE facility params */ +/* Bitset in x25_sock->flags for misc flags */ +#define X25_Q_BIT_FLAG		0 +#define X25_INTERRUPT_FLAG	1 +#define X25_ACCPT_APPRV_FLAG	2 +  /**   *	struct x25_route - x25 routing entry   *	@node - entry in x25_list_lock @@ -146,10 +149,11 @@ struct x25_sock {  	struct x25_address	source_addr, dest_addr;  	struct x25_neigh	*neighbour;  	unsigned int		lci, cudmatchlength; -	unsigned char		state, condition, qbitincl, intflag, accptapprv; +	unsigned char		state, condition;  	unsigned short		vs, vr, va, vl;  	unsigned long		t2, t21, t22, t23;  	unsigned short		fraglen; +	unsigned long		flags;  	struct sk_buff_head	ack_queue;  	struct sk_buff_head	fragment_queue;  	struct sk_buff_head	interrupt_in_queue; diff --git a/include/net/x25device.h b/include/net/x25device.h index 1415bcf93980..1fa08b49f1c2 100644 --- a/include/net/x25device.h +++ b/include/net/x25device.h @@ -3,6 +3,7 @@  #include <linux/if_ether.h>  #include <linux/if_packet.h> +#include <linux/if_x25.h>  #include <linux/skbuff.h>  static inline __be16 x25_type_trans(struct sk_buff *skb, struct net_device *dev) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index ac52f33f3e4a..1913af67c43d 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -20,6 +20,7 @@  #include <net/route.h>  #include <net/ipv6.h>  #include <net/ip6_fib.h> +#include <net/flow.h>  #include <linux/interrupt.h> @@ -267,7 +268,6 @@ struct xfrm_policy_afinfo {  					       xfrm_address_t *saddr,  					       xfrm_address_t *daddr);  	int			(*get_saddr)(struct net *net, xfrm_address_t *saddr, xfrm_address_t *daddr); -	struct dst_entry	*(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);  	void			(*decode_session)(struct sk_buff *skb,  						  struct flowi *fl,  						  int reverse); @@ -482,13 +482,14 @@ struct xfrm_policy {  	atomic_t		refcnt;  	struct timer_list	timer; +	struct flow_cache_object flo; +	atomic_t		genid;  	u32			priority;  	u32			index;  	struct xfrm_mark	mark;  	struct xfrm_selector	selector;  	struct xfrm_lifetime_cfg lft;  	struct xfrm_lifetime_cur curlft; -	struct dst_entry       *bundles;  	struct xfrm_policy_walk_entry walk;  	u8			type;  	u8			action; @@ -735,19 +736,12 @@ static inline void xfrm_pol_put(struct xfrm_policy *policy)  		xfrm_policy_destroy(policy);  } -#ifdef CONFIG_XFRM_SUB_POLICY  static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)  {  	int i;  	for (i = npols - 1; i >= 0; --i)  		xfrm_pol_put(pols[i]);  } -#else -static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols) -{ -	xfrm_pol_put(pols[0]); -} -#endif  extern void __xfrm_state_destroy(struct xfrm_state *); @@ -878,11 +872,15 @@ struct xfrm_dst {  		struct rt6_info		rt6;  	} u;  	struct dst_entry *route; +	struct flow_cache_object flo; +	struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; +	int num_pols, num_xfrms;  #ifdef CONFIG_XFRM_SUB_POLICY  	struct flowi *origin;  	struct xfrm_selector *partner;  #endif -	u32 genid; +	u32 xfrm_genid; +	u32 policy_genid;  	u32 route_mtu_cached;  	u32 child_mtu_cached;  	u32 route_cookie; @@ -892,6 +890,7 @@ struct xfrm_dst {  #ifdef CONFIG_XFRM  static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)  { +	xfrm_pols_put(xdst->pols, xdst->num_pols);  	dst_release(xdst->route);  	if (likely(xdst->u.dst.xfrm))  		xfrm_state_put(xdst->u.dst.xfrm); | 
