diff options
Diffstat (limited to 'include/net')
88 files changed, 3114 insertions, 887 deletions
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index a7fb54808a23..a8de812ccbc8 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -86,6 +86,18 @@ do { \ /** * enum p9_msg_t - 9P message types + * @P9_TSTATFS: file system status request + * @P9_RSTATFS: file system status response + * @P9_TSYMLINK: make symlink request + * @P9_RSYMLINK: make symlink response + * @P9_TMKNOD: create a special file object request + * @P9_RMKNOD: create a special file object response + * @P9_TLCREATE: prepare a handle for I/O on an new file for 9P2000.L + * @P9_RLCREATE: response with file access information for 9P2000.L + * @P9_TRENAME: rename request + * @P9_RRENAME: rename response + * @P9_TMKDIR: create a directory request + * @P9_RMKDIR: create a directory response * @P9_TVERSION: version handshake request * @P9_RVERSION: version handshake response * @P9_TAUTH: request to establish authentication channel @@ -125,6 +137,32 @@ do { \ */ enum p9_msg_t { + P9_TSTATFS = 8, + P9_RSTATFS, + P9_TLOPEN = 12, + P9_RLOPEN, + P9_TLCREATE = 14, + P9_RLCREATE, + P9_TSYMLINK = 16, + P9_RSYMLINK, + P9_TMKNOD = 18, + P9_RMKNOD, + P9_TRENAME = 20, + P9_RRENAME, + P9_TGETATTR = 24, + P9_RGETATTR, + P9_TSETATTR = 26, + P9_RSETATTR, + P9_TXATTRWALK = 30, + P9_RXATTRWALK, + P9_TXATTRCREATE = 32, + P9_RXATTRCREATE, + P9_TREADDIR = 40, + P9_RREADDIR, + P9_TLINK = 70, + P9_RLINK, + P9_TMKDIR = 72, + P9_RMKDIR, P9_TVERSION = 100, P9_RVERSION, P9_TAUTH = 102, @@ -267,6 +305,9 @@ enum p9_qid_t { /* ample room for Twrite/Rread header */ #define P9_IOHDRSZ 24 +/* Room for readdir header */ +#define P9_READDIRHDRSZ 24 + /** * struct p9_str - length prefixed string type * @len: length of the string @@ -349,7 +390,100 @@ struct p9_wstat { u32 n_muid; /* 9p2000.u extensions */ }; +struct p9_stat_dotl { + u64 st_result_mask; + struct p9_qid qid; + u32 st_mode; + u32 st_uid; + u32 st_gid; + u64 st_nlink; + u64 st_rdev; + u64 st_size; + u64 st_blksize; + u64 st_blocks; + u64 st_atime_sec; + u64 st_atime_nsec; + u64 st_mtime_sec; + u64 st_mtime_nsec; + u64 st_ctime_sec; + u64 st_ctime_nsec; + u64 st_btime_sec; + u64 st_btime_nsec; + u64 st_gen; + u64 st_data_version; +}; + +#define P9_STATS_MODE 0x00000001ULL +#define P9_STATS_NLINK 0x00000002ULL +#define P9_STATS_UID 0x00000004ULL +#define P9_STATS_GID 0x00000008ULL +#define P9_STATS_RDEV 0x00000010ULL +#define P9_STATS_ATIME 0x00000020ULL +#define P9_STATS_MTIME 0x00000040ULL +#define P9_STATS_CTIME 0x00000080ULL +#define P9_STATS_INO 0x00000100ULL +#define P9_STATS_SIZE 0x00000200ULL +#define P9_STATS_BLOCKS 0x00000400ULL + +#define P9_STATS_BTIME 0x00000800ULL +#define P9_STATS_GEN 0x00001000ULL +#define P9_STATS_DATA_VERSION 0x00002000ULL + +#define P9_STATS_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */ +#define P9_STATS_ALL 0x00003fffULL /* Mask for All fields above */ + +/** + * struct p9_iattr_dotl - P9 inode attribute for setattr + * @valid: bitfield specifying which fields are valid + * same as in struct iattr + * @mode: File permission bits + * @uid: user id of owner + * @gid: group id + * @size: File size + * @atime_sec: Last access time, seconds + * @atime_nsec: Last access time, nanoseconds + * @mtime_sec: Last modification time, seconds + * @mtime_nsec: Last modification time, nanoseconds + */ + +struct p9_iattr_dotl { + u32 valid; + u32 mode; + u32 uid; + u32 gid; + u64 size; + u64 atime_sec; + u64 atime_nsec; + u64 mtime_sec; + u64 mtime_nsec; +}; + /* 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; @@ -452,6 +586,18 @@ struct p9_rwrite { u32 count; }; +struct p9_treaddir { + u32 fid; + u64 offset; + u32 count; +}; + +struct p9_rreaddir { + u32 count; + u8 *data; +}; + + struct p9_tclunk { u32 fid; }; diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 4f3760afc20f..d1aa2cfb30f0 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -195,6 +195,23 @@ struct p9_fid { struct list_head dlist; /* list of all fids attached to a dentry */ }; +/** + * struct p9_dirent - directory entry structure + * @qid: The p9 server qid for this dirent + * @d_off: offset to the next dirent + * @d_type: type of file + * @d_name: file name + */ + +struct p9_dirent { + struct p9_qid qid; + u64 d_off; + unsigned char d_type; + char d_name[256]; +}; + +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); @@ -209,15 +226,31 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, int p9_client_open(struct p9_fid *fid, int mode); int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, char *extension); +int p9_client_link(struct p9_fid *fid, struct p9_fid *oldfid, char *newname); +int p9_client_symlink(struct p9_fid *fid, char *name, char *symname, gid_t gid, + struct p9_qid *qid); +int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode, + gid_t gid, struct p9_qid *qid); int p9_client_clunk(struct p9_fid *fid); int p9_client_remove(struct p9_fid *fid); int p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, u32 count); int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, u64 offset, u32 count); +int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset); +int p9dirent_read(char *buf, int len, struct p9_dirent *dirent, + int proto_version); struct p9_wstat *p9_client_stat(struct p9_fid *fid); int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); +int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *attr); + +struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, + u64 request_mask); +int p9_client_mknod_dotl(struct p9_fid *oldfid, char *name, int mode, + dev_t rdev, gid_t gid, struct p9_qid *); +int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode, + gid_t gid, struct p9_qid *); struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); void p9_client_cb(struct p9_client *c, struct p9_req_t *req); @@ -227,5 +260,7 @@ void p9stat_free(struct p9_wstat *); int p9_is_proto_dotu(struct p9_client *clnt); int p9_is_proto_dotl(struct p9_client *clnt); +struct p9_fid *p9_client_xattrwalk(struct p9_fid *, const char *, u64 *); +int p9_client_xattrcreate(struct p9_fid *, const char *, u64, int); #endif /* NET_9P_CLIENT_H */ diff --git a/include/net/act_api.h b/include/net/act_api.h index c05fd717c588..bab385f13ac3 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -20,6 +20,7 @@ struct tcf_common { struct gnet_stats_queue tcfc_qstats; struct gnet_stats_rate_est tcfc_rate_est; spinlock_t tcfc_lock; + struct rcu_head tcfc_rcu; }; #define tcf_next common.tcfc_next #define tcf_index common.tcfc_index @@ -32,6 +33,7 @@ struct tcf_common { #define tcf_qstats common.tcfc_qstats #define tcf_rate_est common.tcfc_rate_est #define tcf_lock common.tcfc_lock +#define tcf_rcu common.tcfc_rcu struct tcf_police { struct tcf_common common; diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 1614d78c60ed..90c9e2872f27 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -23,15 +23,15 @@ struct unix_address { }; struct unix_skb_parms { - struct ucred creds; /* Skb credentials */ + struct pid *pid; /* Skb credentials */ + const struct cred *cred; struct scm_fp_list *fp; /* Passed files */ #ifdef CONFIG_SECURITY_NETWORK u32 secid; /* Security ID */ #endif }; -#define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb)) -#define UNIXCREDS(skb) (&UNIXCB((skb)).creds) +#define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) #define UNIXSID(skb) (&UNIXCB((skb)).secid) #define unix_state_lock(s) spin_lock(&unix_sk(s)->lock) @@ -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/bluetooth.h b/include/net/bluetooth/bluetooth.h index ff77e8f882f1..27a902d9b3a9 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -84,7 +84,7 @@ enum { /* BD Address */ typedef struct { __u8 b[6]; -} __attribute__((packed)) bdaddr_t; +} __packed bdaddr_t; #define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}}) @@ -138,6 +138,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock); struct bt_skb_cb { __u8 pkt_type; __u8 incoming; + __u16 expect; __u8 tx_seq; __u8 retries; __u8 sar; diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index fc0c502d9fd1..bcbdd6d4e6dd 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -100,6 +100,9 @@ enum { #define HCISETACLMTU _IOW('H', 227, int) #define HCISETSCOMTU _IOW('H', 228, int) +#define HCIBLOCKADDR _IOW('H', 230, int) +#define HCIUNBLOCKADDR _IOW('H', 231, int) + #define HCIINQUIRY _IOR('H', 240, int) /* HCI timeouts */ @@ -227,7 +230,7 @@ struct hci_cp_inquiry { __u8 lap[3]; __u8 length; __u8 num_rsp; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_INQUIRY_CANCEL 0x0402 @@ -241,81 +244,81 @@ struct hci_cp_create_conn { __u8 pscan_mode; __le16 clock_offset; __u8 role_switch; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_DISCONNECT 0x0406 struct hci_cp_disconnect { __le16 handle; __u8 reason; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_ADD_SCO 0x0407 struct hci_cp_add_sco { __le16 handle; __le16 pkt_type; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_CREATE_CONN_CANCEL 0x0408 struct hci_cp_create_conn_cancel { bdaddr_t bdaddr; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_ACCEPT_CONN_REQ 0x0409 struct hci_cp_accept_conn_req { bdaddr_t bdaddr; __u8 role; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_REJECT_CONN_REQ 0x040a struct hci_cp_reject_conn_req { bdaddr_t bdaddr; __u8 reason; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_LINK_KEY_REPLY 0x040b struct hci_cp_link_key_reply { bdaddr_t bdaddr; __u8 link_key[16]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_LINK_KEY_NEG_REPLY 0x040c struct hci_cp_link_key_neg_reply { bdaddr_t bdaddr; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_PIN_CODE_REPLY 0x040d struct hci_cp_pin_code_reply { bdaddr_t bdaddr; __u8 pin_len; __u8 pin_code[16]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_PIN_CODE_NEG_REPLY 0x040e struct hci_cp_pin_code_neg_reply { bdaddr_t bdaddr; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_CHANGE_CONN_PTYPE 0x040f struct hci_cp_change_conn_ptype { __le16 handle; __le16 pkt_type; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_AUTH_REQUESTED 0x0411 struct hci_cp_auth_requested { __le16 handle; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_SET_CONN_ENCRYPT 0x0413 struct hci_cp_set_conn_encrypt { __le16 handle; __u8 encrypt; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415 struct hci_cp_change_conn_link_key { __le16 handle; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_REMOTE_NAME_REQ 0x0419 struct hci_cp_remote_name_req { @@ -323,28 +326,28 @@ struct hci_cp_remote_name_req { __u8 pscan_rep_mode; __u8 pscan_mode; __le16 clock_offset; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a struct hci_cp_remote_name_req_cancel { bdaddr_t bdaddr; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_REMOTE_FEATURES 0x041b struct hci_cp_read_remote_features { __le16 handle; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c struct hci_cp_read_remote_ext_features { __le16 handle; __u8 page; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_REMOTE_VERSION 0x041d struct hci_cp_read_remote_version { __le16 handle; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_SETUP_SYNC_CONN 0x0428 struct hci_cp_setup_sync_conn { @@ -355,7 +358,7 @@ struct hci_cp_setup_sync_conn { __le16 voice_setting; __u8 retrans_effort; __le16 pkt_type; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429 struct hci_cp_accept_sync_conn_req { @@ -366,13 +369,13 @@ struct hci_cp_accept_sync_conn_req { __le16 content_format; __u8 retrans_effort; __le16 pkt_type; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a struct hci_cp_reject_sync_conn_req { bdaddr_t bdaddr; __u8 reason; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_SNIFF_MODE 0x0803 struct hci_cp_sniff_mode { @@ -381,59 +384,59 @@ struct hci_cp_sniff_mode { __le16 min_interval; __le16 attempt; __le16 timeout; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_EXIT_SNIFF_MODE 0x0804 struct hci_cp_exit_sniff_mode { __le16 handle; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_ROLE_DISCOVERY 0x0809 struct hci_cp_role_discovery { __le16 handle; -} __attribute__ ((packed)); +} __packed; struct hci_rp_role_discovery { __u8 status; __le16 handle; __u8 role; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_SWITCH_ROLE 0x080b struct hci_cp_switch_role { bdaddr_t bdaddr; __u8 role; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_LINK_POLICY 0x080c struct hci_cp_read_link_policy { __le16 handle; -} __attribute__ ((packed)); +} __packed; struct hci_rp_read_link_policy { __u8 status; __le16 handle; __le16 policy; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_WRITE_LINK_POLICY 0x080d struct hci_cp_write_link_policy { __le16 handle; __le16 policy; -} __attribute__ ((packed)); +} __packed; struct hci_rp_write_link_policy { __u8 status; __le16 handle; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_DEF_LINK_POLICY 0x080e struct hci_rp_read_def_link_policy { __u8 status; __le16 policy; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f struct hci_cp_write_def_link_policy { __le16 policy; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_SNIFF_SUBRATE 0x0811 struct hci_cp_sniff_subrate { @@ -441,12 +444,12 @@ struct hci_cp_sniff_subrate { __le16 max_latency; __le16 min_remote_timeout; __le16 min_local_timeout; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_SET_EVENT_MASK 0x0c01 struct hci_cp_set_event_mask { __u8 mask[8]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_RESET 0x0c03 @@ -455,7 +458,7 @@ struct hci_cp_set_event_flt { __u8 flt_type; __u8 cond_type; __u8 condition[0]; -} __attribute__ ((packed)); +} __packed; /* Filter types */ #define HCI_FLT_CLEAR_ALL 0x00 @@ -474,13 +477,13 @@ struct hci_cp_set_event_flt { #define HCI_OP_WRITE_LOCAL_NAME 0x0c13 struct hci_cp_write_local_name { __u8 name[248]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_LOCAL_NAME 0x0c14 struct hci_rp_read_local_name { __u8 status; __u8 name[248]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_WRITE_CA_TIMEOUT 0x0c16 @@ -508,23 +511,23 @@ struct hci_rp_read_local_name { struct hci_rp_read_class_of_dev { __u8 status; __u8 dev_class[3]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_WRITE_CLASS_OF_DEV 0x0c24 struct hci_cp_write_class_of_dev { __u8 dev_class[3]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_VOICE_SETTING 0x0c25 struct hci_rp_read_voice_setting { __u8 status; __le16 voice_setting; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_WRITE_VOICE_SETTING 0x0c26 struct hci_cp_write_voice_setting { __le16 voice_setting; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_HOST_BUFFER_SIZE 0x0c33 struct hci_cp_host_buffer_size { @@ -532,18 +535,18 @@ struct hci_cp_host_buffer_size { __u8 sco_mtu; __le16 acl_max_pkt; __le16 sco_max_pkt; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_SSP_MODE 0x0c55 struct hci_rp_read_ssp_mode { __u8 status; __u8 mode; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_WRITE_SSP_MODE 0x0c56 struct hci_cp_write_ssp_mode { __u8 mode; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_LOCAL_VERSION 0x1001 struct hci_rp_read_local_version { @@ -553,19 +556,19 @@ struct hci_rp_read_local_version { __u8 lmp_ver; __le16 manufacturer; __le16 lmp_subver; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_LOCAL_COMMANDS 0x1002 struct hci_rp_read_local_commands { __u8 status; __u8 commands[64]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_LOCAL_FEATURES 0x1003 struct hci_rp_read_local_features { __u8 status; __u8 features[8]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_LOCAL_EXT_FEATURES 0x1004 struct hci_rp_read_local_ext_features { @@ -573,7 +576,7 @@ struct hci_rp_read_local_ext_features { __u8 page; __u8 max_page; __u8 features[8]; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_BUFFER_SIZE 0x1005 struct hci_rp_read_buffer_size { @@ -582,13 +585,13 @@ struct hci_rp_read_buffer_size { __u8 sco_mtu; __le16 acl_max_pkt; __le16 sco_max_pkt; -} __attribute__ ((packed)); +} __packed; #define HCI_OP_READ_BD_ADDR 0x1009 struct hci_rp_read_bd_addr { __u8 status; bdaddr_t bdaddr; -} __attribute__ ((packed)); +} __packed; /* ---- HCI Events ---- */ #define HCI_EV_INQUIRY_COMPLETE 0x01 @@ -601,7 +604,7 @@ struct inquiry_info { __u8 pscan_mode; __u8 dev_class[3]; __le16 clock_offset; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_CONN_COMPLETE 0x03 struct hci_ev_conn_complete { @@ -610,54 +613,54 @@ struct hci_ev_conn_complete { bdaddr_t bdaddr; __u8 link_type; __u8 encr_mode; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_CONN_REQUEST 0x04 struct hci_ev_conn_request { bdaddr_t bdaddr; __u8 dev_class[3]; __u8 link_type; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_DISCONN_COMPLETE 0x05 struct hci_ev_disconn_complete { __u8 status; __le16 handle; __u8 reason; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_AUTH_COMPLETE 0x06 struct hci_ev_auth_complete { __u8 status; __le16 handle; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_REMOTE_NAME 0x07 struct hci_ev_remote_name { __u8 status; bdaddr_t bdaddr; __u8 name[248]; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_ENCRYPT_CHANGE 0x08 struct hci_ev_encrypt_change { __u8 status; __le16 handle; __u8 encrypt; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09 struct hci_ev_change_link_key_complete { __u8 status; __le16 handle; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_REMOTE_FEATURES 0x0b struct hci_ev_remote_features { __u8 status; __le16 handle; __u8 features[8]; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_REMOTE_VERSION 0x0c struct hci_ev_remote_version { @@ -666,7 +669,7 @@ struct hci_ev_remote_version { __u8 lmp_ver; __le16 manufacturer; __le16 lmp_subver; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_QOS_SETUP_COMPLETE 0x0d struct hci_qos { @@ -675,38 +678,38 @@ struct hci_qos { __u32 peak_bandwidth; __u32 latency; __u32 delay_variation; -} __attribute__ ((packed)); +} __packed; struct hci_ev_qos_setup_complete { __u8 status; __le16 handle; struct hci_qos qos; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_CMD_COMPLETE 0x0e struct hci_ev_cmd_complete { __u8 ncmd; __le16 opcode; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_CMD_STATUS 0x0f struct hci_ev_cmd_status { __u8 status; __u8 ncmd; __le16 opcode; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_ROLE_CHANGE 0x12 struct hci_ev_role_change { __u8 status; bdaddr_t bdaddr; __u8 role; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_NUM_COMP_PKTS 0x13 struct hci_ev_num_comp_pkts { __u8 num_hndl; /* variable length part */ -} __attribute__ ((packed)); +} __packed; #define HCI_EV_MODE_CHANGE 0x14 struct hci_ev_mode_change { @@ -714,44 +717,44 @@ struct hci_ev_mode_change { __le16 handle; __u8 mode; __le16 interval; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_PIN_CODE_REQ 0x16 struct hci_ev_pin_code_req { bdaddr_t bdaddr; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_LINK_KEY_REQ 0x17 struct hci_ev_link_key_req { bdaddr_t bdaddr; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_LINK_KEY_NOTIFY 0x18 struct hci_ev_link_key_notify { bdaddr_t bdaddr; __u8 link_key[16]; __u8 key_type; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_CLOCK_OFFSET 0x1c struct hci_ev_clock_offset { __u8 status; __le16 handle; __le16 clock_offset; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_PKT_TYPE_CHANGE 0x1d struct hci_ev_pkt_type_change { __u8 status; __le16 handle; __le16 pkt_type; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_PSCAN_REP_MODE 0x20 struct hci_ev_pscan_rep_mode { bdaddr_t bdaddr; __u8 pscan_rep_mode; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 struct inquiry_info_with_rssi { @@ -761,7 +764,7 @@ struct inquiry_info_with_rssi { __u8 dev_class[3]; __le16 clock_offset; __s8 rssi; -} __attribute__ ((packed)); +} __packed; struct inquiry_info_with_rssi_and_pscan_mode { bdaddr_t bdaddr; __u8 pscan_rep_mode; @@ -770,7 +773,7 @@ struct inquiry_info_with_rssi_and_pscan_mode { __u8 dev_class[3]; __le16 clock_offset; __s8 rssi; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_REMOTE_EXT_FEATURES 0x23 struct hci_ev_remote_ext_features { @@ -779,7 +782,7 @@ struct hci_ev_remote_ext_features { __u8 page; __u8 max_page; __u8 features[8]; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_SYNC_CONN_COMPLETE 0x2c struct hci_ev_sync_conn_complete { @@ -792,7 +795,7 @@ struct hci_ev_sync_conn_complete { __le16 rx_pkt_len; __le16 tx_pkt_len; __u8 air_mode; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_SYNC_CONN_CHANGED 0x2d struct hci_ev_sync_conn_changed { @@ -802,7 +805,7 @@ struct hci_ev_sync_conn_changed { __u8 retrans_window; __le16 rx_pkt_len; __le16 tx_pkt_len; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_SNIFF_SUBRATE 0x2e struct hci_ev_sniff_subrate { @@ -812,7 +815,7 @@ struct hci_ev_sniff_subrate { __le16 max_rx_latency; __le16 max_remote_timeout; __le16 max_local_timeout; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f struct extended_inquiry_info { @@ -823,37 +826,37 @@ struct extended_inquiry_info { __le16 clock_offset; __s8 rssi; __u8 data[240]; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_IO_CAPA_REQUEST 0x31 struct hci_ev_io_capa_request { bdaddr_t bdaddr; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 struct hci_ev_simple_pair_complete { __u8 status; bdaddr_t bdaddr; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_REMOTE_HOST_FEATURES 0x3d struct hci_ev_remote_host_features { bdaddr_t bdaddr; __u8 features[8]; -} __attribute__ ((packed)); +} __packed; /* Internal events generated by Bluetooth stack */ #define HCI_EV_STACK_INTERNAL 0xfd struct hci_ev_stack_internal { __u16 type; __u8 data[0]; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_SI_DEVICE 0x01 struct hci_ev_si_device { __u16 event; __u16 dev_id; -} __attribute__ ((packed)); +} __packed; #define HCI_EV_SI_SECURITY 0x02 struct hci_ev_si_security { @@ -861,7 +864,7 @@ struct hci_ev_si_security { __u16 proto; __u16 subproto; __u8 incoming; -} __attribute__ ((packed)); +} __packed; /* ---- HCI Packet structures ---- */ #define HCI_COMMAND_HDR_SIZE 3 @@ -872,22 +875,22 @@ struct hci_ev_si_security { struct hci_command_hdr { __le16 opcode; /* OCF & OGF */ __u8 plen; -} __attribute__ ((packed)); +} __packed; struct hci_event_hdr { __u8 evt; __u8 plen; -} __attribute__ ((packed)); +} __packed; struct hci_acl_hdr { __le16 handle; /* Handle & Flags(PB, BC) */ __le16 dlen; -} __attribute__ ((packed)); +} __packed; struct hci_sco_hdr { __le16 handle; __u8 dlen; -} __attribute__ ((packed)); +} __packed; #ifdef __KERNEL__ #include <linux/skbuff.h> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index ce3c99e5fa25..4568b938ca35 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1,6 +1,6 @@ -/* +/* BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated + Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> @@ -12,13 +12,13 @@ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ @@ -62,6 +62,11 @@ struct hci_conn_hash { unsigned int sco_num; }; +struct bdaddr_list { + struct list_head list; + bdaddr_t bdaddr; +}; +#define NUM_REASSEMBLY 4 struct hci_dev { struct list_head list; spinlock_t lock; @@ -107,6 +112,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; @@ -116,7 +123,7 @@ struct hci_dev { struct sk_buff_head cmd_q; struct sk_buff *sent_cmd; - struct sk_buff *reassembly[3]; + struct sk_buff *reassembly[NUM_REASSEMBLY]; struct mutex req_lock; wait_queue_head_t req_wait_q; @@ -125,6 +132,7 @@ struct hci_dev { struct inquiry_cache inq_cache; struct hci_conn_hash conn_hash; + struct list_head blacklist; struct hci_dev_stats stat; @@ -248,6 +256,7 @@ enum { HCI_CONN_ENCRYPT_PEND, HCI_CONN_RSWITCH_PEND, HCI_CONN_MODE_CHANGE_PEND, + HCI_CONN_SCO_SETUP_PEND, }; static inline void hci_conn_hash_init(struct hci_dev *hdev) @@ -328,6 +337,7 @@ void hci_acl_connect(struct hci_conn *conn); void hci_acl_disconn(struct hci_conn *conn, __u8 reason); void hci_add_sco(struct hci_conn *conn, __u16 handle); void hci_setup_sync(struct hci_conn *conn, __u16 handle); +void hci_sco_setup(struct hci_conn *conn, __u8 status); struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); int hci_conn_del(struct hci_conn *conn); @@ -378,7 +388,7 @@ static inline void __hci_dev_put(struct hci_dev *d) } static inline void hci_dev_put(struct hci_dev *d) -{ +{ __hci_dev_put(d); module_put(d->owner); } @@ -422,10 +432,14 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); int hci_inquiry(void __user *arg); +struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); +int hci_blacklist_clear(struct hci_dev *hdev); + void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); int hci_recv_frame(struct sk_buff *skb); int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); +int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); int hci_register_sysfs(struct hci_dev *hdev); void hci_unregister_sysfs(struct hci_dev *hdev); @@ -636,8 +650,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..636724b203ee 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -1,6 +1,8 @@ /* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated + Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> + Copyright (C) 2010 Google Inc. Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> @@ -30,11 +32,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 +58,8 @@ struct l2cap_options { __u16 flush_to; __u8 mode; __u8 fcs; + __u8 max_tx; + __u16 txwin_size; }; #define L2CAP_CONNINFO 0x02 @@ -126,31 +131,31 @@ struct l2cap_conninfo { struct l2cap_hdr { __le16 len; __le16 cid; -} __attribute__ ((packed)); +} __packed; #define L2CAP_HDR_SIZE 4 struct l2cap_cmd_hdr { __u8 code; __u8 ident; __le16 len; -} __attribute__ ((packed)); +} __packed; #define L2CAP_CMD_HDR_SIZE 4 struct l2cap_cmd_rej { __le16 reason; -} __attribute__ ((packed)); +} __packed; struct l2cap_conn_req { __le16 psm; __le16 scid; -} __attribute__ ((packed)); +} __packed; struct l2cap_conn_rsp { __le16 dcid; __le16 scid; __le16 result; __le16 status; -} __attribute__ ((packed)); +} __packed; /* channel indentifier */ #define L2CAP_CID_SIGNALING 0x0001 @@ -174,14 +179,14 @@ struct l2cap_conf_req { __le16 dcid; __le16 flags; __u8 data[0]; -} __attribute__ ((packed)); +} __packed; struct l2cap_conf_rsp { __le16 scid; __le16 flags; __le16 result; __u8 data[0]; -} __attribute__ ((packed)); +} __packed; #define L2CAP_CONF_SUCCESS 0x0000 #define L2CAP_CONF_UNACCEPT 0x0001 @@ -192,7 +197,7 @@ struct l2cap_conf_opt { __u8 type; __u8 len; __u8 val[0]; -} __attribute__ ((packed)); +} __packed; #define L2CAP_CONF_OPT_SIZE 2 #define L2CAP_CONF_HINT 0x80 @@ -213,7 +218,7 @@ struct l2cap_conf_rfc { __le16 retrans_timeout; __le16 monitor_timeout; __le16 max_pdu_size; -} __attribute__ ((packed)); +} __packed; #define L2CAP_MODE_BASIC 0x00 #define L2CAP_MODE_RETRANS 0x01 @@ -224,22 +229,22 @@ struct l2cap_conf_rfc { struct l2cap_disconn_req { __le16 dcid; __le16 scid; -} __attribute__ ((packed)); +} __packed; struct l2cap_disconn_rsp { __le16 dcid; __le16 scid; -} __attribute__ ((packed)); +} __packed; struct l2cap_info_req { __le16 type; -} __attribute__ ((packed)); +} __packed; struct l2cap_info_rsp { __le16 type; __le16 result; __u8 data[0]; -} __attribute__ ((packed)); +} __packed; /* info type */ #define L2CAP_IT_CL_MTU 0x0001 @@ -284,6 +289,11 @@ struct l2cap_conn { struct l2cap_chan_list chan_list; }; +struct sock_del_list { + struct sock *sk; + struct list_head list; +}; + #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 #define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 #define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 @@ -292,6 +302,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 +331,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 +339,34 @@ 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; 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 +385,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/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 921d7b3c7f8d..a140847d622c 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -106,19 +106,19 @@ struct rfcomm_hdr { u8 addr; u8 ctrl; u8 len; // Actual size can be 2 bytes -} __attribute__ ((packed)); +} __packed; struct rfcomm_cmd { u8 addr; u8 ctrl; u8 len; u8 fcs; -} __attribute__ ((packed)); +} __packed; struct rfcomm_mcc { u8 type; u8 len; -} __attribute__ ((packed)); +} __packed; struct rfcomm_pn { u8 dlci; @@ -128,7 +128,7 @@ struct rfcomm_pn { __le16 mtu; u8 max_retrans; u8 credits; -} __attribute__ ((packed)); +} __packed; struct rfcomm_rpn { u8 dlci; @@ -138,17 +138,17 @@ struct rfcomm_rpn { u8 xon_char; u8 xoff_char; __le16 param_mask; -} __attribute__ ((packed)); +} __packed; struct rfcomm_rls { u8 dlci; u8 status; -} __attribute__ ((packed)); +} __packed; struct rfcomm_msc { u8 dlci; u8 v24_sig; -} __attribute__ ((packed)); +} __packed; /* ---- Core structures, flags etc ---- */ diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h new file mode 100644 index 000000000000..6da573c75d54 --- /dev/null +++ b/include/net/caif/caif_dev.h @@ -0,0 +1,107 @@ +/* + * 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. + * @ifindex: Link layer interface index used for this connection. + * @headroom: Head room needed by CAIF protocol. + * @tailroom: Tail room needed by CAIF protocol. + * + * 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 *conn_req, + struct cflayer *client_layer, int *ifindex, + int *headroom, int *tailroom); + +/** + * 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..c8b07a904e78 --- /dev/null +++ b/include/net/caif/caif_layer.h @@ -0,0 +1,277 @@ +/* + * 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_LAYER_NAME_SZ 16 + +/** + * 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/caif_spi.h b/include/net/caif/caif_spi.h new file mode 100644 index 000000000000..ce4570dff020 --- /dev/null +++ b/include/net/caif/caif_spi.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Author: Daniel Martensson / Daniel.Martensson@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CAIF_SPI_H_ +#define CAIF_SPI_H_ + +#include <net/caif/caif_device.h> + +#define SPI_CMD_WR 0x00 +#define SPI_CMD_RD 0x01 +#define SPI_CMD_EOT 0x02 +#define SPI_CMD_IND 0x04 + +#define SPI_DMA_BUF_LEN 8192 + +#define WL_SZ 2 /* 16 bits. */ +#define SPI_CMD_SZ 4 /* 32 bits. */ +#define SPI_IND_SZ 4 /* 32 bits. */ + +#define SPI_XFER 0 +#define SPI_SS_ON 1 +#define SPI_SS_OFF 2 +#define SPI_TERMINATE 3 + +/* Minimum time between different levels is 50 microseconds. */ +#define MIN_TRANSITION_TIME_USEC 50 + +/* Defines for calculating duration of SPI transfers for a particular + * number of bytes. + */ +#define SPI_MASTER_CLK_MHZ 13 +#define SPI_XFER_TIME_USEC(bytes, clk) (((bytes) * 8) / clk) + +/* Normally this should be aligned on the modem in order to benefit from full + * duplex transfers. However a size of 8188 provokes errors when running with + * the modem. These errors occur when packet sizes approaches 4 kB of data. + */ +#define CAIF_MAX_SPI_FRAME 4092 + +/* Maximum number of uplink CAIF frames that can reside in the same SPI frame. + * This number should correspond with the modem setting. The application side + * CAIF accepts any number of embedded downlink CAIF frames. + */ +#define CAIF_MAX_SPI_PKTS 9 + +/* Decides if SPI buffers should be prefilled with 0xFF pattern for easier + * debugging. Both TX and RX buffers will be filled before the transfer. + */ +#define CFSPI_DBG_PREFILL 0 + +/* Structure describing a SPI transfer. */ +struct cfspi_xfer { + u16 tx_dma_len; + u16 rx_dma_len; + void *va_tx; + dma_addr_t pa_tx; + void *va_rx; + dma_addr_t pa_rx; +}; + +/* Structure implemented by the SPI interface. */ +struct cfspi_ifc { + void (*ss_cb) (bool assert, struct cfspi_ifc *ifc); + void (*xfer_done_cb) (struct cfspi_ifc *ifc); + void *priv; +}; + +/* Structure implemented by SPI clients. */ +struct cfspi_dev { + int (*init_xfer) (struct cfspi_xfer *xfer, struct cfspi_dev *dev); + void (*sig_xfer) (bool xfer, struct cfspi_dev *dev); + struct cfspi_ifc *ifc; + char *name; + u32 clk_mhz; + void *priv; +}; + +/* Enumeration describing the CAIF SPI state. */ +enum cfspi_state { + CFSPI_STATE_WAITING = 0, + CFSPI_STATE_AWAKE, + CFSPI_STATE_FETCH_PKT, + CFSPI_STATE_GET_NEXT, + CFSPI_STATE_INIT_XFER, + CFSPI_STATE_WAIT_ACTIVE, + CFSPI_STATE_SIG_ACTIVE, + CFSPI_STATE_WAIT_XFER_DONE, + CFSPI_STATE_XFER_DONE, + CFSPI_STATE_WAIT_INACTIVE, + CFSPI_STATE_SIG_INACTIVE, + CFSPI_STATE_DELIVER_PKT, + CFSPI_STATE_MAX, +}; + +/* Structure implemented by SPI physical interfaces. */ +struct cfspi { + struct caif_dev_common cfdev; + struct net_device *ndev; + struct platform_device *pdev; + struct sk_buff_head qhead; + struct sk_buff_head chead; + u16 cmd; + u16 tx_cpck_len; + u16 tx_npck_len; + u16 rx_cpck_len; + u16 rx_npck_len; + struct cfspi_ifc ifc; + struct cfspi_xfer xfer; + struct cfspi_dev *dev; + unsigned long state; + struct work_struct work; + struct workqueue_struct *wq; + struct list_head list; + int flow_off_sent; + u32 qd_low_mark; + u32 qd_high_mark; + struct completion comp; + wait_queue_head_t wait; + spinlock_t lock; + bool flow_stop; +#ifdef CONFIG_DEBUG_FS + enum cfspi_state dbg_state; + u16 pcmd; + u16 tx_ppck_len; + u16 rx_ppck_len; + struct dentry *dbgfs_dir; + struct dentry *dbgfs_state; + struct dentry *dbgfs_frame; +#endif /* CONFIG_DEBUG_FS */ +}; + +extern int spi_frm_align; +extern int spi_up_head_align; +extern int spi_up_tail_align; +extern int spi_down_head_align; +extern int spi_down_tail_align; +extern struct platform_driver cfspi_spi_driver; + +void cfspi_dbg_state(struct cfspi *cfspi, int state); +int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len); +int cfspi_xmitlen(struct cfspi *cfspi); +int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len); +int cfspi_spi_remove(struct platform_device *pdev); +int cfspi_spi_probe(struct platform_device *pdev); +int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len); +int cfspi_xmitlen(struct cfspi *cfspi); +int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len); +void cfspi_xfer(struct work_struct *work); + +#endif /* CAIF_SPI_H_ */ diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h new file mode 100644 index 000000000000..bd646faffa47 --- /dev/null +++ b/include/net/caif/cfcnfg.h @@ -0,0 +1,148 @@ +/* + * 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 <linux/netdevice.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, + struct net_device *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. + * @ifindex: Link layer interface index used for this connection. + * @proto_head: Protocol head-space needed by CAIF protocol, + * excluding link layer. + * @proto_tail: Protocol tail-space needed by CAIF protocol, + * excluding link layer. + */ +int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, + struct cfctrl_link_param *param, + struct cflayer *adap_layer, + int *ifindex, + int *proto_head, + int *proto_tail); + +/** + * 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..b1fa87ee0992 --- /dev/null +++ b/include/net/caif/cfsrvl.h @@ -0,0 +1,63 @@ +/* + * 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; + bool supports_flowctrl; + void (*release)(struct kref *); + 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, + int mtu_size); +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 supports_flowctrl); +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); + + WARN_ON(!s->release); + if (s->release) + kref_put(&s->ref, s->release); +} + +#endif /* CFSRVL_H_ */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 3d134a1fb96b..2fd06c60ffbb 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -37,6 +37,7 @@ * * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7) + * @IEEE80211_NUM_BANDS: number of defined bands */ enum ieee80211_band { IEEE80211_BAND_2GHZ = NL80211_BAND_2GHZ, @@ -89,7 +90,7 @@ enum ieee80211_channel_flags { * @max_power: maximum transmission power (in dBm) * @beacon_found: helper to regulatory code to indicate when a beacon * has been found on this channel. Use regulatory_hint_found_beacon() - * to enable this, this is is useful only on 5 GHz band. + * to enable this, this is useful only on 5 GHz band. * @orig_mag: internal use * @orig_mpwr: internal use */ @@ -188,6 +189,7 @@ struct ieee80211_sta_ht_cap { * in this band. Must be sorted to give a valid "supported * rates" IE, i.e. CCK rates first, then OFDM. * @n_bitrates: Number of bitrates in @bitrates + * @ht_cap: HT capabilities in this band */ struct ieee80211_supported_band { struct ieee80211_channel *channels; @@ -225,6 +227,7 @@ struct vif_params { * @seq: sequence counter (IV/PN) for TKIP and CCMP keys, only used * with the get_key() callback, must be in little endian, * length given by @seq_len. + * @seq_len: length of @seq. */ struct key_params { u8 *key; @@ -237,6 +240,8 @@ struct key_params { /** * enum survey_info_flags - survey information flags * + * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in + * * Used by the driver to indicate which info in &struct survey_info * it has filled in during the get_survey(). */ @@ -247,13 +252,13 @@ enum survey_info_flags { /** * struct survey_info - channel survey response * - * Used by dump_survey() to report back per-channel survey information. - * * @channel: the channel this survey record reports, mandatory * @filled: bitflag of flags from &enum survey_info_flags * @noise: channel noise in dBm. This and all following fields are * optional * + * Used by dump_survey() to report back per-channel survey information. + * * This structure can later be expanded with things like * channel duty cycle etc. */ @@ -288,7 +293,7 @@ struct beacon_parameters { * * @PLINK_ACTION_INVALID: action 0 is reserved * @PLINK_ACTION_OPEN: start mesh peer link establishment - * @PLINK_ACTION_BLOCL: block traffic from this mesh peer + * @PLINK_ACTION_BLOCK: block traffic from this mesh peer */ enum plink_actions { PLINK_ACTION_INVALID, @@ -311,6 +316,8 @@ enum plink_actions { * (bitmask of BIT(NL80211_STA_FLAG_...)) * @listen_interval: listen interval or -1 for no change * @aid: AID or zero for no change + * @plink_action: plink action to take + * @ht_capa: HT capabilities of station */ struct station_parameters { u8 *supported_rates; @@ -448,13 +455,13 @@ enum monitor_flags { * Used by the driver to indicate which info in &struct mpath_info it has filled * in during get_station() or dump_station(). * - * MPATH_INFO_FRAME_QLEN: @frame_qlen filled - * MPATH_INFO_SN: @sn filled - * MPATH_INFO_METRIC: @metric filled - * MPATH_INFO_EXPTIME: @exptime filled - * MPATH_INFO_DISCOVERY_TIMEOUT: @discovery_timeout filled - * MPATH_INFO_DISCOVERY_RETRIES: @discovery_retries filled - * MPATH_INFO_FLAGS: @flags filled + * @MPATH_INFO_FRAME_QLEN: @frame_qlen filled + * @MPATH_INFO_SN: @sn filled + * @MPATH_INFO_METRIC: @metric filled + * @MPATH_INFO_EXPTIME: @exptime filled + * @MPATH_INFO_DISCOVERY_TIMEOUT: @discovery_timeout filled + * @MPATH_INFO_DISCOVERY_RETRIES: @discovery_retries filled + * @MPATH_INFO_FLAGS: @flags filled */ enum mpath_info_flags { MPATH_INFO_FRAME_QLEN = BIT(0), @@ -511,6 +518,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 +526,7 @@ struct bss_parameters { int use_short_slot_time; u8 *basic_rates; u8 basic_rates_len; + int ap_isolate; }; struct mesh_config { @@ -585,6 +594,7 @@ struct cfg80211_ssid { * @ie_len: length of ie in octets * @wiphy: the wiphy this was for * @dev: the interface + * @aborted: (internal) scan request was notified as aborted */ struct cfg80211_scan_request { struct cfg80211_ssid *ssids; @@ -621,6 +631,7 @@ enum cfg80211_signal_type { * This structure describes a BSS (which may also be a mesh network) * for use in scan results and similar. * + * @channel: channel this BSS is on * @bssid: BSSID of the BSS * @tsf: timestamp of last received update * @beacon_interval: the beacon interval as from the frame @@ -704,6 +715,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 +727,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 +760,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 +781,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; }; /** @@ -788,6 +810,7 @@ struct cfg80211_disassoc_request { * @beacon_interval: beacon interval to use * @privacy: this is a protected network, keys will be configured * after joining + * @basic_rates: bitmap of basic rates to use when creating the IBSS */ struct cfg80211_ibss_params { u8 *ssid; @@ -796,6 +819,7 @@ struct cfg80211_ibss_params { u8 *ie; u8 ssid_len, ie_len; u16 beacon_interval; + u32 basic_rates; bool channel_fixed; bool privacy; }; @@ -813,8 +837,8 @@ struct cfg80211_ibss_params { * @ssid: SSID * @ssid_len: Length of ssid in octets * @auth_type: Authentication type (algorithm) - * @assoc_ie: IEs for association request - * @assoc_ie_len: Length of assoc_ie in octets + * @ie: IEs for association request + * @ie_len: Length of assoc_ie in octets * @privacy: indicates whether privacy-enabled APs should be used * @crypto: crypto settings * @key_len: length of WEP key for shared key authentication @@ -837,10 +861,11 @@ struct cfg80211_connect_params { /** * enum wiphy_params_flags - set_wiphy_params bitfield values - * WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed - * WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed - * WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed - * WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed + * @WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed + * @WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed + * @WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed + * @WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed + * @WIPHY_PARAM_COVERAGE_CLASS: coverage class changed */ enum wiphy_params_flags { WIPHY_PARAM_RETRY_SHORT = 1 << 0, @@ -850,19 +875,6 @@ enum wiphy_params_flags { WIPHY_PARAM_COVERAGE_CLASS = 1 << 4, }; -/** - * enum tx_power_setting - TX power adjustment - * - * @TX_POWER_AUTOMATIC: the dbm parameter is ignored - * @TX_POWER_LIMITED: limit TX power by the dbm parameter - * @TX_POWER_FIXED: fix TX power to the dbm parameter - */ -enum tx_power_setting { - TX_POWER_AUTOMATIC, - TX_POWER_LIMITED, - TX_POWER_FIXED, -}; - /* * cfg80211_bitrate_mask - masks for bitrate control */ @@ -936,10 +948,16 @@ struct cfg80211_pmksa { * @del_beacon: Remove beacon configuration and stop sending the beacon. * * @add_station: Add a new station. - * * @del_station: Remove a station; @mac may be NULL to remove all stations. - * * @change_station: Modify a given station. + * @get_station: get station information for the station identified by @mac + * @dump_station: dump station callback -- resume dump at index @idx + * + * @add_mpath: add a fixed mesh path + * @del_mpath: delete a given mesh path + * @change_mpath: change a given mesh path + * @get_mpath: get a mesh path for the given parameters + * @dump_mpath: dump mesh path callback -- resume dump at index @idx * * @get_mesh_params: Put the current mesh parameters into *params * @@ -947,13 +965,15 @@ struct cfg80211_pmksa { * The mask is a bitfield which tells us which parameters to * set, and which to leave alone. * - * @set_mesh_cfg: set mesh parameters (by now, just mesh id) - * * @change_bss: Modify parameters for a given BSS. * * @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(). @@ -985,6 +1005,8 @@ struct cfg80211_pmksa { * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful * + * @set_wds_peer: set the WDS peer for a WDS interface + * * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting * functions to adjust rfkill hw state * @@ -1002,11 +1024,16 @@ struct cfg80211_pmksa { * * @testmode_cmd: run a test mode command * + * @set_bitrate_mask: set the bitrate mask configuration + * * @set_pmksa: Cache a PMKID for a BSSID. This is mostly useful for fullmac * devices running firmwares capable of generating the (re) association * 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 +1106,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); @@ -1109,7 +1136,7 @@ struct cfg80211_ops { int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); int (*set_tx_power)(struct wiphy *wiphy, - enum tx_power_setting type, int dbm); + enum nl80211_tx_power_setting type, int mbm); int (*get_tx_power)(struct wiphy *wiphy, int *dbm); int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, @@ -1148,10 +1175,15 @@ struct cfg80211_ops { int (*action)(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type, + bool channel_type_valid, const u8 *buf, size_t len, u64 *cookie); 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); }; /* @@ -1206,8 +1238,6 @@ struct mac_address { /** * struct wiphy - wireless hardware description - * @idx: the wiphy index assigned to this item - * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name> * @reg_notifier: the driver's regulatory notification callback * @regd: the driver's regulatory domain, if one was requested via * the regulatory_hint() API. This can be used by the driver @@ -1221,7 +1251,7 @@ struct mac_address { * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold); * -1 = fragmentation disabled, only odd values >= 256 used * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled - * @net: the network namespace this wiphy currently lives in + * @_net: the network namespace this wiphy currently lives in * @perm_addr: permanent MAC address of this device * @addr_mask: If the device supports multiple MAC addresses by masking, * set this to a mask with variable bits set to 1, e.g. if the last @@ -1234,6 +1264,28 @@ struct mac_address { * by default for perm_addr. In this case, the mask should be set to * all-zeroes. In this case it is assumed that the device can handle * the same number of arbitrary MAC addresses. + * @debugfsdir: debugfs directory used for this wiphy, will be renamed + * automatically on wiphy renames + * @dev: (virtual) struct device for this wiphy + * @wext: wireless extension handlers + * @priv: driver private data (sized according to wiphy_new() parameter) + * @interface_modes: bitmask of interfaces types valid for this wiphy, + * must be set by driver + * @flags: wiphy flags, see &enum wiphy_flags + * @bss_priv_size: each BSS struct has private data allocated with it, + * this variable determines its size + * @max_scan_ssids: maximum number of SSIDs the device can scan for in + * any given scan + * @max_scan_ie_len: maximum length of user-controlled IEs device can + * add to probe request frames transmitted during a scan, must not + * include fixed IEs like supported rates + * @coverage_class: current coverage class + * @fw_version: firmware version for ethtool reporting + * @hw_version: hardware version for ethtool reporting + * @max_num_pmkids: maximum number of PMKIDs supported by device + * @privid: a pointer that drivers can use to identify if an arbitrary + * wiphy is theirs, e.g. in global notifiers + * @bands: information about bands/channels supported by this device */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -1306,27 +1358,16 @@ struct wiphy { char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); }; -#ifdef CONFIG_NET_NS static inline struct net *wiphy_net(struct wiphy *wiphy) { - return wiphy->_net; + return read_pnet(&wiphy->_net); } static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net) { - wiphy->_net = net; -} -#else -static inline struct net *wiphy_net(struct wiphy *wiphy) -{ - return &init_net; + write_pnet(&wiphy->_net, net); } -static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net) -{ -} -#endif - /** * wiphy_priv - return priv from wiphy * @@ -1375,7 +1416,7 @@ static inline struct device *wiphy_dev(struct wiphy *wiphy) * * @wiphy: The wiphy whose name to return */ -static inline const char *wiphy_name(struct wiphy *wiphy) +static inline const char *wiphy_name(const struct wiphy *wiphy) { return dev_name(&wiphy->dev); } @@ -1441,17 +1482,20 @@ 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 * @wext: (private) Used by the internal wireless extensions compat code - * @wext_bssid: (private) Used by the internal wireless extensions compat code * @use_4addr: indicates 4addr mode is used on this interface, must be * set by driver (if supported) on add_interface BEFORE registering the * netdev and may otherwise be used by driver read-only, will be update * by cfg80211 on change_interface * @action_registrations: list of registrations for action frames * @action_registrations_lock: lock for the list + * @mtx: mutex used to lock data in this struct + * @cleanup_work: work struct used for cleanup that can't be done directly */ struct wireless_dev { struct wiphy *wiphy; @@ -1487,6 +1531,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; @@ -1524,11 +1569,13 @@ static inline void *wdev_priv(struct wireless_dev *wdev) /** * ieee80211_channel_to_frequency - convert channel number to frequency + * @chan: channel number */ extern int ieee80211_channel_to_frequency(int chan); /** * ieee80211_frequency_to_channel - convert frequency to channel number + * @freq: center frequency */ extern int ieee80211_frequency_to_channel(int freq); @@ -1543,6 +1590,8 @@ extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy, int freq); /** * ieee80211_get_channel - get channel struct from wiphy for specified frequency + * @wiphy: the struct wiphy to get the channel for + * @freq: the center frequency of the channel */ static inline struct ieee80211_channel * ieee80211_get_channel(struct wiphy *wiphy, int freq) @@ -1603,9 +1652,6 @@ struct ieee80211_radiotap_vendor_namespaces { * @is_radiotap_ns: indicates whether the current namespace is the default * radiotap namespace or not * - * @overrides: override standard radiotap fields - * @n_overrides: number of overrides - * * @_rtheader: pointer to the radiotap header we are walking through * @_max_length: length of radiotap header in cpu byte ordering * @_arg_index: next argument index @@ -1627,7 +1673,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; @@ -1906,6 +1952,10 @@ int cfg80211_wext_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra); +int cfg80211_wext_siwpmksa(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra); + /* * callbacks for asynchronous cfg80211 methods, notification * functions and BSS handling helpers @@ -1921,10 +1971,12 @@ int cfg80211_wext_giwap(struct net_device *dev, void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted); /** - * cfg80211_inform_bss - inform cfg80211 of a new BSS + * cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame * * @wiphy: the wiphy reporting the BSS - * @bss: the found BSS + * @channel: The channel the frame was received on + * @mgmt: the management frame (probe response or beacon) + * @len: length of the management frame * @signal: the signal strength, type depends on the wiphy's signal_type * @gfp: context flags * @@ -1937,6 +1989,23 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, struct ieee80211_mgmt *mgmt, size_t len, s32 signal, gfp_t gfp); +/** + * cfg80211_inform_bss - inform cfg80211 of a new BSS + * + * @wiphy: the wiphy reporting the BSS + * @channel: The channel the frame was received on + * @bssid: the BSSID of the BSS + * @timestamp: the TSF timestamp sent by the peer + * @capability: the capability field sent by the peer + * @beacon_interval: the beacon interval announced by the peer + * @ie: additional IEs sent by the peer + * @ielen: length of the additional IEs + * @signal: the signal strength, type depends on the wiphy's signal_type + * @gfp: context flags + * + * This informs cfg80211 that BSS information was found and + * the BSS should be updated/added. + */ struct cfg80211_bss* cfg80211_inform_bss(struct wiphy *wiphy, struct ieee80211_channel *channel, @@ -2337,4 +2406,81 @@ 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); + +#ifdef __KERNEL__ + +/* Logging, debugging and troubleshooting/diagnostic helpers. */ + +/* wiphy_printk helpers, similar to dev_printk */ + +#define wiphy_printk(level, wiphy, format, args...) \ + printk(level "%s: " format, wiphy_name(wiphy), ##args) +#define wiphy_emerg(wiphy, format, args...) \ + wiphy_printk(KERN_EMERG, wiphy, format, ##args) +#define wiphy_alert(wiphy, format, args...) \ + wiphy_printk(KERN_ALERT, wiphy, format, ##args) +#define wiphy_crit(wiphy, format, args...) \ + wiphy_printk(KERN_CRIT, wiphy, format, ##args) +#define wiphy_err(wiphy, format, args...) \ + wiphy_printk(KERN_ERR, wiphy, format, ##args) +#define wiphy_warn(wiphy, format, args...) \ + wiphy_printk(KERN_WARNING, wiphy, format, ##args) +#define wiphy_notice(wiphy, format, args...) \ + wiphy_printk(KERN_NOTICE, wiphy, format, ##args) +#define wiphy_info(wiphy, format, args...) \ + wiphy_printk(KERN_INFO, wiphy, format, ##args) + +int wiphy_debug(const struct wiphy *wiphy, const char *format, ...) + __attribute__ ((format (printf, 2, 3))); + +#if defined(DEBUG) +#define wiphy_dbg(wiphy, format, args...) \ + wiphy_printk(KERN_DEBUG, wiphy, format, ##args) +#elif defined(CONFIG_DYNAMIC_DEBUG) +#define wiphy_dbg(wiphy, format, args...) \ + dynamic_pr_debug("%s: " format, wiphy_name(wiphy), ##args) +#else +#define wiphy_dbg(wiphy, format, args...) \ +({ \ + if (0) \ + wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ + 0; \ +}) +#endif + +#if defined(VERBOSE_DEBUG) +#define wiphy_vdbg wiphy_dbg +#else + +#define wiphy_vdbg(wiphy, format, args...) \ +({ \ + if (0) \ + wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ + 0; \ +}) +#endif + +/* + * wiphy_WARN() acts like wiphy_printk(), but with the key difference + * of using a WARN/WARN_ON to get the message out, including the + * file/line information and a backtrace. + */ +#define wiphy_WARN(wiphy, format, args...) \ + WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args); + +#endif + #endif /* __NET_CFG80211_H */ diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h new file mode 100644 index 000000000000..726cc3536409 --- /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 = 0; + + 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_dev.h b/include/net/dn_dev.h index 511a459ec10f..0916bbf3bdff 100644 --- a/include/net/dn_dev.h +++ b/include/net/dn_dev.h @@ -101,7 +101,7 @@ struct dn_short_packet { __le16 dstnode; __le16 srcnode; __u8 forward; -} __attribute__((packed)); +} __packed; struct dn_long_packet { __u8 msgflg; @@ -115,7 +115,7 @@ struct dn_long_packet { __u8 visit_ct; __u8 s_class; __u8 pt; -} __attribute__((packed)); +} __packed; /*------------------------- DRP - Routing messages ---------------------*/ @@ -132,7 +132,7 @@ struct endnode_hello_message { __u8 mpd; __u8 datalen; __u8 data[2]; -} __attribute__((packed)); +} __packed; struct rtnode_hello_message { __u8 msgflg; @@ -144,7 +144,7 @@ struct rtnode_hello_message { __u8 area; __le16 timer; __u8 mpd; -} __attribute__((packed)); +} __packed; extern void dn_dev_init(void); 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/dn_nsp.h b/include/net/dn_nsp.h index 17d43d2db5ec..e43a2893f132 100644 --- a/include/net/dn_nsp.h +++ b/include/net/dn_nsp.h @@ -74,18 +74,18 @@ struct nsp_data_seg_msg { __u8 msgflg; __le16 dstaddr; __le16 srcaddr; -} __attribute__((packed)); +} __packed; struct nsp_data_opt_msg { __le16 acknum; __le16 segnum; __le16 lsflgs; -} __attribute__((packed)); +} __packed; struct nsp_data_opt_msg1 { __le16 acknum; __le16 segnum; -} __attribute__((packed)); +} __packed; /* Acknowledgment Message (data/other data) */ @@ -94,13 +94,13 @@ struct nsp_data_ack_msg { __le16 dstaddr; __le16 srcaddr; __le16 acknum; -} __attribute__((packed)); +} __packed; /* Connect Acknowledgment Message */ struct nsp_conn_ack_msg { __u8 msgflg; __le16 dstaddr; -} __attribute__((packed)); +} __packed; /* Connect Initiate/Retransmit Initiate/Connect Confirm */ @@ -117,7 +117,7 @@ struct nsp_conn_init_msg { #define NSP_FC_MASK 0x0c /* FC type mask */ __u8 info; __le16 segsize; -} __attribute__((packed)); +} __packed; /* Disconnect Initiate/Disconnect Confirm */ struct nsp_disconn_init_msg { @@ -125,7 +125,7 @@ struct nsp_disconn_init_msg { __le16 dstaddr; __le16 srcaddr; __le16 reason; -} __attribute__((packed)); +} __packed; @@ -135,7 +135,7 @@ struct srcobj_fmt { __le16 grpcode; __le16 usrcode; __u8 dlen; -} __attribute__((packed)); +} __packed; /* * A collection of functions for manipulating the sequence diff --git a/include/net/dn_route.h b/include/net/dn_route.h index 60c9f22d8694..ccadab3aa3f6 100644 --- a/include/net/dn_route.h +++ b/include/net/dn_route.h @@ -65,9 +65,7 @@ extern void dn_rt_cache_flush(int delay); * packets to the originating host. */ struct dn_route { - union { - struct dst_entry dst; - } u; + struct dst_entry dst; struct flowi fl; diff --git a/include/net/dst.h b/include/net/dst.h index ce078cda6b74..81d1413a8701 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,22 +183,78 @@ 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 * Linux networking. Thus, destinations are stackable. */ -static inline struct dst_entry *dst_pop(struct dst_entry *dst) +static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb) { - struct dst_entry *child = dst_clone(dst->child); + struct dst_entry *child = skb_dst(skb)->child; - dst_release(dst); + skb_dst_drop(skb); return child; } @@ -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/genetlink.h b/include/net/genetlink.h index eb551baafc04..f7dcd2c70412 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -68,26 +68,15 @@ struct genl_info { #endif }; -#ifdef CONFIG_NET_NS static inline struct net *genl_info_net(struct genl_info *info) { - return info->_net; + return read_pnet(&info->_net); } static inline void genl_info_net_set(struct genl_info *info, struct net *net) { - info->_net = net; + write_pnet(&info->_net, net); } -#else -static inline struct net *genl_info_net(struct genl_info *info) -{ - return &init_net; -} - -static inline void genl_info_net_set(struct genl_info *info, struct net *net) -{ -} -#endif /** * struct genl_ops - generic netlink operations 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_common.h b/include/net/inet_common.h index 18c773286b91..22fac9892b16 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h @@ -1,8 +1,8 @@ #ifndef _INET_COMMON_H #define _INET_COMMON_H -extern const struct proto_ops inet_stream_ops; -extern const struct proto_ops inet_dgram_ops; +extern const struct proto_ops inet_stream_ops; +extern const struct proto_ops inet_dgram_ops; /* * INET4 prototypes used by INET6 @@ -13,37 +13,28 @@ struct sock; struct sockaddr; struct socket; -extern int inet_release(struct socket *sock); -extern int inet_stream_connect(struct socket *sock, - struct sockaddr * uaddr, - int addr_len, int flags); -extern int inet_dgram_connect(struct socket *sock, - struct sockaddr * uaddr, - int addr_len, int flags); -extern int inet_accept(struct socket *sock, - struct socket *newsock, int flags); -extern int inet_sendmsg(struct kiocb *iocb, - struct socket *sock, - struct msghdr *msg, - size_t size); -extern int inet_shutdown(struct socket *sock, int how); -extern int inet_listen(struct socket *sock, int backlog); - -extern void inet_sock_destruct(struct sock *sk); - -extern int inet_bind(struct socket *sock, - struct sockaddr *uaddr, int addr_len); -extern int inet_getname(struct socket *sock, - struct sockaddr *uaddr, - int *uaddr_len, int peer); -extern int inet_ioctl(struct socket *sock, - unsigned int cmd, unsigned long arg); - -extern int inet_ctl_sock_create(struct sock **sk, - unsigned short family, - unsigned short type, - unsigned char protocol, - struct net *net); +extern int inet_release(struct socket *sock); +extern int inet_stream_connect(struct socket *sock, struct sockaddr * uaddr, + int addr_len, int flags); +extern int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr, + int addr_len, int flags); +extern int inet_accept(struct socket *sock, struct socket *newsock, int flags); +extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t size); +extern ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, + size_t size, int flags); +extern int inet_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t size, int flags); +extern int inet_shutdown(struct socket *sock, int how); +extern int inet_listen(struct socket *sock, int backlog); +extern void inet_sock_destruct(struct sock *sk); +extern int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len); +extern int inet_getname(struct socket *sock, struct sockaddr *uaddr, + int *uaddr_len, int peer); +extern int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); +extern int inet_ctl_sock_create(struct sock **sk, unsigned short family, + unsigned short type, unsigned char protocol, + struct net *net); static inline void inet_ctl_sock_destroy(struct sock *sk) { @@ -51,5 +42,3 @@ static inline void inet_ctl_sock_destroy(struct sock *sk) } #endif - - 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_frag.h b/include/net/inet_frag.h index 39f2dc943908..16ff29a7bb30 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h @@ -20,6 +20,7 @@ struct inet_frag_queue { atomic_t refcnt; struct timer_list timer; /* when will this queue expire? */ struct sk_buff *fragments; /* list of received fragments */ + struct sk_buff *fragments_tail; ktime_t stamp; int len; /* total length of orig datagram */ int meat; diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 83fd34437cf1..1989cfd7405f 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> @@ -136,7 +137,8 @@ struct inet_sock { hdrincl:1, mc_loop:1, transparent:1, - mc_all:1; + mc_all:1, + nodefrag:1; int mc_index; __be32 mc_addr; struct ip_mc_socklist *mc_list; 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/inetpeer.h b/include/net/inetpeer.h index 87b1df0d4d8c..417d0c894f29 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -22,10 +22,21 @@ struct inet_peer { __u32 dtime; /* the time of last use of not * referenced entries */ atomic_t refcnt; - atomic_t rid; /* Frag reception counter */ - atomic_t ip_id_count; /* IP ID for the next packet */ - __u32 tcp_ts; - __u32 tcp_ts_stamp; + /* + * Once inet_peer is queued for deletion (refcnt == -1), following fields + * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp + * We can share memory with rcu_head to keep inet_peer small + * (less then 64 bytes) + */ + union { + struct { + atomic_t rid; /* Frag reception counter */ + atomic_t ip_id_count; /* IP ID for the next packet */ + __u32 tcp_ts; + __u32 tcp_ts_stamp; + }; + struct rcu_head rcu; + }; }; void inet_initpeers(void) __init; @@ -36,10 +47,21 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create); /* can be called from BH context or outside */ extern void inet_putpeer(struct inet_peer *p); +/* + * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, + * tcp_ts_stamp if no refcount is taken on inet_peer + */ +static inline void inet_peer_refcheck(const struct inet_peer *p) +{ + WARN_ON_ONCE(atomic_read(&p->refcnt) <= 0); +} + + /* can be called with or without local BH being disabled */ static inline __u16 inet_getid(struct inet_peer *p, int more) { more++; + inet_peer_refcheck(p); return atomic_add_return(more, &p->ip_id_count) - more; } diff --git a/include/net/ip.h b/include/net/ip.h index 503994a38ed1..890f9725d681 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -61,11 +61,14 @@ struct ipcm_cookie { struct ip_ra_chain { struct ip_ra_chain *next; struct sock *sk; - void (*destructor)(struct sock *); + union { + void (*destructor)(struct sock *); + struct sock *saved_sk; + }; + struct rcu_head rcu; }; extern struct ip_ra_chain *ip_ra_chain; -extern rwlock_t ip_ra_lock; /* IP flags. */ #define IP_CE 0x8000 /* Flag: "Congestion" */ @@ -101,7 +104,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, @@ -162,12 +165,12 @@ struct ipv4_config { }; extern struct ipv4_config ipv4_config; -#define IP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.ip_statistics, field) -#define IP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.ip_statistics, field) -#define IP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.ip_statistics, field, val) -#define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS_BH((net)->mib.ip_statistics, field, val) -#define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS((net)->mib.ip_statistics, field, val) -#define IP_UPD_PO_STATS_BH(net, field, val) SNMP_UPD_PO_STATS_BH((net)->mib.ip_statistics, field, val) +#define IP_INC_STATS(net, field) SNMP_INC_STATS64((net)->mib.ip_statistics, field) +#define IP_INC_STATS_BH(net, field) SNMP_INC_STATS64_BH((net)->mib.ip_statistics, field) +#define IP_ADD_STATS(net, field, val) SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val) +#define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS64_BH((net)->mib.ip_statistics, field, val) +#define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val) +#define IP_UPD_PO_STATS_BH(net, field, val) SNMP_UPD_PO_STATS64_BH((net)->mib.ip_statistics, field, val) #define NET_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.net_statistics, field) #define NET_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.net_statistics, field) #define NET_INC_STATS_USER(net, field) SNMP_INC_STATS_USER((net)->mib.net_statistics, field) @@ -175,7 +178,15 @@ extern struct ipv4_config ipv4_config; #define NET_ADD_STATS_USER(net, field, adnd) SNMP_ADD_STATS_USER((net)->mib.net_statistics, field, adnd) extern unsigned long snmp_fold_field(void __percpu *mib[], int offt); -extern int snmp_mib_init(void __percpu *ptr[2], size_t mibsize); +#if BITS_PER_LONG==32 +extern u64 snmp_fold_field64(void __percpu *mib[], int offt, size_t sync_off); +#else +static inline u64 snmp_fold_field64(void __percpu *mib[], int offt, size_t syncp_off) +{ + return snmp_fold_field(mib, offt); +} +#endif +extern int snmp_mib_init(void __percpu *ptr[2], size_t mibsize, size_t align); extern void snmp_mib_free(void __percpu *ptr[2]); extern struct local_ports { @@ -184,6 +195,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 +369,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 +410,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..062a823d311c 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -84,38 +84,39 @@ struct rt6key { struct fib6_table; struct rt6_info { - union { - struct dst_entry dst; - } u; + struct dst_entry dst; - struct inet6_dev *rt6i_idev; - -#define rt6i_dev u.dst.dev -#define rt6i_nexthop u.dst.neighbour -#define rt6i_expires u.dst.expires +#define rt6i_dev dst.dev +#define rt6i_nexthop dst.neighbour +#define rt6i_expires 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/ip6_tunnel.h b/include/net/ip6_tunnel.h index fbf9d1cda27b..fc94ec568a50 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -27,6 +27,6 @@ struct ipv6_tlv_tnl_enc_lim { __u8 type; /* type-code for option */ __u8 length; /* option length */ __u8 encap_limit; /* tunnel encapsulation limit */ -} __attribute__ ((packed)); +} __packed; #endif diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index fe82b1e10a29..a4747a0f7303 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -632,10 +632,22 @@ extern struct ip_vs_conn *ip_vs_ct_in_get (int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, const union nf_inet_addr *d_addr, __be16 d_port); +struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, + struct ip_vs_protocol *pp, + const struct ip_vs_iphdr *iph, + unsigned int proto_off, + int inverse); + extern struct ip_vs_conn *ip_vs_conn_out_get (int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, const union nf_inet_addr *d_addr, __be16 d_port); +struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, + struct ip_vs_protocol *pp, + const struct ip_vs_iphdr *iph, + unsigned int proto_off, + int inverse); + /* put back the conn without restarting its timer */ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp) { @@ -736,8 +748,6 @@ extern void ip_vs_app_inc_put(struct ip_vs_app *inc); extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff *skb); extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb); -extern int ip_vs_skb_replace(struct sk_buff *skb, gfp_t pri, - char *o_buf, int o_len, char *n_buf, int n_len); extern int ip_vs_app_init(void); extern void ip_vs_app_cleanup(void); diff --git a/include/net/ipip.h b/include/net/ipip.h index 11e8513d2d07..65caea8b414f 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -50,7 +50,7 @@ struct ip_tunnel_prl_entry { int pkt_len = skb->len - skb_transport_offset(skb); \ \ skb->ip_summed = CHECKSUM_NONE; \ - ip_select_ident(iph, &rt->u.dst, NULL); \ + ip_select_ident(iph, &rt->dst, NULL); \ \ err = ip_local_out(skb); \ if (likely(net_xmit_eval(err) == 0)) { \ diff --git a/include/net/ipv6.h b/include/net/ipv6.h index e72fb10ce573..1f8412410998 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -136,17 +136,17 @@ extern struct ctl_path net_ipv6_ctl_path[]; /* MIBs */ #define IP6_INC_STATS(net, idev,field) \ - _DEVINC(net, ipv6, , idev, field) + _DEVINC(net, ipv6, 64, idev, field) #define IP6_INC_STATS_BH(net, idev,field) \ - _DEVINC(net, ipv6, _BH, idev, field) + _DEVINC(net, ipv6, 64_BH, idev, field) #define IP6_ADD_STATS(net, idev,field,val) \ - _DEVADD(net, ipv6, , idev, field, val) + _DEVADD(net, ipv6, 64, idev, field, val) #define IP6_ADD_STATS_BH(net, idev,field,val) \ - _DEVADD(net, ipv6, _BH, idev, field, val) + _DEVADD(net, ipv6, 64_BH, idev, field, val) #define IP6_UPD_PO_STATS(net, idev,field,val) \ - _DEVUPD(net, ipv6, , idev, field, val) + _DEVUPD(net, ipv6, 64, idev, field, val) #define IP6_UPD_PO_STATS_BH(net, idev,field,val) \ - _DEVUPD(net, ipv6, _BH, idev, field, val) + _DEVUPD(net, ipv6, 64_BH, idev, field, val) #define ICMP6_INC_STATS(net, idev, field) \ _DEVINC(net, icmpv6, , idev, field) #define ICMP6_INC_STATS_BH(net, idev, field) \ @@ -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); @@ -551,6 +551,10 @@ extern int ipv6_ext_hdr(u8 nexthdr); extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); +extern struct in6_addr *fl6_update_dst(struct flowi *fl, + const struct ipv6_txoptions *opt, + struct in6_addr *orig); + /* * socket options (ipv6_sockglue.c) */ @@ -578,9 +582,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/ipx.h b/include/net/ipx.h index ef51a668ba19..05d7e4a88b49 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h @@ -27,9 +27,9 @@ struct ipx_address { #define IPX_MAX_PPROP_HOPS 8 struct ipxhdr { - __be16 ipx_checksum __attribute__ ((packed)); + __be16 ipx_checksum __packed; #define IPX_NO_CHECKSUM cpu_to_be16(0xFFFF) - __be16 ipx_pktsize __attribute__ ((packed)); + __be16 ipx_pktsize __packed; __u8 ipx_tctrl; __u8 ipx_type; #define IPX_TYPE_UNKNOWN 0x00 @@ -38,8 +38,8 @@ struct ipxhdr { #define IPX_TYPE_SPX 0x05 /* SPX protocol */ #define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */ #define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast */ - struct ipx_address ipx_dest __attribute__ ((packed)); - struct ipx_address ipx_source __attribute__ ((packed)); + struct ipx_address ipx_dest __packed; + struct ipx_address ipx_source __packed; }; static __inline__ struct ipxhdr *ipx_hdr(struct sk_buff *skb) diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h index 7e582061b230..3bed61d379a8 100644 --- a/include/net/irda/irda.h +++ b/include/net/irda/irda.h @@ -53,10 +53,6 @@ typedef __u32 magic_t; #ifndef IRDA_ALIGN # define IRDA_ALIGN __attribute__((aligned)) #endif -#ifndef IRDA_PACK -# define IRDA_PACK __attribute__((packed)) -#endif - #ifdef CONFIG_IRDA_DEBUG diff --git a/include/net/irda/irlap_frame.h b/include/net/irda/irlap_frame.h index 641f88e848bd..6b1dc4f8eca5 100644 --- a/include/net/irda/irlap_frame.h +++ b/include/net/irda/irlap_frame.h @@ -85,7 +85,7 @@ struct discovery_t; struct disc_frame { __u8 caddr; /* Connection address */ __u8 control; -} IRDA_PACK; +} __packed; struct xid_frame { __u8 caddr; /* Connection address */ @@ -96,41 +96,41 @@ struct xid_frame { __u8 flags; /* Discovery flags */ __u8 slotnr; __u8 version; -} IRDA_PACK; +} __packed; struct test_frame { __u8 caddr; /* Connection address */ __u8 control; __le32 saddr; /* Source device address */ __le32 daddr; /* Destination device address */ -} IRDA_PACK; +} __packed; struct ua_frame { __u8 caddr; __u8 control; __le32 saddr; /* Source device address */ __le32 daddr; /* Dest device address */ -} IRDA_PACK; +} __packed; struct dm_frame { __u8 caddr; /* Connection address */ __u8 control; -} IRDA_PACK; +} __packed; struct rd_frame { __u8 caddr; /* Connection address */ __u8 control; -} IRDA_PACK; +} __packed; struct rr_frame { __u8 caddr; /* Connection address */ __u8 control; -} IRDA_PACK; +} __packed; struct i_frame { __u8 caddr; __u8 control; -} IRDA_PACK; +} __packed; struct snrm_frame { __u8 caddr; @@ -138,7 +138,7 @@ struct snrm_frame { __le32 saddr; __le32 daddr; __u8 ncaddr; -} IRDA_PACK; +} __packed; void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb); void irlap_send_discovery_xid_frame(struct irlap_cb *, int S, __u8 s, 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/lib80211.h b/include/net/lib80211.h index fb4e2784857d..848cce1bb7a5 100644 --- a/include/net/lib80211.h +++ b/include/net/lib80211.h @@ -54,9 +54,6 @@ struct lib80211_crypto_ops { /* deinitialize crypto context and free allocated private data */ void (*deinit) (void *priv); - int (*build_iv) (struct sk_buff * skb, int hdr_len, - u8 *key, int keylen, void *priv); - /* encrypt/decrypt return < 0 on error or >= 0 on success. The return * value from decrypt_mpdu is passed as the keyidx value for * decrypt_msdu. skb must have enough head and tail room for the diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 45d7d44d7cbe..b0787a1dea90 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -144,6 +144,11 @@ 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 + * @BSS_CHANGED_ARP_FILTER: Hardware ARP filter address list or state changed. + * @BSS_CHANGED_QOS: QoS for this association was enabled/disabled. Note + * that it is only ever disabled for station mode. */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -156,8 +161,21 @@ 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, + BSS_CHANGED_ARP_FILTER = 1<<12, + BSS_CHANGED_QOS = 1<<13, + + /* when adding here, make sure to change ieee80211_reconfig */ }; +/* + * The maximum number of IPv4 addresses listed for ARP filtering. If the number + * of addresses for an interface increase beyond this value, hardware ARP + * filtering will be disabled. + */ +#define IEEE80211_BSS_ARP_ADDR_LIST_LEN 4 + /** * struct ieee80211_bss_conf - holds the BSS's changing parameters * @@ -165,6 +183,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; @@ -174,7 +194,9 @@ enum ieee80211_bss_change { * if the hardware cannot handle this it must set the * IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag * @dtim_period: num of beacons before the next DTIM, for beaconing, - * not valid in station mode (cf. hw conf ps_dtim_period) + * valid in station mode only while @assoc is true and if also + * requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf + * @ps_dtim_period) * @timestamp: beacon timestamp * @beacon_int: beacon interval * @assoc_capability: capabilities taken from assoc resp @@ -183,13 +205,29 @@ 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 + * @arp_addr_list: List of IPv4 addresses for hardware ARP filtering. The + * may filter ARP queries targeted for other addresses than listed here. + * The driver must allow ARP queries targeted for all address listed here + * to pass through. An empty list implies no ARP queries need to pass. + * @arp_addr_cnt: Number of addresses currently on the list. + * @arp_filter_enabled: Enable ARP filtering - if enabled, the hardware may + * filter ARP queries based on the @arp_addr_list, if disabled, the + * hardware must not perform any ARP filtering. Note, that the filter will + * be enabled also in promiscuous mode. + * @qos: This is a QoS-enabled BSS. */ 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 +240,13 @@ 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; + __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN]; + u8 arp_addr_cnt; + bool arp_filter_enabled; + bool qos; }; /** @@ -267,6 +312,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,8 +338,12 @@ 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 + /** * enum mac80211_rate_control_flags - per-rate flags set by the * Rate Control algorithm. @@ -367,7 +419,7 @@ struct ieee80211_tx_rate { s8 idx; u8 count; u8 flags; -} __attribute__((packed)); +} __packed; /** * struct ieee80211_tx_info - skb transmit information @@ -388,11 +440,9 @@ 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. - * @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 { @@ -425,10 +475,9 @@ struct ieee80211_tx_info { struct { struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES]; u8 ampdu_ack_len; - u64 ampdu_ack_map; int ack_signal; u8 ampdu_len; - /* 7 bytes free */ + /* 15 bytes free */ } status; struct { struct ieee80211_tx_rate driver_rates[ @@ -543,7 +592,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 +602,6 @@ struct ieee80211_rx_status { enum ieee80211_band band; int freq; int signal; - int noise; int antenna; int rate_idx; int flag; @@ -580,11 +627,14 @@ 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_OFFCHANNEL: The device is currently not on its main + * operating channel. */ enum ieee80211_conf_flags { IEEE80211_CONF_MONITOR = (1<<0), IEEE80211_CONF_PS = (1<<1), IEEE80211_CONF_IDLE = (1<<2), + IEEE80211_CONF_OFFCHANNEL = (1<<3), }; @@ -682,6 +732,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 @@ -828,16 +900,12 @@ struct ieee80211_sta { * enum sta_notify_cmd - sta notify command * * Used with the sta_notify() callback in &struct ieee80211_ops, this - * indicates addition and removal of a station to station table, - * or if a associated station made a power state transition. + * indicates if an associated station made a power state transition. * - * @STA_NOTIFY_ADD: (DEPRECATED) a station was added to the station table - * @STA_NOTIFY_REMOVE: (DEPRECATED) a station being removed from the station table * @STA_NOTIFY_SLEEP: a station is now sleeping * @STA_NOTIFY_AWAKE: a sleeping station woke up */ enum sta_notify_cmd { - STA_NOTIFY_ADD, STA_NOTIFY_REMOVE, STA_NOTIFY_SLEEP, STA_NOTIFY_AWAKE, }; @@ -907,10 +975,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 +1018,20 @@ 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. + * + * @IEEE80211_HW_NEED_DTIM_PERIOD: + * This device needs to know the DTIM period for the BSS before + * associating. */ enum ieee80211_hw_flags { IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, @@ -963,7 +1041,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, + IEEE80211_HW_NEED_DTIM_PERIOD = 1<<7, IEEE80211_HW_SPECTRUM_MGMT = 1<<8, IEEE80211_HW_AMPDU_AGGREGATION = 1<<9, IEEE80211_HW_SUPPORTS_PS = 1<<10, @@ -975,6 +1053,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, }; /** @@ -1198,6 +1278,15 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * dynamic PS feature in stack and will just keep %IEEE80211_CONF_PS * enabled whenever user has enabled powersave. * + * Some hardware need to toggle a single shared antenna between WLAN and + * Bluetooth to facilitate co-existence. These types of hardware set + * limitations on the use of host controlled dynamic powersave whenever there + * is simultaneous WLAN and Bluetooth traffic. For these types of hardware, the + * driver may request temporarily going into full power save, in order to + * enable toggling the antenna between BT and WLAN. If the driver requests + * disabling dynamic powersave, the @dynamic_ps_timeout value will be + * temporarily set to zero until the driver re-enables dynamic powersave. + * * Driver informs U-APSD client support by enabling * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS @@ -1389,7 +1478,7 @@ enum ieee80211_filter_flags { * * Note that drivers MUST be able to deal with a TX aggregation * session being stopped even before they OK'ed starting it by - * calling ieee80211_start_tx_ba_cb(_irqsafe), because the peer + * calling ieee80211_start_tx_ba_cb_irqsafe, because the peer * might receive the addBA frame and send a delBA right away! * * @IEEE80211_AMPDU_RX_START: start Rx aggregation @@ -1574,7 +1663,9 @@ enum ieee80211_ampdu_mlme_action { * is the first frame we expect to perform the action on. Notice * that TX/RX_STOP can pass NULL for this parameter. * Returns a negative error code on failure. - * The callback must be atomic. + * The callback can sleep. + * + * @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, @@ -1591,6 +1682,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 +1702,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 +1717,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 +1742,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 +1901,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 @@ -2232,25 +2334,14 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid); /** - * ieee80211_start_tx_ba_cb - low level driver ready to aggregate. - * @vif: &struct ieee80211_vif pointer from the add_interface callback - * @ra: receiver address of the BA session recipient. - * @tid: the TID to BA on. - * - * This function must be called by low level driver once it has - * finished with preparations for the BA session. - */ -void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); - -/** * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate. * @vif: &struct ieee80211_vif pointer from the add_interface callback * @ra: receiver address of the BA session recipient. * @tid: the TID to BA on. * * This function must be called by low level driver once it has - * finished with preparations for the BA session. - * This version of the function is IRQ-safe. + * finished with preparations for the BA session. It can be called + * from any context. */ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra, u16 tid); @@ -2259,27 +2350,14 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra, * ieee80211_stop_tx_ba_session - Stop a Block Ack session. * @sta: the station whose BA session to stop * @tid: the TID to stop BA. - * @initiator: if indicates initiator DELBA frame will be sent. * - * Return: error if no sta with matching da found, success otherwise + * Return: negative error if the TID is invalid, or no aggregation active * * Although mac80211/low level driver/user space application can estimate * the need to stop aggregation on a certain RA/TID, the session level * will be managed by the mac80211. */ -int ieee80211_stop_tx_ba_session(struct ieee80211_sta *sta, u16 tid, - enum ieee80211_back_parties initiator); - -/** - * ieee80211_stop_tx_ba_cb - low level driver ready to stop aggregate. - * @vif: &struct ieee80211_vif pointer from the add_interface callback - * @ra: receiver address of the BA session recipient. - * @tid: the desired TID to BA on. - * - * This function must be called by low level driver once it has - * finished with preparations for the BA session tear down. - */ -void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); +int ieee80211_stop_tx_ba_session(struct ieee80211_sta *sta, u16 tid); /** * ieee80211_stop_tx_ba_cb_irqsafe - low level driver ready to stop aggregate. @@ -2288,8 +2366,8 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); * @tid: the desired TID to BA on. * * This function must be called by low level driver once it has - * finished with preparations for the BA session tear down. - * This version of the function is IRQ-safe. + * finished with preparations for the BA session tear down. It + * can be called from any context. */ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra, u16 tid); @@ -2364,12 +2442,82 @@ 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_disable_dyn_ps - force mac80211 to temporarily disable dynamic psm + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * + * Some hardware require full power save to manage simultaneous BT traffic + * on the WLAN frequency. Full PSM is required periodically, whenever there are + * burst of BT traffic. The hardware gets information of BT traffic via + * hardware co-existence lines, and consequentially requests mac80211 to + * (temporarily) enter full psm. + * This function will only temporarily disable dynamic PS, not enable PSM if + * it was not already enabled. + * The driver must make sure to re-enable dynamic PS using + * ieee80211_enable_dyn_ps() if the driver has disabled it. + * + */ +void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif); + +/** + * ieee80211_enable_dyn_ps - restore dynamic psm after being disabled + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * + * This function restores dynamic PS after being temporarily disabled via + * ieee80211_disable_dyn_ps(). Each ieee80211_disable_dyn_ps() call must + * be coupled with an eventual call to this function. + * + */ +void ieee80211_enable_dyn_ps(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/mip6.h b/include/net/mip6.h index a83ad1982a90..26ba99b5a4b1 100644 --- a/include/net/mip6.h +++ b/include/net/mip6.h @@ -39,7 +39,7 @@ struct ip6_mh { __u16 ip6mh_cksum; /* Followed by type specific messages */ __u8 data[0]; -} __attribute__ ((__packed__)); +} __packed; #define IP6_MH_TYPE_BRR 0 /* Binding Refresh Request */ #define IP6_MH_TYPE_HOTI 1 /* HOTI Message */ 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/ndisc.h b/include/net/ndisc.h index f76f22d05721..895997bc2ead 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -82,7 +82,7 @@ struct ra_msg { struct nd_opt_hdr { __u8 nd_opt_type; __u8 nd_opt_len; -} __attribute__((__packed__)); +} __packed; extern int ndisc_init(void); diff --git a/include/net/neighbour.h b/include/net/neighbour.h index da1d58be31b7..242879b6c4df 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -151,7 +151,7 @@ struct neigh_table { void (*proxy_redo)(struct sk_buff *skb); char *id; struct neigh_parms parms; - /* HACK. gc_* shoul follow parms without a gap! */ + /* HACK. gc_* should follow parms without a gap! */ int gc_interval; int gc_thresh1; int gc_thresh2; @@ -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.h b/include/net/netfilter/nf_conntrack.h index bde095f7e845..e624dae54fa4 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -152,11 +152,7 @@ extern struct net init_net; static inline struct net *nf_ct_net(const struct nf_conn *ct) { -#ifdef CONFIG_NET_NS - return ct->ct_net; -#else - return &init_net; -#endif + return read_pnet(&ct->ct_net); } /* Alter reply tuple (maybe alter helper). */ @@ -261,7 +257,12 @@ extern s16 (*nf_ct_nat_offset)(const struct nf_conn *ct, u32 seq); /* Fake conntrack entry for untracked connections */ -extern struct nf_conn nf_conntrack_untracked; +DECLARE_PER_CPU(struct nf_conn, nf_conntrack_untracked); +static inline struct nf_conn *nf_ct_untracked_get(void) +{ + return &__raw_get_cpu_var(nf_conntrack_untracked); +} +extern void nf_ct_untracked_status_or(unsigned long bits); /* Iterate over all conntracks: if iter returns true, it's deleted. */ extern void @@ -289,9 +290,9 @@ static inline int nf_ct_is_dying(struct nf_conn *ct) return test_bit(IPS_DYING_BIT, &ct->status); } -static inline int nf_ct_is_untracked(const struct sk_buff *skb) +static inline int nf_ct_is_untracked(const struct nf_conn *ct) { - return (skb->nfct == &nf_conntrack_untracked.ct_general); + return test_bit(IPS_UNTRACKED_BIT, &ct->status); } extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp); diff --git a/include/net/netfilter/nf_conntrack_acct.h b/include/net/netfilter/nf_conntrack_acct.h index 03e218f0be43..4e9c63a20db2 100644 --- a/include/net/netfilter/nf_conntrack_acct.h +++ b/include/net/netfilter/nf_conntrack_acct.h @@ -45,6 +45,18 @@ struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp) extern unsigned int seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir); +/* Check if connection tracking accounting is enabled */ +static inline bool nf_ct_acct_enabled(struct net *net) +{ + return net->ct.sysctl_acct != 0; +} + +/* Enable/disable connection tracking accounting */ +static inline void nf_ct_set_acct(struct net *net, bool enable) +{ + net->ct.sysctl_acct = enable; +} + extern int nf_conntrack_acct_init(struct net *net); extern void nf_conntrack_acct_fini(struct net *net); diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index dffde8e6920e..aced085132e7 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h @@ -60,8 +60,8 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb) struct nf_conn *ct = (struct nf_conn *)skb->nfct; int ret = NF_ACCEPT; - if (ct && ct != &nf_conntrack_untracked) { - if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) + if (ct && !nf_ct_is_untracked(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/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 32d15bd6efa3..0772d296dfdb 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -28,9 +28,14 @@ struct nf_ct_ext { char data[0]; }; -static inline int nf_ct_ext_exist(const struct nf_conn *ct, u8 id) +static inline bool __nf_ct_ext_exist(const struct nf_ct_ext *ext, u8 id) { - return (ct->ext && ct->ext->offset[id]); + return !!ext->offset[id]; +} + +static inline bool nf_ct_ext_exist(const struct nf_conn *ct, u8 id) +{ + return (ct->ext && __nf_ct_ext_exist(ct->ext, id)); } static inline void *__nf_ct_ext_find(const struct nf_conn *ct, u8 id) diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h index c398017ccfa3..df17bac46bf5 100644 --- a/include/net/netfilter/nf_nat_protocol.h +++ b/include/net/netfilter/nf_nat_protocol.h @@ -27,9 +27,9 @@ struct nf_nat_protocol { /* Alter the per-proto part of the tuple (depending on maniptype), to give a unique tuple in the given range if - possible; return false if not. Per-protocol part of tuple - is initialized to the incoming packet. */ - bool (*unique_tuple)(struct nf_conntrack_tuple *tuple, + possible. Per-protocol part of tuple is initialized to the + incoming packet. */ + void (*unique_tuple)(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct); @@ -63,7 +63,7 @@ extern bool nf_nat_proto_in_range(const struct nf_conntrack_tuple *tuple, const union nf_conntrack_man_proto *min, const union nf_conntrack_man_proto *max); -extern bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, +extern void nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct, diff --git a/include/net/netfilter/nf_nat_rule.h b/include/net/netfilter/nf_nat_rule.h index e4a18ae361c6..2890bdc4cd92 100644 --- a/include/net/netfilter/nf_nat_rule.h +++ b/include/net/netfilter/nf_nat_rule.h @@ -12,6 +12,4 @@ extern int nf_nat_rule_find(struct sk_buff *skb, const struct net_device *out, struct nf_conn *ct); -extern unsigned int -alloc_null_binding(struct nf_conn *ct, unsigned int hooknum); #endif /* _NF_NAT_RULE_H */ diff --git a/include/net/netfilter/nfnetlink_log.h b/include/net/netfilter/nfnetlink_log.h index b0569ff0775e..e2dec42c2db2 100644 --- a/include/net/netfilter/nfnetlink_log.h +++ b/include/net/netfilter/nfnetlink_log.h @@ -10,5 +10,7 @@ nfulnl_log_packet(u_int8_t pf, const struct nf_loginfo *li_user, const char *prefix); +#define NFULNL_COPY_DISABLED 0xff + #endif /* _KER_NFNETLINK_LOG_H */ diff --git a/include/net/netfilter/xt_rateest.h b/include/net/netfilter/xt_rateest.h index ddbf37e19616..5a2978d1cb22 100644 --- a/include/net/netfilter/xt_rateest.h +++ b/include/net/netfilter/xt_rateest.h @@ -2,13 +2,18 @@ #define _XT_RATEEST_H struct xt_rateest { + /* keep lock and bstats on same cache line to speedup xt_rateest_tg() */ + struct gnet_stats_basic_packed bstats; + spinlock_t lock; + /* keep rstats and lock on same cache line to speedup xt_rateest_mt() */ + struct gnet_stats_rate_est rstats; + + /* following fields not accessed in hot path */ struct hlist_node list; char name[IFNAMSIZ]; unsigned int refcnt; - spinlock_t lock; struct gnet_estimator params; - struct gnet_stats_rate_est rstats; - struct gnet_stats_basic_packed bstats; + struct rcu_head rcu; }; extern struct xt_rateest *xt_rateest_lookup(const char *name); diff --git a/include/net/netlink.h b/include/net/netlink.h index 4fc05b58503e..f3b201d335b3 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -35,7 +35,7 @@ * nlmsg_new() create a new netlink message * nlmsg_put() add a netlink message to an skb * nlmsg_put_answer() callback based nlmsg_put() - * nlmsg_end() finanlize netlink message + * nlmsg_end() finalize netlink message * nlmsg_get_pos() return current position in message * nlmsg_trim() trim part of message * nlmsg_cancel() cancel message construction 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/phonet/pn_dev.h b/include/net/phonet/pn_dev.h index d7b989ca3d63..2d16783d5e20 100644 --- a/include/net/phonet/pn_dev.h +++ b/include/net/phonet/pn_dev.h @@ -34,6 +34,7 @@ struct phonet_device { struct list_head list; struct net_device *netdev; DECLARE_BITMAP(addrs, 64); + struct rcu_head rcu; }; int phonet_device_init(void); diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index b6cdc33b39c1..d9549af6929a 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) @@ -95,7 +95,7 @@ extern void __qdisc_run(struct Qdisc *q); static inline void qdisc_run(struct Qdisc *q) { - if (!test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) + if (qdisc_run_begin(q)) __qdisc_run(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/regulatory.h b/include/net/regulatory.h index f873ee37f7e4..9e103a4e91ee 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -54,7 +54,6 @@ struct regulatory_request { enum nl80211_reg_initiator initiator; char alpha2[2]; bool intersect; - u32 country_ie_checksum; enum environment_cap country_ie_env; struct list_head list; }; diff --git a/include/net/route.h b/include/net/route.h index 2c9fba7f7731..bd732d62e1c3 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -50,9 +50,7 @@ struct fib_nh; struct inet_peer; struct rtable { - union { - struct dst_entry dst; - } u; + struct dst_entry dst; /* Cache lookup keys */ struct flowi fl; @@ -112,7 +110,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); @@ -129,7 +142,7 @@ extern void fib_add_ifaddr(struct in_ifaddr *); static inline void ip_rt_put(struct rtable * rt) { if (rt) - dst_release(&rt->u.dst); + dst_release(&rt->dst); } #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 67dc08eaaa45..3c8728aaab4e 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -23,11 +23,17 @@ struct qdisc_rate_table { }; enum qdisc_state_t { - __QDISC_STATE_RUNNING, __QDISC_STATE_SCHED, __QDISC_STATE_DEACTIVATED, }; +/* + * following bits are only changed while qdisc lock is held + */ +enum qdisc___state_t { + __QDISC___STATE_RUNNING, +}; + struct qdisc_size_table { struct list_head list; struct tc_sizespec szopts; @@ -72,9 +78,27 @@ struct Qdisc { unsigned long state; struct sk_buff_head q; struct gnet_stats_basic_packed bstats; + unsigned long __state; struct gnet_stats_queue qstats; + struct rcu_head rcu_head; + spinlock_t busylock; }; +static inline bool qdisc_is_running(struct Qdisc *qdisc) +{ + return test_bit(__QDISC___STATE_RUNNING, &qdisc->__state); +} + +static inline bool qdisc_run_begin(struct Qdisc *qdisc) +{ + return !__test_and_set_bit(__QDISC___STATE_RUNNING, &qdisc->__state); +} + +static inline void qdisc_run_end(struct Qdisc *qdisc) +{ + __clear_bit(__QDISC___STATE_RUNNING, &qdisc->__state); +} + struct Qdisc_class_ops { /* Child qdisc manipulation */ struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); @@ -312,12 +336,24 @@ extern void qdisc_calculate_pkt_len(struct sk_buff *skb, extern void tcf_destroy(struct tcf_proto *tp); extern void tcf_destroy_chain(struct tcf_proto **fl); -/* Reset all TX qdiscs of a device. */ +/* Reset all TX qdiscs greater then index of a device. */ +static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) +{ + struct Qdisc *qdisc; + + for (; i < dev->num_tx_queues; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc; + if (qdisc) { + spin_lock_bh(qdisc_lock(qdisc)); + qdisc_reset(qdisc); + spin_unlock_bh(qdisc_lock(qdisc)); + } + } +} + static inline void qdisc_reset_all_tx(struct net_device *dev) { - unsigned int i; - for (i = 0; i < dev->num_tx_queues; i++) - qdisc_reset(netdev_get_tx_queue(dev, i)->qdisc); + qdisc_reset_all_tx_gt(dev, 0); } /* Are all TX queues of the device empty? */ @@ -570,9 +606,16 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen) } #ifdef CONFIG_NET_CLS_ACT -static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask) +static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask, + int action) { - struct sk_buff *n = skb_clone(skb, gfp_mask); + struct sk_buff *n; + + if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) && + !skb_shared(skb)) + n = skb_get(skb); + else + n = skb_clone(skb, gfp_mask); if (n) { n->tc_verd = SET_TC_VERD(n->tc_verd, 0); diff --git a/include/net/scm.h b/include/net/scm.h index 8360e47aa7e3..31656506d967 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -19,8 +19,10 @@ struct scm_fp_list { }; struct scm_cookie { - struct ucred creds; /* Skb credentials */ + struct pid *pid; /* Skb credentials */ + const struct cred *cred; struct scm_fp_list *fp; /* Passed files */ + struct ucred creds; /* Skb credentials */ #ifdef CONFIG_SECURITY_NETWORK u32 secid; /* Passed security ID */ #endif @@ -42,8 +44,27 @@ static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_co { } #endif /* CONFIG_SECURITY_NETWORK */ +static __inline__ void scm_set_cred(struct scm_cookie *scm, + struct pid *pid, const struct cred *cred) +{ + scm->pid = get_pid(pid); + scm->cred = get_cred(cred); + cred_to_ucred(pid, cred, &scm->creds); +} + +static __inline__ void scm_destroy_cred(struct scm_cookie *scm) +{ + put_pid(scm->pid); + scm->pid = NULL; + + if (scm->cred) + put_cred(scm->cred); + scm->cred = NULL; +} + static __inline__ void scm_destroy(struct scm_cookie *scm) { + scm_destroy_cred(scm); if (scm && scm->fp) __scm_destroy(scm); } @@ -51,10 +72,7 @@ static __inline__ void scm_destroy(struct scm_cookie *scm) static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { - struct task_struct *p = current; - scm->creds.uid = current_uid(); - scm->creds.gid = current_gid(); - scm->creds.pid = task_tgid_vnr(p); + scm_set_cred(scm, task_tgid(current), current_cred()); scm->fp = NULL; unix_get_peersec_dgram(sock, scm); if (msg->msg_controllen <= 0) @@ -96,6 +114,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, if (test_bit(SOCK_PASSCRED, &sock->flags)) put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds); + scm_destroy_cred(scm); + scm_passec(sock, msg, scm); if (!scm->fp) 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 851c813adb3a..4088c89a9055 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -279,6 +279,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype, /* 2nd level prototypes */ void sctp_generate_t3_rtx_event(unsigned long peer); void sctp_generate_heartbeat_event(unsigned long peer); +void sctp_generate_proto_unreach_event(unsigned long peer); void sctp_ootb_pkt_free(struct sctp_packet *); @@ -437,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 597f8e27aaf6..f9e7473613bd 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -443,7 +443,7 @@ struct sctp_signed_cookie { __u8 signature[SCTP_SECRET_SIZE]; __u32 __pad; /* force sctp_cookie alignment to 64 bits */ struct sctp_cookie c; -} __attribute__((packed)); +} __packed; /* This is another convenience type to allocate memory for address * params for the maximum size and pass such structures around @@ -488,7 +488,7 @@ typedef struct sctp_sender_hb_info { union sctp_addr daddr; unsigned long sent_at; __u64 hb_nonce; -} __attribute__((packed)) sctp_sender_hb_info_t; +} __packed sctp_sender_hb_info_t; /* * RFC 2960 1.3.2 Sequenced Delivery within Streams @@ -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; + __u32 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; @@ -1010,6 +1008,9 @@ struct sctp_transport { /* Heartbeat timer is per destination. */ struct timer_list hb_timer; + /* Timer to handle ICMP proto unreachable envets */ + struct timer_list proto_unreach_timer; + /* Since we're using per-destination retransmission timers * (see above), we're also using per-destination "transmitted" * queues. This probably ought to be a private struct @@ -1023,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. @@ -1066,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); @@ -1720,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..a0e61806d480 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -47,31 +47,17 @@ struct snmp_mib { } /* - * We use all unsigned longs. Linux will soon be so reliable that even - * these will rapidly get too small 8-). Seriously consider the IpInReceives - * count on the 20Gb/s + networks people expect in a few years time! + * We use unsigned longs for most mibs but u64 for ipstats. */ - -/* - * 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 +#include <linux/u64_stats_sync.h> /* IPstats */ #define IPSTATS_MIB_MAX __IPSTATS_MIB_MAX struct ipstats_mib { - unsigned long mibs[IPSTATS_MIB_MAX]; -} __SNMP_MIB_ALIGN__; + /* mibs[] must be first field of struct ipstats_mib */ + u64 mibs[IPSTATS_MIB_MAX]; + struct u64_stats_sync syncp; +}; /* ICMP */ #define ICMP_MIB_DUMMY __ICMP_MIB_MAX @@ -79,36 +65,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 +134,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[!in_softirq()]->mibs[field], addend) /* * Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr" * to make @ptr a non-percpu pointer. @@ -168,4 +156,70 @@ struct linux_xfrm_mib { ptr->mibs[basefield##PKTS]++; \ ptr->mibs[basefield##OCTETS] += addend;\ } while (0) + + +#if BITS_PER_LONG==32 + +#define SNMP_ADD_STATS64_BH(mib, field, addend) \ + do { \ + __typeof__(*mib[0]) *ptr = __this_cpu_ptr((mib)[0]); \ + u64_stats_update_begin(&ptr->syncp); \ + ptr->mibs[field] += addend; \ + u64_stats_update_end(&ptr->syncp); \ + } while (0) +#define SNMP_ADD_STATS64_USER(mib, field, addend) \ + do { \ + __typeof__(*mib[0]) *ptr; \ + preempt_disable(); \ + ptr = __this_cpu_ptr((mib)[1]); \ + u64_stats_update_begin(&ptr->syncp); \ + ptr->mibs[field] += addend; \ + u64_stats_update_end(&ptr->syncp); \ + preempt_enable(); \ + } while (0) +#define SNMP_ADD_STATS64(mib, field, addend) \ + do { \ + __typeof__(*mib[0]) *ptr; \ + preempt_disable(); \ + ptr = __this_cpu_ptr((mib)[!in_softirq()]); \ + u64_stats_update_begin(&ptr->syncp); \ + ptr->mibs[field] += addend; \ + u64_stats_update_end(&ptr->syncp); \ + preempt_enable(); \ + } while (0) +#define SNMP_INC_STATS64_BH(mib, field) SNMP_ADD_STATS64_BH(mib, field, 1) +#define SNMP_INC_STATS64_USER(mib, field) SNMP_ADD_STATS64_USER(mib, field, 1) +#define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1) +#define SNMP_UPD_PO_STATS64(mib, basefield, addend) \ + do { \ + __typeof__(*mib[0]) *ptr; \ + preempt_disable(); \ + ptr = __this_cpu_ptr((mib)[!in_softirq()]); \ + u64_stats_update_begin(&ptr->syncp); \ + ptr->mibs[basefield##PKTS]++; \ + ptr->mibs[basefield##OCTETS] += addend; \ + u64_stats_update_end(&ptr->syncp); \ + preempt_enable(); \ + } while (0) +#define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) \ + do { \ + __typeof__(*mib[0]) *ptr; \ + ptr = __this_cpu_ptr((mib)[!in_softirq()]); \ + u64_stats_update_begin(&ptr->syncp); \ + ptr->mibs[basefield##PKTS]++; \ + ptr->mibs[basefield##OCTETS] += addend; \ + u64_stats_update_end(&ptr->syncp); \ + } while (0) +#else +#define SNMP_INC_STATS64_BH(mib, field) SNMP_INC_STATS_BH(mib, field) +#define SNMP_INC_STATS64_USER(mib, field) SNMP_INC_STATS_USER(mib, field) +#define SNMP_INC_STATS64(mib, field) SNMP_INC_STATS(mib, field) +#define SNMP_DEC_STATS64(mib, field) SNMP_DEC_STATS(mib, field) +#define SNMP_ADD_STATS64_BH(mib, field, addend) SNMP_ADD_STATS_BH(mib, field, addend) +#define SNMP_ADD_STATS64_USER(mib, field, addend) SNMP_ADD_STATS_USER(mib, field, addend) +#define SNMP_ADD_STATS64(mib, field, addend) SNMP_ADD_STATS(mib, field, addend) +#define SNMP_UPD_PO_STATS64(mib, basefield, addend) SNMP_UPD_PO_STATS(mib, basefield, addend) +#define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) SNMP_UPD_PO_STATS_BH(mib, basefield, addend) +#endif + #endif diff --git a/include/net/sock.h b/include/net/sock.h index 1ad6435f252e..a441c9cdd625 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; @@ -290,7 +295,8 @@ struct sock { unsigned short sk_ack_backlog; unsigned short sk_max_ack_backlog; __u32 sk_priority; - struct ucred sk_peercred; + struct pid *sk_peer_pid; + const struct cred *sk_peer_cred; long sk_rcvtimeo; long sk_sndtimeo; struct sk_filter *sk_filter; @@ -307,7 +313,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 +601,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 +639,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); \ @@ -719,6 +772,7 @@ struct proto { int *sysctl_wmem; int *sysctl_rmem; int max_header; + bool no_autobind; struct kmem_cache *slab; unsigned int obj_size; @@ -974,6 +1028,24 @@ extern void release_sock(struct sock *sk); SINGLE_DEPTH_NESTING) #define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock)) +extern bool lock_sock_fast(struct sock *sk); +/** + * unlock_sock_fast - complement of lock_sock_fast + * @sk: socket + * @slow: slow mode + * + * fast unlock socket for user context. + * If slow mode is on, we call regular release_sock() + */ +static inline void unlock_sock_fast(struct sock *sk, bool slow) +{ + if (slow) + release_sock(sk); + else + 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 +1084,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. @@ -1146,12 +1226,7 @@ static inline void sk_tx_queue_clear(struct sock *sk) static inline int sk_tx_queue_get(const struct sock *sk) { - return sk->sk_tx_queue_mapping; -} - -static inline bool sk_tx_queue_recorded(const struct sock *sk) -{ - return (sk && sk->sk_tx_queue_mapping >= 0); + return sk ? sk->sk_tx_queue_mapping : -1; } static inline void sk_set_socket(struct sock *sk, struct socket *sock) @@ -1160,6 +1235,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 +1251,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 +1271,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 +1281,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 +1353,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 +1416,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 +1434,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 +1446,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 +1466,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 +1477,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(); } @@ -1419,20 +1521,7 @@ extern void sk_stop_timer(struct sock *sk, struct timer_list* timer); extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); -static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) -{ - /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces - number of warnings when compiling with -W --ANK - */ - if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= - (unsigned)sk->sk_rcvbuf) - return -ENOMEM; - skb_set_owner_r(skb, sk); - skb_queue_tail(&sk->sk_error_queue, skb); - if (!sock_flag(sk, SOCK_DEAD)) - sk->sk_data_ready(sk, skb->len); - return 0; -} +extern int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb); /* * Recover an error report and clear atomically @@ -1557,7 +1646,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 @@ -1602,19 +1708,13 @@ static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, int copied_e static inline struct net *sock_net(const struct sock *sk) { -#ifdef CONFIG_NET_NS - return sk->sk_net; -#else - return &init_net; -#endif + return read_pnet(&sk->sk_net); } static inline void sock_net_set(struct sock *sk, struct net *net) { -#ifdef CONFIG_NET_NS - sk->sk_net = net; -#endif + write_pnet(&sk->sk_net, net); } /* diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h index ceac661cdfd5..cfe2943690ff 100644 --- a/include/net/tc_act/tc_mirred.h +++ b/include/net/tc_act/tc_mirred.h @@ -9,6 +9,7 @@ struct tcf_mirred { int tcfm_ifindex; int tcfm_ok_push; struct net_device *tcfm_dev; + struct list_head tcfm_list; }; #define to_mirred(pc) \ container_of(pc, struct tcf_mirred, common) diff --git a/include/net/tcp.h b/include/net/tcp.h index 75be5a28815d..df6a2eb20193 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -294,46 +294,32 @@ 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) - -extern void tcp_v4_err(struct sk_buff *skb, u32); - -extern void tcp_shutdown (struct sock *sk, int how); - -extern int tcp_v4_rcv(struct sk_buff *skb); - -extern int tcp_v4_remember_stamp(struct sock *sk); - -extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); - -extern int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t size); -extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags); - -extern int tcp_ioctl(struct sock *sk, - int cmd, - unsigned long arg); - -extern int tcp_rcv_state_process(struct sock *sk, - struct sk_buff *skb, - struct tcphdr *th, - unsigned len); - -extern int tcp_rcv_established(struct sock *sk, - struct sk_buff *skb, - struct tcphdr *th, - unsigned len); - -extern void tcp_rcv_space_adjust(struct sock *sk); - -extern void tcp_cleanup_rbuf(struct sock *sk, int copied); - -extern int tcp_twsk_unique(struct sock *sk, - struct sock *sktw, void *twp); - -extern void tcp_twsk_destructor(struct sock *sk); - -extern ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, unsigned int flags); +#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); + +extern void tcp_shutdown (struct sock *sk, int how); + +extern int tcp_v4_rcv(struct sk_buff *skb); + +extern int tcp_v4_remember_stamp(struct sock *sk); +extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); +extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + size_t size); +extern int tcp_sendpage(struct sock *sk, struct page *page, int offset, + size_t size, int flags); +extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); +extern int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, + struct tcphdr *th, unsigned len); +extern int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, + struct tcphdr *th, unsigned len); +extern void tcp_rcv_space_adjust(struct sock *sk); +extern void tcp_cleanup_rbuf(struct sock *sk, int copied); +extern int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp); +extern void tcp_twsk_destructor(struct sock *sk); +extern ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); static inline void tcp_dec_quickack_mode(struct sock *sk, const unsigned int pkts) @@ -371,88 +357,59 @@ enum tcp_tw_status { }; -extern enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw, - struct sk_buff *skb, - const struct tcphdr *th); - -extern struct sock * tcp_check_req(struct sock *sk,struct sk_buff *skb, - struct request_sock *req, - struct request_sock **prev); -extern int tcp_child_process(struct sock *parent, - struct sock *child, - struct sk_buff *skb); -extern int tcp_use_frto(struct sock *sk); -extern void tcp_enter_frto(struct sock *sk); -extern void tcp_enter_loss(struct sock *sk, int how); -extern void tcp_clear_retrans(struct tcp_sock *tp); -extern void tcp_update_metrics(struct sock *sk); - -extern void tcp_close(struct sock *sk, - long timeout); -extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); - -extern int tcp_getsockopt(struct sock *sk, int level, - int optname, - char __user *optval, - int __user *optlen); -extern int tcp_setsockopt(struct sock *sk, int level, - int optname, char __user *optval, - unsigned int optlen); -extern int compat_tcp_getsockopt(struct sock *sk, - int level, int optname, - char __user *optval, int __user *optlen); -extern int compat_tcp_setsockopt(struct sock *sk, - int level, int optname, - char __user *optval, unsigned int optlen); -extern void tcp_set_keepalive(struct sock *sk, int val); -extern void tcp_syn_ack_timeout(struct sock *sk, - struct request_sock *req); -extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, - struct msghdr *msg, - size_t len, int nonblock, - int flags, int *addr_len); - -extern void tcp_parse_options(struct sk_buff *skb, - struct tcp_options_received *opt_rx, - u8 **hvpp, - int estab); - -extern u8 *tcp_parse_md5sig_option(struct tcphdr *th); +extern enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw, + struct sk_buff *skb, + const struct tcphdr *th); +extern struct sock * tcp_check_req(struct sock *sk,struct sk_buff *skb, + struct request_sock *req, + struct request_sock **prev); +extern int tcp_child_process(struct sock *parent, struct sock *child, + struct sk_buff *skb); +extern int tcp_use_frto(struct sock *sk); +extern void tcp_enter_frto(struct sock *sk); +extern void tcp_enter_loss(struct sock *sk, int how); +extern void tcp_clear_retrans(struct tcp_sock *tp); +extern void tcp_update_metrics(struct sock *sk); +extern void tcp_close(struct sock *sk, long timeout); +extern unsigned int tcp_poll(struct file * file, struct socket *sock, + struct poll_table_struct *wait); +extern int tcp_getsockopt(struct sock *sk, int level, int optname, + char __user *optval, int __user *optlen); +extern int tcp_setsockopt(struct sock *sk, int level, int optname, + char __user *optval, unsigned int optlen); +extern int compat_tcp_getsockopt(struct sock *sk, int level, int optname, + char __user *optval, int __user *optlen); +extern int compat_tcp_setsockopt(struct sock *sk, int level, int optname, + char __user *optval, unsigned int optlen); +extern void tcp_set_keepalive(struct sock *sk, int val); +extern void tcp_syn_ack_timeout(struct sock *sk, struct request_sock *req); +extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + size_t len, int nonblock, int flags, int *addr_len); +extern void tcp_parse_options(struct sk_buff *skb, + struct tcp_options_received *opt_rx, u8 **hvpp, + int estab); +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, - struct sk_buff *skb); - -extern int tcp_v4_conn_request(struct sock *sk, - struct sk_buff *skb); - -extern struct sock * tcp_create_openreq_child(struct sock *sk, - struct request_sock *req, - struct sk_buff *skb); - -extern struct sock * tcp_v4_syn_recv_sock(struct sock *sk, - struct sk_buff *skb, - struct request_sock *req, - struct dst_entry *dst); - -extern int tcp_v4_do_rcv(struct sock *sk, +extern void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); +extern int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); +extern struct sock * tcp_create_openreq_child(struct sock *sk, + struct request_sock *req, struct sk_buff *skb); - -extern int tcp_v4_connect(struct sock *sk, - struct sockaddr *uaddr, - int addr_len); - -extern int tcp_connect(struct sock *sk); - -extern struct sk_buff * tcp_make_synack(struct sock *sk, - struct dst_entry *dst, - struct request_sock *req, - struct request_values *rvp); - -extern int tcp_disconnect(struct sock *sk, int flags); +extern struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, + struct request_sock *req, + struct dst_entry *dst); +extern int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb); +extern int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, + int addr_len); +extern int tcp_connect(struct sock *sk); +extern struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, + struct request_sock *req, + struct request_values *rvp); +extern int tcp_disconnect(struct sock *sk, int flags); /* From syncookies.c */ @@ -463,7 +420,7 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mss); extern __u32 cookie_init_timestamp(struct request_sock *req); -extern void cookie_check_timestamp(struct tcp_options_received *tcp_opt); +extern bool cookie_check_timestamp(struct tcp_options_received *opt, bool *); /* From net/ipv6/syncookies.c */ extern struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb); @@ -484,10 +441,10 @@ extern int tcp_fragment(struct sock *, struct sk_buff *, u32, unsigned int); extern void tcp_send_probe0(struct sock *); extern void tcp_send_partial(struct sock *); -extern int tcp_write_wakeup(struct sock *); +extern int tcp_write_wakeup(struct sock *); extern void tcp_send_fin(struct sock *sk); extern void tcp_send_active_reset(struct sock *sk, gfp_t priority); -extern int tcp_send_synack(struct sock *); +extern int tcp_send_synack(struct sock *); extern void tcp_push_one(struct sock *, unsigned int mss_now); extern void tcp_send_ack(struct sock *sk); extern void tcp_send_delayed_ack(struct sock *sk); @@ -591,7 +548,7 @@ static inline u32 tcp_receive_window(const struct tcp_sock *tp) * scaling applied to the result. The caller does these things * if necessary. This is a "raw" window selection. */ -extern u32 __tcp_select_window(struct sock *sk); +extern u32 __tcp_select_window(struct sock *sk); /* TCP timestamps are only 32-bits, this causes a slight * complication on 64-bit systems since we store a snapshot @@ -601,12 +558,22 @@ extern u32 __tcp_select_window(struct sock *sk); */ #define tcp_time_stamp ((__u32)(jiffies)) +#define tcp_flag_byte(th) (((u_int8_t *)th)[13]) + +#define TCPHDR_FIN 0x01 +#define TCPHDR_SYN 0x02 +#define TCPHDR_RST 0x04 +#define TCPHDR_PSH 0x08 +#define TCPHDR_ACK 0x10 +#define TCPHDR_URG 0x20 +#define TCPHDR_ECE 0x40 +#define TCPHDR_CWR 0x80 + /* This is what the send packet queuing engine uses to pass - * TCP per-packet control information to the transmission - * code. We also store the host-order sequence numbers in - * here too. This is 36 bytes on 32-bit architectures, - * 40 bytes on 64-bit machines, if this grows please adjust - * skbuff.h:skbuff->cb[xxx] size appropriately. + * TCP per-packet control information to the transmission code. + * We also store the host-order sequence numbers in here too. + * This is 44 bytes if IPV6 is enabled. + * If this grows please adjust skbuff.h:skbuff->cb[xxx] size appropriately. */ struct tcp_skb_cb { union { @@ -619,19 +586,6 @@ struct tcp_skb_cb { __u32 end_seq; /* SEQ + FIN + SYN + datalen */ __u32 when; /* used to compute rtt's */ __u8 flags; /* TCP header flags. */ - - /* NOTE: These must match up to the flags byte in a - * real TCP header. - */ -#define TCPCB_FLAG_FIN 0x01 -#define TCPCB_FLAG_SYN 0x02 -#define TCPCB_FLAG_RST 0x04 -#define TCPCB_FLAG_PSH 0x08 -#define TCPCB_FLAG_ACK 0x10 -#define TCPCB_FLAG_URG 0x20 -#define TCPCB_FLAG_ECE 0x40 -#define TCPCB_FLAG_CWR 0x80 - __u8 sacked; /* State flags for SACK/FACK. */ #define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */ #define TCPCB_SACKED_RETRANS 0x02 /* SKB retransmitted */ @@ -939,7 +893,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 +986,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; @@ -1167,22 +1129,14 @@ struct tcp_md5sig_pool { #define TCP_MD5SIG_MAXKEYS (~(u32)0) /* really?! */ /* - functions */ -extern int tcp_v4_md5_hash_skb(char *md5_hash, - struct tcp_md5sig_key *key, - struct sock *sk, - struct request_sock *req, - struct sk_buff *skb); - -extern struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk, - struct sock *addr_sk); - -extern int tcp_v4_md5_do_add(struct sock *sk, - __be32 addr, - u8 *newkey, - u8 newkeylen); - -extern int tcp_v4_md5_do_del(struct sock *sk, - __be32 addr); +extern int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, + struct sock *sk, struct request_sock *req, + struct sk_buff *skb); +extern struct tcp_md5sig_key * tcp_v4_md5_lookup(struct sock *sk, + struct sock *addr_sk); +extern int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, u8 *newkey, + u8 newkeylen); +extern int tcp_v4_md5_do_del(struct sock *sk, __be32 addr); #ifdef CONFIG_TCP_MD5SIG #define tcp_twsk_md5_key(twsk) ((twsk)->tw_md5_keylen ? \ @@ -1195,32 +1149,17 @@ extern int tcp_v4_md5_do_del(struct sock *sk, #endif extern struct tcp_md5sig_pool * __percpu *tcp_alloc_md5sig_pool(struct sock *); -extern void tcp_free_md5sig_pool(void); +extern void tcp_free_md5sig_pool(void); + +extern struct tcp_md5sig_pool *tcp_get_md5sig_pool(void); +extern void tcp_put_md5sig_pool(void); -extern struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu); -extern void __tcp_put_md5sig_pool(void); extern int tcp_md5_hash_header(struct tcp_md5sig_pool *, struct tcphdr *); extern int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *, struct sk_buff *, unsigned header_len); extern int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, struct tcp_md5sig_key *key); -static inline -struct tcp_md5sig_pool *tcp_get_md5sig_pool(void) -{ - int cpu = get_cpu(); - struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu); - if (!ret) - put_cpu(); - return ret; -} - -static inline void tcp_put_md5sig_pool(void) -{ - __tcp_put_md5sig_pool(); - put_cpu(); -} - /* write queue abstraction */ static inline void tcp_write_queue_purge(struct sock *sk) { @@ -1419,7 +1358,8 @@ struct tcp_iter_state { sa_family_t family; enum tcp_seq_states state; struct sock *syn_wait_sk; - int bucket, sbucket, num, uid; + int bucket, offset, sbucket, num, uid; + loff_t last_pos; }; extern int tcp_proc_register(struct net *net, struct tcp_seq_afinfo *afinfo); @@ -1440,7 +1380,7 @@ extern int tcp_gro_complete(struct sk_buff *skb); extern int tcp4_gro_complete(struct sk_buff *skb); #ifdef CONFIG_PROC_FS -extern int tcp4_proc_init(void); +extern int tcp4_proc_init(void); extern void tcp4_proc_exit(void); #endif 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/udp.h b/include/net/udp.h index 5348d80b25bb..7abdf305da50 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -157,30 +157,28 @@ static inline void udp_lib_close(struct sock *sk, long timeout) sk_common_release(sk); } -extern int udp_lib_get_port(struct sock *sk, unsigned short snum, - int (*)(const struct sock *,const struct sock *), - unsigned int hash2_nulladdr); +extern int udp_lib_get_port(struct sock *sk, unsigned short snum, + int (*)(const struct sock *,const struct sock *), + unsigned int hash2_nulladdr); /* net/ipv4/udp.c */ -extern int udp_get_port(struct sock *sk, unsigned short snum, - int (*saddr_cmp)(const struct sock *, const struct sock *)); -extern void udp_err(struct sk_buff *, u32); - -extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, +extern int udp_get_port(struct sock *sk, unsigned short snum, + int (*saddr_cmp)(const struct sock *, + const struct sock *)); +extern void udp_err(struct sk_buff *, u32); +extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len); -extern void udp_flush_pending_frames(struct sock *sk); - -extern int udp_rcv(struct sk_buff *skb); -extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); -extern int udp_disconnect(struct sock *sk, int flags); +extern void udp_flush_pending_frames(struct sock *sk); +extern int udp_rcv(struct sk_buff *skb); +extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); +extern int udp_disconnect(struct sock *sk, int flags); extern unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait); -extern int udp_lib_getsockopt(struct sock *sk, int level, int optname, - char __user *optval, int __user *optlen); -extern int udp_lib_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, unsigned int optlen, - int (*push_pending_frames)(struct sock *)); - +extern int udp_lib_getsockopt(struct sock *sk, int level, int optname, + char __user *optval, int __user *optlen); +extern int udp_lib_setsockopt(struct sock *sk, int level, int optname, + char __user *optval, unsigned int optlen, + int (*push_pending_frames)(struct sock *)); extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, __be32 daddr, __be16 dport, int dif); @@ -236,7 +234,7 @@ struct udp_iter_state { extern int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo); extern void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo); -extern int udp4_proc_init(void); +extern int udp4_proc_init(void); extern void udp4_proc_exit(void); #endif 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..fc8f36dd0f5c 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); @@ -1587,7 +1586,7 @@ static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb) static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m) { if (attrs[XFRMA_MARK]) - memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(m)); + memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark)); else m->v = m->m = 0; |