mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-11-01 09:13:37 +00:00 
			
		
		
		
	Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
This commit is contained in:
		
						commit
						5c1f4cac6f
					
				
					 33 changed files with 1010 additions and 735 deletions
				
			
		| 
						 | 
					@ -31,16 +31,19 @@
 | 
				
			||||||
#include <linux/connector.h>
 | 
					#include <linux/connector.h>
 | 
				
			||||||
#include <linux/delay.h>
 | 
					#include <linux/delay.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void cn_queue_wrapper(void *data)
 | 
					void cn_queue_wrapper(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cn_callback_entry *cbq = data;
 | 
						struct cn_callback_data *d = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cbq->cb->callback(cbq->cb->priv);
 | 
						d->callback(d->callback_priv);
 | 
				
			||||||
	cbq->destruct_data(cbq->ddata);
 | 
					
 | 
				
			||||||
	cbq->ddata = NULL;
 | 
						d->destruct_data(d->ddata);
 | 
				
			||||||
 | 
						d->ddata = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kfree(d->free);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct cn_callback_entry *cn_queue_alloc_callback_entry(struct cn_callback *cb)
 | 
					static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struct cb_id *id, void (*callback)(void *))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cn_callback_entry *cbq;
 | 
						struct cn_callback_entry *cbq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,8 +53,11 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(struct cn_callbac
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cbq->cb = cb;
 | 
						snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
 | 
				
			||||||
	INIT_WORK(&cbq->work, &cn_queue_wrapper, cbq);
 | 
						memcpy(&cbq->id.id, id, sizeof(struct cb_id));
 | 
				
			||||||
 | 
						cbq->data.callback = callback;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						INIT_WORK(&cbq->work, &cn_queue_wrapper, &cbq->data);
 | 
				
			||||||
	return cbq;
 | 
						return cbq;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,12 +74,12 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
 | 
				
			||||||
	return ((i1->idx == i2->idx) && (i1->val == i2->val));
 | 
						return ((i1->idx == i2->idx) && (i1->val == i2->val));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb)
 | 
					int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cn_callback_entry *cbq, *__cbq;
 | 
						struct cn_callback_entry *cbq, *__cbq;
 | 
				
			||||||
	int found = 0;
 | 
						int found = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cbq = cn_queue_alloc_callback_entry(cb);
 | 
						cbq = cn_queue_alloc_callback_entry(name, id, callback);
 | 
				
			||||||
	if (!cbq)
 | 
						if (!cbq)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +88,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_bh(&dev->queue_lock);
 | 
						spin_lock_bh(&dev->queue_lock);
 | 
				
			||||||
	list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
 | 
						list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
 | 
				
			||||||
		if (cn_cb_equal(&__cbq->cb->id, &cb->id)) {
 | 
							if (cn_cb_equal(&__cbq->id.id, id)) {
 | 
				
			||||||
			found = 1;
 | 
								found = 1;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -99,7 +105,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cbq->nls = dev->nls;
 | 
						cbq->nls = dev->nls;
 | 
				
			||||||
	cbq->seq = 0;
 | 
						cbq->seq = 0;
 | 
				
			||||||
	cbq->group = cbq->cb->id.idx;
 | 
						cbq->group = cbq->id.id.idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -111,7 +117,7 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_bh(&dev->queue_lock);
 | 
						spin_lock_bh(&dev->queue_lock);
 | 
				
			||||||
	list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) {
 | 
						list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) {
 | 
				
			||||||
		if (cn_cb_equal(&cbq->cb->id, id)) {
 | 
							if (cn_cb_equal(&cbq->id.id, id)) {
 | 
				
			||||||
			list_del(&cbq->callback_entry);
 | 
								list_del(&cbq->callback_entry);
 | 
				
			||||||
			found = 1;
 | 
								found = 1;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,7 +84,7 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask)
 | 
				
			||||||
		spin_lock_bh(&dev->cbdev->queue_lock);
 | 
							spin_lock_bh(&dev->cbdev->queue_lock);
 | 
				
			||||||
		list_for_each_entry(__cbq, &dev->cbdev->queue_list,
 | 
							list_for_each_entry(__cbq, &dev->cbdev->queue_list,
 | 
				
			||||||
				    callback_entry) {
 | 
									    callback_entry) {
 | 
				
			||||||
			if (cn_cb_equal(&__cbq->cb->id, &msg->id)) {
 | 
								if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
 | 
				
			||||||
				found = 1;
 | 
									found = 1;
 | 
				
			||||||
				group = __cbq->group;
 | 
									group = __cbq->group;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -127,42 +127,56 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cn_callback_entry *__cbq;
 | 
						struct cn_callback_entry *__cbq;
 | 
				
			||||||
	struct cn_dev *dev = &cdev;
 | 
						struct cn_dev *dev = &cdev;
 | 
				
			||||||
	int found = 0;
 | 
						int err = -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_bh(&dev->cbdev->queue_lock);
 | 
						spin_lock_bh(&dev->cbdev->queue_lock);
 | 
				
			||||||
	list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
 | 
						list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
 | 
				
			||||||
		if (cn_cb_equal(&__cbq->cb->id, &msg->id)) {
 | 
							if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
 | 
				
			||||||
			/*
 | 
					 | 
				
			||||||
			 * Let's scream if there is some magic and the
 | 
					 | 
				
			||||||
			 * data will arrive asynchronously here.
 | 
					 | 
				
			||||||
			 * [i.e. netlink messages will be queued].
 | 
					 | 
				
			||||||
			 * After the first warning I will fix it
 | 
					 | 
				
			||||||
			 * quickly, but now I think it is
 | 
					 | 
				
			||||||
			 * impossible. --zbr (2004_04_27).
 | 
					 | 
				
			||||||
			 */
 | 
					 | 
				
			||||||
			if (likely(!test_bit(0, &__cbq->work.pending) &&
 | 
								if (likely(!test_bit(0, &__cbq->work.pending) &&
 | 
				
			||||||
					__cbq->ddata == NULL)) {
 | 
										__cbq->data.ddata == NULL)) {
 | 
				
			||||||
				__cbq->cb->priv = msg;
 | 
									__cbq->data.callback_priv = msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				__cbq->ddata = data;
 | 
									__cbq->data.ddata = data;
 | 
				
			||||||
				__cbq->destruct_data = destruct_data;
 | 
									__cbq->data.destruct_data = destruct_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (queue_work(dev->cbdev->cn_queue,
 | 
									if (queue_work(dev->cbdev->cn_queue,
 | 
				
			||||||
						&__cbq->work))
 | 
											&__cbq->work))
 | 
				
			||||||
					found = 1;
 | 
										err = 0;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				printk("%s: cbq->data=%p, "
 | 
									struct work_struct *w;
 | 
				
			||||||
				       "work->pending=%08lx.\n",
 | 
									struct cn_callback_data *d;
 | 
				
			||||||
				       __func__, __cbq->ddata,
 | 
									
 | 
				
			||||||
				       __cbq->work.pending);
 | 
									w = kzalloc(sizeof(*w) + sizeof(*d), GFP_ATOMIC);
 | 
				
			||||||
				WARN_ON(1);
 | 
									if (w) {
 | 
				
			||||||
 | 
										d = (struct cn_callback_data *)(w+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										d->callback_priv = msg;
 | 
				
			||||||
 | 
										d->callback = __cbq->data.callback;
 | 
				
			||||||
 | 
										d->ddata = data;
 | 
				
			||||||
 | 
										d->destruct_data = destruct_data;
 | 
				
			||||||
 | 
										d->free = w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										INIT_LIST_HEAD(&w->entry);
 | 
				
			||||||
 | 
										w->pending = 0;
 | 
				
			||||||
 | 
										w->func = &cn_queue_wrapper;
 | 
				
			||||||
 | 
										w->data = d;
 | 
				
			||||||
 | 
										init_timer(&w->timer);
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										if (queue_work(dev->cbdev->cn_queue, w))
 | 
				
			||||||
 | 
											err = 0;
 | 
				
			||||||
 | 
										else {
 | 
				
			||||||
 | 
											kfree(w);
 | 
				
			||||||
 | 
											err = -EINVAL;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									} else
 | 
				
			||||||
 | 
										err = -ENOMEM;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	spin_unlock_bh(&dev->cbdev->queue_lock);
 | 
						spin_unlock_bh(&dev->cbdev->queue_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return found ? 0 : -ENODEV;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -291,22 +305,10 @@ int cn_add_callback(struct cb_id *id, char *name, void (*callback)(void *))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	struct cn_dev *dev = &cdev;
 | 
						struct cn_dev *dev = &cdev;
 | 
				
			||||||
	struct cn_callback *cb;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cb = kzalloc(sizeof(*cb), GFP_KERNEL);
 | 
						err = cn_queue_add_callback(dev->cbdev, name, id, callback);
 | 
				
			||||||
	if (!cb)
 | 
						if (err)
 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	scnprintf(cb->name, sizeof(cb->name), "%s", name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memcpy(&cb->id, id, sizeof(cb->id));
 | 
					 | 
				
			||||||
	cb->callback = callback;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = cn_queue_add_callback(dev->cbdev, cb);
 | 
					 | 
				
			||||||
	if (err) {
 | 
					 | 
				
			||||||
		kfree(cb);
 | 
					 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cn_notify(id, 0);
 | 
						cn_notify(id, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,12 +104,19 @@ struct cn_queue_dev {
 | 
				
			||||||
	struct sock *nls;
 | 
						struct sock *nls;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct cn_callback {
 | 
					struct cn_callback_id {
 | 
				
			||||||
	unsigned char name[CN_CBQ_NAMELEN];
 | 
						unsigned char name[CN_CBQ_NAMELEN];
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct cb_id id;
 | 
						struct cb_id id;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cn_callback_data {
 | 
				
			||||||
 | 
						void (*destruct_data) (void *);
 | 
				
			||||||
 | 
						void *ddata;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						void *callback_priv;
 | 
				
			||||||
	void (*callback) (void *);
 | 
						void (*callback) (void *);
 | 
				
			||||||
	void *priv;
 | 
					
 | 
				
			||||||
 | 
						void *free;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct cn_callback_entry {
 | 
					struct cn_callback_entry {
 | 
				
			||||||
| 
						 | 
					@ -118,8 +125,8 @@ struct cn_callback_entry {
 | 
				
			||||||
	struct work_struct work;
 | 
						struct work_struct work;
 | 
				
			||||||
	struct cn_queue_dev *pdev;
 | 
						struct cn_queue_dev *pdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void (*destruct_data) (void *);
 | 
						struct cn_callback_id id;
 | 
				
			||||||
	void *ddata;
 | 
						struct cn_callback_data data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int seq, group;
 | 
						int seq, group;
 | 
				
			||||||
	struct sock *nls;
 | 
						struct sock *nls;
 | 
				
			||||||
| 
						 | 
					@ -144,7 +151,7 @@ int cn_add_callback(struct cb_id *, char *, void (*callback) (void *));
 | 
				
			||||||
void cn_del_callback(struct cb_id *);
 | 
					void cn_del_callback(struct cb_id *);
 | 
				
			||||||
int cn_netlink_send(struct cn_msg *, u32, int);
 | 
					int cn_netlink_send(struct cn_msg *, u32, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb);
 | 
					int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *));
 | 
				
			||||||
void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
 | 
					void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *);
 | 
					struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *);
 | 
				
			||||||
| 
						 | 
					@ -152,6 +159,8 @@ void cn_queue_free_dev(struct cn_queue_dev *dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int cn_cb_equal(struct cb_id *, struct cb_id *);
 | 
					int cn_cb_equal(struct cb_id *, struct cb_id *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cn_queue_wrapper(void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int cn_already_initialized;
 | 
					extern int cn_already_initialized;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif				/* __KERNEL__ */
 | 
					#endif				/* __KERNEL__ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,16 +5,14 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This header used to share core functionality between the standalone
 | 
					/* This header used to share core functionality between the standalone
 | 
				
			||||||
   NAT module, and the compatibility layer's use of NAT for masquerading. */
 | 
					   NAT module, and the compatibility layer's use of NAT for masquerading. */
 | 
				
			||||||
extern int ip_nat_init(void);
 | 
					 | 
				
			||||||
extern void ip_nat_cleanup(void);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern unsigned int nat_packet(struct ip_conntrack *ct,
 | 
					extern unsigned int ip_nat_packet(struct ip_conntrack *ct,
 | 
				
			||||||
			       enum ip_conntrack_info conntrackinfo,
 | 
								       enum ip_conntrack_info conntrackinfo,
 | 
				
			||||||
			       unsigned int hooknum,
 | 
								       unsigned int hooknum,
 | 
				
			||||||
			       struct sk_buff **pskb);
 | 
								       struct sk_buff **pskb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int icmp_reply_translation(struct sk_buff **pskb,
 | 
					extern int ip_nat_icmp_reply_translation(struct sk_buff **pskb,
 | 
				
			||||||
				  struct ip_conntrack *ct,
 | 
										 struct ip_conntrack *ct,
 | 
				
			||||||
				  enum ip_nat_manip_type manip,
 | 
										 enum ip_nat_manip_type manip,
 | 
				
			||||||
				  enum ip_conntrack_dir dir);
 | 
										 enum ip_conntrack_dir dir);
 | 
				
			||||||
#endif /* _IP_NAT_CORE_H */
 | 
					#endif /* _IP_NAT_CORE_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,6 +203,7 @@ enum
 | 
				
			||||||
	NET_DECNET=15,
 | 
						NET_DECNET=15,
 | 
				
			||||||
	NET_ECONET=16,
 | 
						NET_ECONET=16,
 | 
				
			||||||
	NET_SCTP=17,
 | 
						NET_SCTP=17,
 | 
				
			||||||
 | 
						NET_LLC=18,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* /proc/sys/kernel/random */
 | 
					/* /proc/sys/kernel/random */
 | 
				
			||||||
| 
						 | 
					@ -522,6 +523,29 @@ enum {
 | 
				
			||||||
	NET_IPX_FORWARDING=2
 | 
						NET_IPX_FORWARDING=2
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* /proc/sys/net/llc */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						NET_LLC2=1,
 | 
				
			||||||
 | 
						NET_LLC_STATION=2,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* /proc/sys/net/llc/llc2 */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						NET_LLC2_TIMEOUT=1,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* /proc/sys/net/llc/station */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						NET_LLC_STATION_ACK_TIMEOUT=1,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* /proc/sys/net/llc/llc2/timeout */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						NET_LLC2_ACK_TIMEOUT=1,
 | 
				
			||||||
 | 
						NET_LLC2_P_TIMEOUT=2,
 | 
				
			||||||
 | 
						NET_LLC2_REJ_TIMEOUT=3,
 | 
				
			||||||
 | 
						NET_LLC2_BUSY_TIMEOUT=4,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* /proc/sys/net/appletalk */
 | 
					/* /proc/sys/net/appletalk */
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,8 @@
 | 
				
			||||||
#include <linux/list.h>
 | 
					#include <linux/list.h>
 | 
				
			||||||
#include <linux/spinlock.h>
 | 
					#include <linux/spinlock.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <asm/atomic.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct net_device;
 | 
					struct net_device;
 | 
				
			||||||
struct packet_type;
 | 
					struct packet_type;
 | 
				
			||||||
struct sk_buff;
 | 
					struct sk_buff;
 | 
				
			||||||
| 
						 | 
					@ -44,6 +46,7 @@ struct llc_sap {
 | 
				
			||||||
	unsigned char	 state;
 | 
						unsigned char	 state;
 | 
				
			||||||
	unsigned char	 p_bit;
 | 
						unsigned char	 p_bit;
 | 
				
			||||||
	unsigned char	 f_bit;
 | 
						unsigned char	 f_bit;
 | 
				
			||||||
 | 
						atomic_t         refcnt;
 | 
				
			||||||
	int		 (*rcv_func)(struct sk_buff *skb,
 | 
						int		 (*rcv_func)(struct sk_buff *skb,
 | 
				
			||||||
				     struct net_device *dev,
 | 
									     struct net_device *dev,
 | 
				
			||||||
				     struct packet_type *pt,
 | 
									     struct packet_type *pt,
 | 
				
			||||||
| 
						 | 
					@ -81,13 +84,27 @@ extern struct llc_sap *llc_sap_open(unsigned char lsap,
 | 
				
			||||||
					       struct net_device *dev,
 | 
										       struct net_device *dev,
 | 
				
			||||||
					       struct packet_type *pt,
 | 
										       struct packet_type *pt,
 | 
				
			||||||
					       struct net_device *orig_dev));
 | 
										       struct net_device *orig_dev));
 | 
				
			||||||
 | 
					static inline void llc_sap_hold(struct llc_sap *sap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						atomic_inc(&sap->refcnt);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void llc_sap_close(struct llc_sap *sap);
 | 
					extern void llc_sap_close(struct llc_sap *sap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void llc_sap_put(struct llc_sap *sap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (atomic_dec_and_test(&sap->refcnt))
 | 
				
			||||||
 | 
							llc_sap_close(sap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern struct llc_sap *llc_sap_find(unsigned char sap_value);
 | 
					extern struct llc_sap *llc_sap_find(unsigned char sap_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
 | 
					extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
 | 
				
			||||||
				     unsigned char *dmac, unsigned char dsap);
 | 
									     unsigned char *dmac, unsigned char dsap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
 | 
				
			||||||
 | 
					extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int llc_station_init(void);
 | 
					extern int llc_station_init(void);
 | 
				
			||||||
extern void llc_station_exit(void);
 | 
					extern void llc_station_exit(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,4 +115,17 @@ extern void llc_proc_exit(void);
 | 
				
			||||||
#define llc_proc_init()	(0)
 | 
					#define llc_proc_init()	(0)
 | 
				
			||||||
#define llc_proc_exit()	do { } while(0)
 | 
					#define llc_proc_exit()	do { } while(0)
 | 
				
			||||||
#endif /* CONFIG_PROC_FS */
 | 
					#endif /* CONFIG_PROC_FS */
 | 
				
			||||||
 | 
					#ifdef CONFIG_SYSCTL
 | 
				
			||||||
 | 
					extern int llc_sysctl_init(void);
 | 
				
			||||||
 | 
					extern void llc_sysctl_exit(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int sysctl_llc2_ack_timeout;
 | 
				
			||||||
 | 
					extern int sysctl_llc2_busy_timeout;
 | 
				
			||||||
 | 
					extern int sysctl_llc2_p_timeout;
 | 
				
			||||||
 | 
					extern int sysctl_llc2_rej_timeout;
 | 
				
			||||||
 | 
					extern int sysctl_llc_station_ack_timeout;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define llc_sysctl_init() (0)
 | 
				
			||||||
 | 
					#define llc_sysctl_exit() do { } while(0)
 | 
				
			||||||
 | 
					#endif /* CONFIG_SYSCTL */
 | 
				
			||||||
#endif /* LLC_H */
 | 
					#endif /* LLC_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,14 +19,14 @@
 | 
				
			||||||
#define LLC_EVENT                1
 | 
					#define LLC_EVENT                1
 | 
				
			||||||
#define LLC_PACKET               2
 | 
					#define LLC_PACKET               2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LLC_P_TIME               2
 | 
					#define LLC2_P_TIME               2
 | 
				
			||||||
#define LLC_ACK_TIME             1
 | 
					#define LLC2_ACK_TIME             1
 | 
				
			||||||
#define LLC_REJ_TIME             3
 | 
					#define LLC2_REJ_TIME             3
 | 
				
			||||||
#define LLC_BUSY_TIME            3
 | 
					#define LLC2_BUSY_TIME            3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct llc_timer {
 | 
					struct llc_timer {
 | 
				
			||||||
	struct timer_list timer;
 | 
						struct timer_list timer;
 | 
				
			||||||
	u16		  expire;	/* timer expire time */
 | 
						unsigned long	  expire;	/* timer expire time */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct llc_sock {
 | 
					struct llc_sock {
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,7 @@ struct llc_sock {
 | 
				
			||||||
	struct llc_addr	    laddr;		/* lsap/mac pair */
 | 
						struct llc_addr	    laddr;		/* lsap/mac pair */
 | 
				
			||||||
	struct llc_addr	    daddr;		/* dsap/mac pair */
 | 
						struct llc_addr	    daddr;		/* dsap/mac pair */
 | 
				
			||||||
	struct net_device   *dev;		/* device to send to remote */
 | 
						struct net_device   *dev;		/* device to send to remote */
 | 
				
			||||||
 | 
						u32		    copied_seq;		/* head of yet unread data */
 | 
				
			||||||
	u8		    retry_count;	/* number of retries */
 | 
						u8		    retry_count;	/* number of retries */
 | 
				
			||||||
	u8		    ack_must_be_send;
 | 
						u8		    ack_must_be_send;
 | 
				
			||||||
	u8		    first_pdu_Ns;
 | 
						u8		    first_pdu_Ns;
 | 
				
			||||||
| 
						 | 
					@ -92,7 +93,8 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb)
 | 
				
			||||||
	return skb->cb[sizeof(skb->cb) - 1];
 | 
						return skb->cb[sizeof(skb->cb) - 1];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern struct sock *llc_sk_alloc(int family, int priority, struct proto *prot);
 | 
					extern struct sock *llc_sk_alloc(int family, unsigned int __nocast priority,
 | 
				
			||||||
 | 
									 struct proto *prot);
 | 
				
			||||||
extern void llc_sk_free(struct sock *sk);
 | 
					extern void llc_sk_free(struct sock *sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void llc_sk_reset(struct sock *sk);
 | 
					extern void llc_sk_reset(struct sock *sk);
 | 
				
			||||||
| 
						 | 
					@ -115,5 +117,4 @@ extern void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern u8 llc_data_accept_state(u8 state);
 | 
					extern u8 llc_data_accept_state(u8 state);
 | 
				
			||||||
extern void llc_build_offset_table(void);
 | 
					extern void llc_build_offset_table(void);
 | 
				
			||||||
extern int llc_release_sockets(struct llc_sap *sap);
 | 
					 | 
				
			||||||
#endif /* LLC_CONN_H */
 | 
					#endif /* LLC_CONN_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,11 +12,15 @@
 | 
				
			||||||
 * See the GNU General Public License for more details.
 | 
					 * See the GNU General Public License for more details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct llc_sap;
 | 
					struct llc_sap;
 | 
				
			||||||
 | 
					struct net_device;
 | 
				
			||||||
struct sk_buff;
 | 
					struct sk_buff;
 | 
				
			||||||
 | 
					struct sock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
 | 
					extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
 | 
				
			||||||
extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim);
 | 
					extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb,
 | 
				
			||||||
extern struct sk_buff *llc_alloc_frame(void);
 | 
								       unsigned char prim);
 | 
				
			||||||
 | 
					extern struct sk_buff *llc_alloc_frame(struct sock *sk,
 | 
				
			||||||
 | 
									       struct net_device *dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
 | 
					extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
 | 
				
			||||||
				        struct sk_buff *skb,
 | 
									        struct sk_buff *skb,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,7 +56,7 @@ struct datalink_proto *register_8022_client(unsigned char type,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void unregister_8022_client(struct datalink_proto *proto)
 | 
					void unregister_8022_client(struct datalink_proto *proto)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	llc_sap_close(proto->sap);
 | 
						llc_sap_put(proto->sap);
 | 
				
			||||||
	kfree(proto);
 | 
						kfree(proto);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,7 +106,7 @@ module_init(snap_init);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __exit snap_exit(void)
 | 
					static void __exit snap_exit(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	llc_sap_close(snap_sap);
 | 
						llc_sap_put(snap_sap);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module_exit(snap_exit);
 | 
					module_exit(snap_exit);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,7 +238,7 @@ unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
		return trllc->ethertype;
 | 
							return trllc->ethertype;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ntohs(ETH_P_802_2);
 | 
						return ntohs(ETH_P_TR_802_2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -574,6 +574,8 @@ struct net_device *dev_getbyhwaddr(unsigned short type, char *ha)
 | 
				
			||||||
	return dev;
 | 
						return dev;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(dev_getbyhwaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct net_device *dev_getfirstbyhwtype(unsigned short type)
 | 
					struct net_device *dev_getfirstbyhwtype(unsigned short type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *dev;
 | 
						struct net_device *dev;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# objects for the standalone - connection tracking / NAT
 | 
					# objects for the standalone - connection tracking / NAT
 | 
				
			||||||
ip_conntrack-objs	:= ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
 | 
					ip_conntrack-objs	:= ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
 | 
				
			||||||
iptable_nat-objs	:= ip_nat_standalone.o ip_nat_rule.o ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
 | 
					ip_nat-objs	:= ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
 | 
				
			||||||
 | 
					iptable_nat-objs	:= ip_nat_rule.o ip_nat_standalone.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ip_conntrack_pptp-objs	:= ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
 | 
					ip_conntrack_pptp-objs	:= ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
 | 
				
			||||||
ip_nat_pptp-objs	:= ip_nat_helper_pptp.o ip_nat_proto_gre.o
 | 
					ip_nat_pptp-objs	:= ip_nat_helper_pptp.o ip_nat_proto_gre.o
 | 
				
			||||||
| 
						 | 
					@ -40,7 +41,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
 | 
				
			||||||
# the three instances of ip_tables
 | 
					# the three instances of ip_tables
 | 
				
			||||||
obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
 | 
					obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
 | 
				
			||||||
obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
 | 
					obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
 | 
				
			||||||
obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
 | 
					obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o ip_nat.o
 | 
				
			||||||
obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
 | 
					obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# matches
 | 
					# matches
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,12 +74,14 @@ ip_nat_proto_find_get(u_int8_t protonum)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return p;
 | 
						return p;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(ip_nat_proto_find_get);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
ip_nat_proto_put(struct ip_nat_protocol *p)
 | 
					ip_nat_proto_put(struct ip_nat_protocol *p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	module_put(p->me);
 | 
						module_put(p->me);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(ip_nat_proto_put);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* We keep an extra hash for each conntrack, for fast searching. */
 | 
					/* We keep an extra hash for each conntrack, for fast searching. */
 | 
				
			||||||
static inline unsigned int
 | 
					static inline unsigned int
 | 
				
			||||||
| 
						 | 
					@ -111,6 +113,7 @@ ip_nat_cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
 | 
				
			||||||
	return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
 | 
						return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
 | 
				
			||||||
				      oldcheck^0xFFFF));
 | 
									      oldcheck^0xFFFF));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ip_nat_cheat_check);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Is this tuple already taken? (not by us) */
 | 
					/* Is this tuple already taken? (not by us) */
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
| 
						 | 
					@ -127,6 +130,7 @@ ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple,
 | 
				
			||||||
	invert_tuplepr(&reply, tuple);
 | 
						invert_tuplepr(&reply, tuple);
 | 
				
			||||||
	return ip_conntrack_tuple_taken(&reply, ignored_conntrack);
 | 
						return ip_conntrack_tuple_taken(&reply, ignored_conntrack);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ip_nat_used_tuple);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* If we source map this tuple so reply looks like reply_tuple, will
 | 
					/* If we source map this tuple so reply looks like reply_tuple, will
 | 
				
			||||||
 * that meet the constraints of range. */
 | 
					 * that meet the constraints of range. */
 | 
				
			||||||
| 
						 | 
					@ -347,6 +351,7 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return NF_ACCEPT;
 | 
						return NF_ACCEPT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ip_nat_setup_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Returns true if succeeded. */
 | 
					/* Returns true if succeeded. */
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
| 
						 | 
					@ -387,10 +392,10 @@ manip_pkt(u_int16_t proto,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Do packet manipulations according to ip_nat_setup_info. */
 | 
					/* Do packet manipulations according to ip_nat_setup_info. */
 | 
				
			||||||
unsigned int nat_packet(struct ip_conntrack *ct,
 | 
					unsigned int ip_nat_packet(struct ip_conntrack *ct,
 | 
				
			||||||
			enum ip_conntrack_info ctinfo,
 | 
								   enum ip_conntrack_info ctinfo,
 | 
				
			||||||
			unsigned int hooknum,
 | 
								   unsigned int hooknum,
 | 
				
			||||||
			struct sk_buff **pskb)
 | 
								   struct sk_buff **pskb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 | 
						enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 | 
				
			||||||
	unsigned long statusbit;
 | 
						unsigned long statusbit;
 | 
				
			||||||
| 
						 | 
					@ -417,12 +422,13 @@ unsigned int nat_packet(struct ip_conntrack *ct,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return NF_ACCEPT;
 | 
						return NF_ACCEPT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(ip_nat_packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Dir is direction ICMP is coming from (opposite to packet it contains) */
 | 
					/* Dir is direction ICMP is coming from (opposite to packet it contains) */
 | 
				
			||||||
int icmp_reply_translation(struct sk_buff **pskb,
 | 
					int ip_nat_icmp_reply_translation(struct sk_buff **pskb,
 | 
				
			||||||
			   struct ip_conntrack *ct,
 | 
									  struct ip_conntrack *ct,
 | 
				
			||||||
			   enum ip_nat_manip_type manip,
 | 
									  enum ip_nat_manip_type manip,
 | 
				
			||||||
			   enum ip_conntrack_dir dir)
 | 
									  enum ip_conntrack_dir dir)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct icmphdr icmp;
 | 
							struct icmphdr icmp;
 | 
				
			||||||
| 
						 | 
					@ -509,6 +515,7 @@ int icmp_reply_translation(struct sk_buff **pskb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(ip_nat_icmp_reply_translation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Protocol registration. */
 | 
					/* Protocol registration. */
 | 
				
			||||||
int ip_nat_protocol_register(struct ip_nat_protocol *proto)
 | 
					int ip_nat_protocol_register(struct ip_nat_protocol *proto)
 | 
				
			||||||
| 
						 | 
					@ -525,6 +532,7 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto)
 | 
				
			||||||
	write_unlock_bh(&ip_nat_lock);
 | 
						write_unlock_bh(&ip_nat_lock);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ip_nat_protocol_register);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Noone stores the protocol anywhere; simply delete it. */
 | 
					/* Noone stores the protocol anywhere; simply delete it. */
 | 
				
			||||||
void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
 | 
					void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
 | 
				
			||||||
| 
						 | 
					@ -536,6 +544,7 @@ void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
 | 
				
			||||||
	/* Someone could be still looking at the proto in a bh. */
 | 
						/* Someone could be still looking at the proto in a bh. */
 | 
				
			||||||
	synchronize_net();
 | 
						synchronize_net();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ip_nat_protocol_unregister);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
 | 
					#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
 | 
				
			||||||
    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
 | 
					    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
 | 
				
			||||||
| 
						 | 
					@ -582,7 +591,7 @@ EXPORT_SYMBOL_GPL(ip_nat_port_nfattr_to_range);
 | 
				
			||||||
EXPORT_SYMBOL_GPL(ip_nat_port_range_to_nfattr);
 | 
					EXPORT_SYMBOL_GPL(ip_nat_port_range_to_nfattr);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int __init ip_nat_init(void)
 | 
					static int __init ip_nat_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t i;
 | 
						size_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -624,10 +633,14 @@ static int clean_nat(struct ip_conntrack *i, void *data)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Not __exit: called from ip_nat_standalone.c:init_or_cleanup() --RR */
 | 
					static void __exit ip_nat_cleanup(void)
 | 
				
			||||||
void ip_nat_cleanup(void)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ip_ct_iterate_cleanup(&clean_nat, NULL);
 | 
						ip_ct_iterate_cleanup(&clean_nat, NULL);
 | 
				
			||||||
	ip_conntrack_destroyed = NULL;
 | 
						ip_conntrack_destroyed = NULL;
 | 
				
			||||||
	vfree(bysource);
 | 
						vfree(bysource);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module_init(ip_nat_init);
 | 
				
			||||||
 | 
					module_exit(ip_nat_cleanup);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -199,6 +199,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
/* Generic function for mangling variable-length address changes inside
 | 
					/* Generic function for mangling variable-length address changes inside
 | 
				
			||||||
 * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
 | 
					 * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
 | 
				
			||||||
| 
						 | 
					@ -256,6 +257,7 @@ ip_nat_mangle_udp_packet(struct sk_buff **pskb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Adjust one found SACK option including checksum correction */
 | 
					/* Adjust one found SACK option including checksum correction */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -399,6 +401,7 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ip_nat_seq_adjust);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Setup NAT on this expected conntrack so it follows master. */
 | 
					/* Setup NAT on this expected conntrack so it follows master. */
 | 
				
			||||||
/* If we fail to get a free NAT slot, we'll get dropped on confirm */
 | 
					/* If we fail to get a free NAT slot, we'll get dropped on confirm */
 | 
				
			||||||
| 
						 | 
					@ -425,3 +428,4 @@ void ip_nat_follow_master(struct ip_conntrack *ct,
 | 
				
			||||||
	/* hook doesn't matter, but it has to do destination manip */
 | 
						/* hook doesn't matter, but it has to do destination manip */
 | 
				
			||||||
	ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
 | 
						ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ip_nat_follow_master);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,8 +108,8 @@ ip_nat_fn(unsigned int hooknum,
 | 
				
			||||||
	case IP_CT_RELATED:
 | 
						case IP_CT_RELATED:
 | 
				
			||||||
	case IP_CT_RELATED+IP_CT_IS_REPLY:
 | 
						case IP_CT_RELATED+IP_CT_IS_REPLY:
 | 
				
			||||||
		if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
 | 
							if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
 | 
				
			||||||
			if (!icmp_reply_translation(pskb, ct, maniptype,
 | 
								if (!ip_nat_icmp_reply_translation(pskb, ct, maniptype,
 | 
				
			||||||
						    CTINFO2DIR(ctinfo)))
 | 
												   CTINFO2DIR(ctinfo)))
 | 
				
			||||||
				return NF_DROP;
 | 
									return NF_DROP;
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				return NF_ACCEPT;
 | 
									return NF_ACCEPT;
 | 
				
			||||||
| 
						 | 
					@ -152,7 +152,7 @@ ip_nat_fn(unsigned int hooknum,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IP_NF_ASSERT(info);
 | 
						IP_NF_ASSERT(info);
 | 
				
			||||||
	return nat_packet(ct, ctinfo, hooknum, pskb);
 | 
						return ip_nat_packet(ct, ctinfo, hooknum, pskb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int
 | 
					static unsigned int
 | 
				
			||||||
| 
						 | 
					@ -325,15 +325,10 @@ static int init_or_cleanup(int init)
 | 
				
			||||||
		printk("ip_nat_init: can't setup rules.\n");
 | 
							printk("ip_nat_init: can't setup rules.\n");
 | 
				
			||||||
		goto cleanup_nothing;
 | 
							goto cleanup_nothing;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ret = ip_nat_init();
 | 
					 | 
				
			||||||
	if (ret < 0) {
 | 
					 | 
				
			||||||
		printk("ip_nat_init: can't setup rules.\n");
 | 
					 | 
				
			||||||
		goto cleanup_rule_init;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ret = nf_register_hook(&ip_nat_in_ops);
 | 
						ret = nf_register_hook(&ip_nat_in_ops);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		printk("ip_nat_init: can't register in hook.\n");
 | 
							printk("ip_nat_init: can't register in hook.\n");
 | 
				
			||||||
		goto cleanup_nat;
 | 
							goto cleanup_rule_init;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ret = nf_register_hook(&ip_nat_out_ops);
 | 
						ret = nf_register_hook(&ip_nat_out_ops);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
| 
						 | 
					@ -374,8 +369,6 @@ static int init_or_cleanup(int init)
 | 
				
			||||||
	nf_unregister_hook(&ip_nat_out_ops);
 | 
						nf_unregister_hook(&ip_nat_out_ops);
 | 
				
			||||||
 cleanup_inops:
 | 
					 cleanup_inops:
 | 
				
			||||||
	nf_unregister_hook(&ip_nat_in_ops);
 | 
						nf_unregister_hook(&ip_nat_in_ops);
 | 
				
			||||||
 cleanup_nat:
 | 
					 | 
				
			||||||
	ip_nat_cleanup();
 | 
					 | 
				
			||||||
 cleanup_rule_init:
 | 
					 cleanup_rule_init:
 | 
				
			||||||
	ip_nat_rule_cleanup();
 | 
						ip_nat_rule_cleanup();
 | 
				
			||||||
 cleanup_nothing:
 | 
					 cleanup_nothing:
 | 
				
			||||||
| 
						 | 
					@ -395,14 +388,4 @@ static void __exit fini(void)
 | 
				
			||||||
module_init(init);
 | 
					module_init(init);
 | 
				
			||||||
module_exit(fini);
 | 
					module_exit(fini);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPORT_SYMBOL(ip_nat_setup_info);
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(ip_nat_protocol_register);
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(ip_nat_protocol_unregister);
 | 
					 | 
				
			||||||
EXPORT_SYMBOL_GPL(ip_nat_proto_find_get);
 | 
					 | 
				
			||||||
EXPORT_SYMBOL_GPL(ip_nat_proto_put);
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(ip_nat_cheat_check);
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(ip_nat_used_tuple);
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(ip_nat_follow_master);
 | 
					 | 
				
			||||||
MODULE_LICENSE("GPL");
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3520,6 +3520,8 @@ int __init addrconf_init(void)
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	register_netdevice_notifier(&ipv6_dev_notf);
 | 
						register_netdevice_notifier(&ipv6_dev_notf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_IPV6_PRIVACY
 | 
					#ifdef CONFIG_IPV6_PRIVACY
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,3 +22,4 @@ llc2-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_conn.o llc_c_st.o llc_pdu.o \
 | 
				
			||||||
	  llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_station.o
 | 
						  llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_station.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
llc2-$(CONFIG_PROC_FS) += llc_proc.o
 | 
					llc2-$(CONFIG_PROC_FS) += llc_proc.o
 | 
				
			||||||
 | 
					llc2-$(CONFIG_SYSCTL)  += sysctl_net_llc.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										535
									
								
								net/llc/af_llc.c
									
										
									
									
									
								
							
							
						
						
									
										535
									
								
								net/llc/af_llc.c
									
										
									
									
									
								
							| 
						 | 
					@ -21,6 +21,7 @@
 | 
				
			||||||
 * See the GNU General Public License for more details.
 | 
					 * See the GNU General Public License for more details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#include <linux/config.h>
 | 
					#include <linux/config.h>
 | 
				
			||||||
 | 
					#include <linux/compiler.h>
 | 
				
			||||||
#include <linux/kernel.h>
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
#include <linux/module.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
#include <linux/rtnetlink.h>
 | 
					#include <linux/rtnetlink.h>
 | 
				
			||||||
| 
						 | 
					@ -37,10 +38,9 @@ static u16 llc_ui_sap_link_no_max[256];
 | 
				
			||||||
static struct sockaddr_llc llc_ui_addrnull;
 | 
					static struct sockaddr_llc llc_ui_addrnull;
 | 
				
			||||||
static struct proto_ops llc_ui_ops;
 | 
					static struct proto_ops llc_ui_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int llc_ui_wait_for_conn(struct sock *sk, int timeout);
 | 
					static int llc_ui_wait_for_conn(struct sock *sk, long timeout);
 | 
				
			||||||
static int llc_ui_wait_for_disc(struct sock *sk, int timeout);
 | 
					static int llc_ui_wait_for_disc(struct sock *sk, long timeout);
 | 
				
			||||||
static int llc_ui_wait_for_data(struct sock *sk, int timeout);
 | 
					static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout);
 | 
				
			||||||
static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
#define dprintk(args...) printk(KERN_DEBUG args)
 | 
					#define dprintk(args...) printk(KERN_DEBUG args)
 | 
				
			||||||
| 
						 | 
					@ -116,12 +116,12 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock)
 | 
				
			||||||
	struct llc_sock* llc = llc_sk(sk);
 | 
						struct llc_sock* llc = llc_sk(sk);
 | 
				
			||||||
	int rc = 0;
 | 
						int rc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (llc_data_accept_state(llc->state) || llc->p_flag) {
 | 
						if (unlikely(llc_data_accept_state(llc->state) || llc->p_flag)) {
 | 
				
			||||||
		int timeout = sock_sndtimeo(sk, noblock);
 | 
							long timeout = sock_sndtimeo(sk, noblock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rc = llc_ui_wait_for_busy_core(sk, timeout);
 | 
							rc = llc_ui_wait_for_busy_core(sk, timeout);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!rc)
 | 
						if (unlikely(!rc))
 | 
				
			||||||
		rc = llc_build_and_send_pkt(sk, skb);
 | 
							rc = llc_build_and_send_pkt(sk, skb);
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -155,7 +155,7 @@ static int llc_ui_create(struct socket *sock, int protocol)
 | 
				
			||||||
	struct sock *sk;
 | 
						struct sock *sk;
 | 
				
			||||||
	int rc = -ESOCKTNOSUPPORT;
 | 
						int rc = -ESOCKTNOSUPPORT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM) {
 | 
						if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) {
 | 
				
			||||||
		rc = -ENOMEM;
 | 
							rc = -ENOMEM;
 | 
				
			||||||
		sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
 | 
							sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
 | 
				
			||||||
		if (sk) {
 | 
							if (sk) {
 | 
				
			||||||
| 
						 | 
					@ -177,7 +177,7 @@ static int llc_ui_release(struct socket *sock)
 | 
				
			||||||
	struct sock *sk = sock->sk;
 | 
						struct sock *sk = sock->sk;
 | 
				
			||||||
	struct llc_sock *llc;
 | 
						struct llc_sock *llc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!sk)
 | 
						if (unlikely(sk == NULL))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	sock_hold(sk);
 | 
						sock_hold(sk);
 | 
				
			||||||
	lock_sock(sk);
 | 
						lock_sock(sk);
 | 
				
			||||||
| 
						 | 
					@ -189,10 +189,6 @@ static int llc_ui_release(struct socket *sock)
 | 
				
			||||||
	if (!sock_flag(sk, SOCK_ZAPPED))
 | 
						if (!sock_flag(sk, SOCK_ZAPPED))
 | 
				
			||||||
		llc_sap_remove_socket(llc->sap, sk);
 | 
							llc_sap_remove_socket(llc->sap, sk);
 | 
				
			||||||
	release_sock(sk);
 | 
						release_sock(sk);
 | 
				
			||||||
	if (llc->sap && hlist_empty(&llc->sap->sk_list.list)) {
 | 
					 | 
				
			||||||
		llc_release_sockets(llc->sap);
 | 
					 | 
				
			||||||
		llc_sap_close(llc->sap);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (llc->dev)
 | 
						if (llc->dev)
 | 
				
			||||||
		dev_put(llc->dev);
 | 
							dev_put(llc->dev);
 | 
				
			||||||
	sock_put(sk);
 | 
						sock_put(sk);
 | 
				
			||||||
| 
						 | 
					@ -221,6 +217,7 @@ static int llc_ui_autoport(void)
 | 
				
			||||||
				llc_ui_sap_last_autoport = i + 2;
 | 
									llc_ui_sap_last_autoport = i + 2;
 | 
				
			||||||
				goto out;
 | 
									goto out;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								llc_sap_put(sap);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
 | 
							llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
 | 
				
			||||||
		tries++;
 | 
							tries++;
 | 
				
			||||||
| 
						 | 
					@ -231,20 +228,13 @@ out:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	llc_ui_autobind - Bind a socket to a specific address.
 | 
					 *	llc_ui_autobind - automatically bind a socket to a sap
 | 
				
			||||||
 *	@sk: Socket to bind an address to.
 | 
					 *	@sock: socket to bind
 | 
				
			||||||
 *	@addr: Address the user wants the socket bound to.
 | 
					 *	@addr: address to connect to
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 	Used by llc_ui_connect and llc_ui_sendmsg when the user hasn't
 | 
				
			||||||
 | 
					 * 	specifically used llc_ui_bind to bind to an specific address/sap
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *	Bind a socket to a specific address. For llc a user is able to bind to
 | 
					 | 
				
			||||||
 *	a specific sap only or mac + sap. If the user only specifies a sap and
 | 
					 | 
				
			||||||
 *	a null dmac (all zeros) the user is attempting to bind to an entire
 | 
					 | 
				
			||||||
 *	sap. This will stop anyone else on the local system from using that
 | 
					 | 
				
			||||||
 *	sap.  If someone else has a mac + sap open the bind to null + sap will
 | 
					 | 
				
			||||||
 *	fail.
 | 
					 | 
				
			||||||
 *	If the user desires to bind to a specific mac + sap, it is possible to
 | 
					 | 
				
			||||||
 *	have multiple sap connections via multiple macs.
 | 
					 | 
				
			||||||
 *	Bind and autobind for that matter must enforce the correct sap usage
 | 
					 | 
				
			||||||
 *	otherwise all hell will break loose.
 | 
					 | 
				
			||||||
 *	Returns: 0 upon success, negative otherwise.
 | 
					 *	Returns: 0 upon success, negative otherwise.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
 | 
					static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
 | 
				
			||||||
| 
						 | 
					@ -285,11 +275,7 @@ out:
 | 
				
			||||||
 *	@addrlen: Length of the uaddr structure.
 | 
					 *	@addrlen: Length of the uaddr structure.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *	Bind a socket to a specific address. For llc a user is able to bind to
 | 
					 *	Bind a socket to a specific address. For llc a user is able to bind to
 | 
				
			||||||
 *	a specific sap only or mac + sap. If the user only specifies a sap and
 | 
					 *	a specific sap only or mac + sap.
 | 
				
			||||||
 *	a null dmac (all zeros) the user is attempting to bind to an entire
 | 
					 | 
				
			||||||
 *	sap. This will stop anyone else on the local system from using that
 | 
					 | 
				
			||||||
 *	sap. If someone else has a mac + sap open the bind to null + sap will
 | 
					 | 
				
			||||||
 *	fail.
 | 
					 | 
				
			||||||
 *	If the user desires to bind to a specific mac + sap, it is possible to
 | 
					 *	If the user desires to bind to a specific mac + sap, it is possible to
 | 
				
			||||||
 *	have multiple sap connections via multiple macs.
 | 
					 *	have multiple sap connections via multiple macs.
 | 
				
			||||||
 *	Bind and autobind for that matter must enforce the correct sap usage
 | 
					 *	Bind and autobind for that matter must enforce the correct sap usage
 | 
				
			||||||
| 
						 | 
					@ -305,10 +291,16 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
 | 
				
			||||||
	int rc = -EINVAL;
 | 
						int rc = -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap);
 | 
						dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap);
 | 
				
			||||||
	if (!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))
 | 
						if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr)))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = -EAFNOSUPPORT;
 | 
						rc = -EAFNOSUPPORT;
 | 
				
			||||||
	if (addr->sllc_family != AF_LLC)
 | 
						if (unlikely(addr->sllc_family != AF_LLC))
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						rc = -ENODEV;
 | 
				
			||||||
 | 
						rtnl_lock();
 | 
				
			||||||
 | 
						llc->dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_mac);
 | 
				
			||||||
 | 
						rtnl_unlock();
 | 
				
			||||||
 | 
						if (!llc->dev)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	if (!addr->sllc_sap) {
 | 
						if (!addr->sllc_sap) {
 | 
				
			||||||
		rc = -EUSERS;
 | 
							rc = -EUSERS;
 | 
				
			||||||
| 
						 | 
					@ -322,6 +314,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
 | 
				
			||||||
		rc = -EBUSY; /* some other network layer is using the sap */
 | 
							rc = -EBUSY; /* some other network layer is using the sap */
 | 
				
			||||||
		if (!sap)
 | 
							if (!sap)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
 | 
							llc_sap_hold(sap);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct llc_addr laddr, daddr;
 | 
							struct llc_addr laddr, daddr;
 | 
				
			||||||
		struct sock *ask;
 | 
							struct sock *ask;
 | 
				
			||||||
| 
						 | 
					@ -338,7 +331,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
 | 
				
			||||||
		ask = llc_lookup_established(sap, &daddr, &laddr);
 | 
							ask = llc_lookup_established(sap, &daddr, &laddr);
 | 
				
			||||||
		if (ask) {
 | 
							if (ask) {
 | 
				
			||||||
			sock_put(ask);
 | 
								sock_put(ask);
 | 
				
			||||||
			goto out;
 | 
								goto out_put;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	llc->laddr.lsap = addr->sllc_sap;
 | 
						llc->laddr.lsap = addr->sllc_sap;
 | 
				
			||||||
| 
						 | 
					@ -348,6 +341,8 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
 | 
				
			||||||
	llc_sap_add_socket(sap, sk);
 | 
						llc_sap_add_socket(sap, sk);
 | 
				
			||||||
	sock_reset_flag(sk, SOCK_ZAPPED);
 | 
						sock_reset_flag(sk, SOCK_ZAPPED);
 | 
				
			||||||
	rc = 0;
 | 
						rc = 0;
 | 
				
			||||||
 | 
					out_put:
 | 
				
			||||||
 | 
						llc_sap_put(sap);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -369,7 +364,7 @@ static int llc_ui_shutdown(struct socket *sock, int how)
 | 
				
			||||||
	int rc = -ENOTCONN;
 | 
						int rc = -ENOTCONN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lock_sock(sk);
 | 
						lock_sock(sk);
 | 
				
			||||||
	if (sk->sk_state != TCP_ESTABLISHED)
 | 
						if (unlikely(sk->sk_state != TCP_ESTABLISHED))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = -EINVAL;
 | 
						rc = -EINVAL;
 | 
				
			||||||
	if (how != 2)
 | 
						if (how != 2)
 | 
				
			||||||
| 
						 | 
					@ -404,14 +399,18 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
 | 
				
			||||||
	struct sock *sk = sock->sk;
 | 
						struct sock *sk = sock->sk;
 | 
				
			||||||
	struct llc_sock *llc = llc_sk(sk);
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
	struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
 | 
						struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
 | 
				
			||||||
	struct net_device *dev;
 | 
					 | 
				
			||||||
	int rc = -EINVAL;
 | 
						int rc = -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lock_sock(sk);
 | 
						lock_sock(sk);
 | 
				
			||||||
	if (addrlen != sizeof(*addr))
 | 
						if (unlikely(addrlen != sizeof(*addr)))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = -EAFNOSUPPORT;
 | 
						rc = -EAFNOSUPPORT;
 | 
				
			||||||
	if (addr->sllc_family != AF_LLC)
 | 
						if (unlikely(addr->sllc_family != AF_LLC))
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						if (unlikely(sk->sk_type != SOCK_STREAM))
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						rc = -EALREADY;
 | 
				
			||||||
 | 
						if (unlikely(sock->state == SS_CONNECTING))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	/* bind connection to sap if user hasn't done it. */
 | 
						/* bind connection to sap if user hasn't done it. */
 | 
				
			||||||
	if (sock_flag(sk, SOCK_ZAPPED)) {
 | 
						if (sock_flag(sk, SOCK_ZAPPED)) {
 | 
				
			||||||
| 
						 | 
					@ -419,19 +418,13 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
 | 
				
			||||||
		rc = llc_ui_autobind(sock, addr);
 | 
							rc = llc_ui_autobind(sock, addr);
 | 
				
			||||||
		if (rc)
 | 
							if (rc)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		llc->daddr.lsap = addr->sllc_sap;
 | 
					 | 
				
			||||||
		memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dev = llc->dev;
 | 
						llc->daddr.lsap = addr->sllc_sap;
 | 
				
			||||||
	if (sk->sk_type != SOCK_STREAM)
 | 
						memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	rc = -EALREADY;
 | 
					 | 
				
			||||||
	if (sock->state == SS_CONNECTING)
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	sock->state = SS_CONNECTING;
 | 
						sock->state = SS_CONNECTING;
 | 
				
			||||||
	sk->sk_state   = TCP_SYN_SENT;
 | 
						sk->sk_state   = TCP_SYN_SENT;
 | 
				
			||||||
	llc->link   = llc_ui_next_link_no(llc->sap->laddr.lsap);
 | 
						llc->link   = llc_ui_next_link_no(llc->sap->laddr.lsap);
 | 
				
			||||||
	rc = llc_establish_connection(sk, dev->dev_addr,
 | 
						rc = llc_establish_connection(sk, llc->dev->dev_addr,
 | 
				
			||||||
				      addr->sllc_mac, addr->sllc_sap);
 | 
									      addr->sllc_mac, addr->sllc_sap);
 | 
				
			||||||
	if (rc) {
 | 
						if (rc) {
 | 
				
			||||||
		dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__);
 | 
							dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__);
 | 
				
			||||||
| 
						 | 
					@ -439,12 +432,30 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
 | 
				
			||||||
		sk->sk_state = TCP_CLOSE;
 | 
							sk->sk_state = TCP_CLOSE;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rc = llc_ui_wait_for_conn(sk, sk->sk_rcvtimeo);
 | 
					
 | 
				
			||||||
	if (rc)
 | 
						if (sk->sk_state == TCP_SYN_SENT) {
 | 
				
			||||||
		dprintk("%s: llc_ui_wait_for_conn failed=%d\n", __FUNCTION__, rc);
 | 
							const long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!timeo || !llc_ui_wait_for_conn(sk, timeo))
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rc = sock_intr_errno(timeo);
 | 
				
			||||||
 | 
							if (signal_pending(current))
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sk->sk_state == TCP_CLOSE)
 | 
				
			||||||
 | 
							goto sock_error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sock->state = SS_CONNECTED;
 | 
				
			||||||
 | 
						rc = 0;
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	release_sock(sk);
 | 
						release_sock(sk);
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
 | 
					sock_error:
 | 
				
			||||||
 | 
						rc = sock_error(sk) ? : -ECONNABORTED;
 | 
				
			||||||
 | 
						sock->state = SS_UNCONNECTED;
 | 
				
			||||||
 | 
						goto out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -461,10 +472,10 @@ static int llc_ui_listen(struct socket *sock, int backlog)
 | 
				
			||||||
	int rc = -EINVAL;
 | 
						int rc = -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lock_sock(sk);
 | 
						lock_sock(sk);
 | 
				
			||||||
	if (sock->state != SS_UNCONNECTED)
 | 
						if (unlikely(sock->state != SS_UNCONNECTED))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = -EOPNOTSUPP;
 | 
						rc = -EOPNOTSUPP;
 | 
				
			||||||
	if (sk->sk_type != SOCK_STREAM)
 | 
						if (unlikely(sk->sk_type != SOCK_STREAM))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = -EAGAIN;
 | 
						rc = -EAGAIN;
 | 
				
			||||||
	if (sock_flag(sk, SOCK_ZAPPED))
 | 
						if (sock_flag(sk, SOCK_ZAPPED))
 | 
				
			||||||
| 
						 | 
					@ -483,86 +494,14 @@ out:
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int llc_ui_wait_for_disc(struct sock *sk, int timeout)
 | 
					static int llc_ui_wait_for_disc(struct sock *sk, long timeout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	DECLARE_WAITQUEUE(wait, current);
 | 
						DEFINE_WAIT(wait);
 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	add_wait_queue_exclusive(sk->sk_sleep, &wait);
 | 
					 | 
				
			||||||
	for (;;) {
 | 
					 | 
				
			||||||
		__set_current_state(TASK_INTERRUPTIBLE);
 | 
					 | 
				
			||||||
		rc = 0;
 | 
					 | 
				
			||||||
		if (sk->sk_state != TCP_CLOSE) {
 | 
					 | 
				
			||||||
			release_sock(sk);
 | 
					 | 
				
			||||||
			timeout = schedule_timeout(timeout);
 | 
					 | 
				
			||||||
			lock_sock(sk);
 | 
					 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		rc = -ERESTARTSYS;
 | 
					 | 
				
			||||||
		if (signal_pending(current))
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		rc = -EAGAIN;
 | 
					 | 
				
			||||||
		if (!timeout)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	__set_current_state(TASK_RUNNING);
 | 
					 | 
				
			||||||
	remove_wait_queue(sk->sk_sleep, &wait);
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int llc_ui_wait_for_conn(struct sock *sk, int timeout)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	DECLARE_WAITQUEUE(wait, current);
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	add_wait_queue_exclusive(sk->sk_sleep, &wait);
 | 
					 | 
				
			||||||
	for (;;) {
 | 
					 | 
				
			||||||
		__set_current_state(TASK_INTERRUPTIBLE);
 | 
					 | 
				
			||||||
		rc = -EAGAIN;
 | 
					 | 
				
			||||||
		if (sk->sk_state == TCP_CLOSE)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		rc = 0;
 | 
					 | 
				
			||||||
		if (sk->sk_state != TCP_ESTABLISHED) {
 | 
					 | 
				
			||||||
			release_sock(sk);
 | 
					 | 
				
			||||||
			timeout = schedule_timeout(timeout);
 | 
					 | 
				
			||||||
			lock_sock(sk);
 | 
					 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		rc = -ERESTARTSYS;
 | 
					 | 
				
			||||||
		if (signal_pending(current))
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		rc = -EAGAIN;
 | 
					 | 
				
			||||||
		if (!timeout)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	__set_current_state(TASK_RUNNING);
 | 
					 | 
				
			||||||
	remove_wait_queue(sk->sk_sleep, &wait);
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int llc_ui_wait_for_data(struct sock *sk, int timeout)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	DECLARE_WAITQUEUE(wait, current);
 | 
					 | 
				
			||||||
	int rc = 0;
 | 
						int rc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	add_wait_queue_exclusive(sk->sk_sleep, &wait);
 | 
						while (1) {
 | 
				
			||||||
	for (;;) {
 | 
							prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 | 
				
			||||||
		__set_current_state(TASK_INTERRUPTIBLE);
 | 
							if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE))
 | 
				
			||||||
		if (sk->sk_shutdown & RCV_SHUTDOWN)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * Well, if we have backlog, try to process it now.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
                if (sk->sk_backlog.tail) {
 | 
					 | 
				
			||||||
			release_sock(sk);
 | 
					 | 
				
			||||||
			lock_sock(sk);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		rc = 0;
 | 
					 | 
				
			||||||
		if (skb_queue_empty(&sk->sk_receive_queue)) {
 | 
					 | 
				
			||||||
			release_sock(sk);
 | 
					 | 
				
			||||||
			timeout = schedule_timeout(timeout);
 | 
					 | 
				
			||||||
			lock_sock(sk);
 | 
					 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		rc = -ERESTARTSYS;
 | 
							rc = -ERESTARTSYS;
 | 
				
			||||||
		if (signal_pending(current))
 | 
							if (signal_pending(current))
 | 
				
			||||||
| 
						 | 
					@ -570,31 +509,40 @@ static int llc_ui_wait_for_data(struct sock *sk, int timeout)
 | 
				
			||||||
		rc = -EAGAIN;
 | 
							rc = -EAGAIN;
 | 
				
			||||||
		if (!timeout)
 | 
							if (!timeout)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							rc = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	__set_current_state(TASK_RUNNING);
 | 
						finish_wait(sk->sk_sleep, &wait);
 | 
				
			||||||
	remove_wait_queue(sk->sk_sleep, &wait);
 | 
					 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout)
 | 
					static int llc_ui_wait_for_conn(struct sock *sk, long timeout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	DECLARE_WAITQUEUE(wait, current);
 | 
						DEFINE_WAIT(wait);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (1) {
 | 
				
			||||||
 | 
							prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 | 
				
			||||||
 | 
							if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT))
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							if (signal_pending(current) || !timeout)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						finish_wait(sk->sk_sleep, &wait);
 | 
				
			||||||
 | 
						return timeout;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DEFINE_WAIT(wait);
 | 
				
			||||||
	struct llc_sock *llc = llc_sk(sk);
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
	int rc;
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	add_wait_queue_exclusive(sk->sk_sleep, &wait);
 | 
						while (1) {
 | 
				
			||||||
	for (;;) {
 | 
							prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 | 
				
			||||||
		dprintk("%s: looping...\n", __FUNCTION__);
 | 
					 | 
				
			||||||
		__set_current_state(TASK_INTERRUPTIBLE);
 | 
					 | 
				
			||||||
		rc = -ENOTCONN;
 | 
					 | 
				
			||||||
		if (sk->sk_shutdown & RCV_SHUTDOWN)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		rc = 0;
 | 
							rc = 0;
 | 
				
			||||||
		if (llc_data_accept_state(llc->state) || llc->p_flag) {
 | 
							if (sk_wait_event(sk, &timeout,
 | 
				
			||||||
			release_sock(sk);
 | 
									  (sk->sk_shutdown & RCV_SHUTDOWN) ||
 | 
				
			||||||
			timeout = schedule_timeout(timeout);
 | 
									  (!llc_data_accept_state(llc->state) &&
 | 
				
			||||||
			lock_sock(sk);
 | 
									   !llc->p_flag)))
 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		rc = -ERESTARTSYS;
 | 
							rc = -ERESTARTSYS;
 | 
				
			||||||
		if (signal_pending(current))
 | 
							if (signal_pending(current))
 | 
				
			||||||
| 
						 | 
					@ -603,8 +551,35 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout)
 | 
				
			||||||
		if (!timeout)
 | 
							if (!timeout)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	__set_current_state(TASK_RUNNING);
 | 
						finish_wait(sk->sk_sleep, &wait);
 | 
				
			||||||
	remove_wait_queue(sk->sk_sleep, &wait);
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int llc_wait_data(struct sock *sk, long timeo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (1) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * POSIX 1003.1g mandates this order.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (sk->sk_err) {
 | 
				
			||||||
 | 
								rc = sock_error(sk);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							rc = 0;
 | 
				
			||||||
 | 
							if (sk->sk_shutdown & RCV_SHUTDOWN)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							rc = -EAGAIN;
 | 
				
			||||||
 | 
							if (!timeo)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							rc = sock_intr_errno(timeo);
 | 
				
			||||||
 | 
							if (signal_pending(current))
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							rc = 0;
 | 
				
			||||||
 | 
							if (sk_wait_data(sk, &timeo))
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -627,15 +602,18 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
 | 
				
			||||||
	dprintk("%s: accepting on %02X\n", __FUNCTION__,
 | 
						dprintk("%s: accepting on %02X\n", __FUNCTION__,
 | 
				
			||||||
	        llc_sk(sk)->laddr.lsap);
 | 
						        llc_sk(sk)->laddr.lsap);
 | 
				
			||||||
	lock_sock(sk);
 | 
						lock_sock(sk);
 | 
				
			||||||
	if (sk->sk_type != SOCK_STREAM)
 | 
						if (unlikely(sk->sk_type != SOCK_STREAM))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = -EINVAL;
 | 
						rc = -EINVAL;
 | 
				
			||||||
	if (sock->state != SS_UNCONNECTED || sk->sk_state != TCP_LISTEN)
 | 
						if (unlikely(sock->state != SS_UNCONNECTED ||
 | 
				
			||||||
 | 
							     sk->sk_state != TCP_LISTEN))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	/* wait for a connection to arrive. */
 | 
						/* wait for a connection to arrive. */
 | 
				
			||||||
	rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo);
 | 
						if (skb_queue_empty(&sk->sk_receive_queue)) {
 | 
				
			||||||
	if (rc)
 | 
							rc = llc_wait_data(sk, sk->sk_rcvtimeo);
 | 
				
			||||||
		goto out;
 | 
							if (rc)
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	dprintk("%s: got a new connection on %02X\n", __FUNCTION__,
 | 
						dprintk("%s: got a new connection on %02X\n", __FUNCTION__,
 | 
				
			||||||
	        llc_sk(sk)->laddr.lsap);
 | 
						        llc_sk(sk)->laddr.lsap);
 | 
				
			||||||
	skb = skb_dequeue(&sk->sk_receive_queue);
 | 
						skb = skb_dequeue(&sk->sk_receive_queue);
 | 
				
			||||||
| 
						 | 
					@ -657,7 +635,6 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
 | 
				
			||||||
	/* put original socket back into a clean listen state. */
 | 
						/* put original socket back into a clean listen state. */
 | 
				
			||||||
	sk->sk_state = TCP_LISTEN;
 | 
						sk->sk_state = TCP_LISTEN;
 | 
				
			||||||
	sk->sk_ack_backlog--;
 | 
						sk->sk_ack_backlog--;
 | 
				
			||||||
	skb->sk = NULL;
 | 
					 | 
				
			||||||
	dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
 | 
						dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
 | 
				
			||||||
		llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
 | 
							llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
 | 
				
			||||||
frees:
 | 
					frees:
 | 
				
			||||||
| 
						 | 
					@ -671,56 +648,167 @@ out:
 | 
				
			||||||
 *	llc_ui_recvmsg - copy received data to the socket user.
 | 
					 *	llc_ui_recvmsg - copy received data to the socket user.
 | 
				
			||||||
 *	@sock: Socket to copy data from.
 | 
					 *	@sock: Socket to copy data from.
 | 
				
			||||||
 *	@msg: Various user space related information.
 | 
					 *	@msg: Various user space related information.
 | 
				
			||||||
 *	@size: Size of user buffer.
 | 
					 *	@len: Size of user buffer.
 | 
				
			||||||
 *	@flags: User specified flags.
 | 
					 *	@flags: User specified flags.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *	Copy received data to the socket user.
 | 
					 *	Copy received data to the socket user.
 | 
				
			||||||
 *	Returns non-negative upon success, negative otherwise.
 | 
					 *	Returns non-negative upon success, negative otherwise.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
 | 
					static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
 | 
				
			||||||
			  struct msghdr *msg, size_t size, int flags)
 | 
								  struct msghdr *msg, size_t len, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock *sk = sock->sk;
 | 
					 | 
				
			||||||
	struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;
 | 
						struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;
 | 
				
			||||||
	struct sk_buff *skb;
 | 
						const int nonblock = flags & MSG_DONTWAIT;
 | 
				
			||||||
 | 
						struct sk_buff *skb = NULL;
 | 
				
			||||||
 | 
						struct sock *sk = sock->sk;
 | 
				
			||||||
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
	size_t copied = 0;
 | 
						size_t copied = 0;
 | 
				
			||||||
	int rc = -ENOMEM, timeout;
 | 
						u32 peek_seq = 0;
 | 
				
			||||||
	int noblock = flags & MSG_DONTWAIT;
 | 
						u32 *seq;
 | 
				
			||||||
 | 
						unsigned long used;
 | 
				
			||||||
 | 
						int target;	/* Read at least this many bytes */
 | 
				
			||||||
 | 
						long timeo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__,
 | 
					 | 
				
			||||||
		llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
 | 
					 | 
				
			||||||
	lock_sock(sk);
 | 
						lock_sock(sk);
 | 
				
			||||||
	timeout = sock_rcvtimeo(sk, noblock);
 | 
						copied = -ENOTCONN;
 | 
				
			||||||
	rc = llc_ui_wait_for_data(sk, timeout);
 | 
						if (sk->sk_state == TCP_LISTEN)
 | 
				
			||||||
	if (rc) {
 | 
					 | 
				
			||||||
		dprintk("%s: llc_ui_wait_for_data failed recv "
 | 
					 | 
				
			||||||
			"in %02X from %02X\n", __FUNCTION__,
 | 
					 | 
				
			||||||
			llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
 | 
					 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
	skb = skb_dequeue(&sk->sk_receive_queue);
 | 
						timeo = sock_rcvtimeo(sk, nonblock);
 | 
				
			||||||
	if (!skb) /* shutdown */
 | 
					
 | 
				
			||||||
		goto out;
 | 
						seq = &llc->copied_seq;
 | 
				
			||||||
	copied = skb->len;
 | 
						if (flags & MSG_PEEK) {
 | 
				
			||||||
	if (copied > size)
 | 
							peek_seq = llc->copied_seq;
 | 
				
			||||||
		copied = size;
 | 
							seq = &peek_seq;
 | 
				
			||||||
	rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 | 
					 	}
 | 
				
			||||||
	if (rc)
 | 
					
 | 
				
			||||||
		goto dgram_free;
 | 
						target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
 | 
				
			||||||
	if (skb->len > copied) {
 | 
						copied = 0;
 | 
				
			||||||
		skb_pull(skb, copied);
 | 
					
 | 
				
			||||||
		skb_queue_head(&sk->sk_receive_queue, skb);
 | 
						do {
 | 
				
			||||||
	}
 | 
							u32 offset;
 | 
				
			||||||
	if (uaddr)
 | 
					
 | 
				
			||||||
		memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
 | 
							/*
 | 
				
			||||||
	msg->msg_namelen = sizeof(*uaddr);
 | 
							 * We need to check signals first, to get correct SIGURG
 | 
				
			||||||
	if (!skb->next) {
 | 
							 * handling. FIXME: Need to check this doesn't impact 1003.1g
 | 
				
			||||||
dgram_free:
 | 
							 * and move it down to the bottom of the loop
 | 
				
			||||||
		kfree_skb(skb);
 | 
							 */
 | 
				
			||||||
	}
 | 
							if (signal_pending(current)) {
 | 
				
			||||||
 | 
								if (copied)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								copied = timeo ? sock_intr_errno(timeo) : -EAGAIN;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Next get a buffer. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							skb = skb_peek(&sk->sk_receive_queue);
 | 
				
			||||||
 | 
							if (skb) {
 | 
				
			||||||
 | 
								offset = *seq;
 | 
				
			||||||
 | 
								goto found_ok_skb;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/* Well, if we have backlog, try to process it now yet. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (copied >= target && !sk->sk_backlog.tail)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (copied) {
 | 
				
			||||||
 | 
								if (sk->sk_err ||
 | 
				
			||||||
 | 
								    sk->sk_state == TCP_CLOSE ||
 | 
				
			||||||
 | 
								    (sk->sk_shutdown & RCV_SHUTDOWN) ||
 | 
				
			||||||
 | 
								    !timeo ||
 | 
				
			||||||
 | 
								    (flags & MSG_PEEK))
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if (sock_flag(sk, SOCK_DONE))
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (sk->sk_err) {
 | 
				
			||||||
 | 
									copied = sock_error(sk);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (sk->sk_shutdown & RCV_SHUTDOWN)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (sk->sk_state == TCP_CLOSE) {
 | 
				
			||||||
 | 
									if (!sock_flag(sk, SOCK_DONE)) {
 | 
				
			||||||
 | 
										/*
 | 
				
			||||||
 | 
										 * This occurs when user tries to read
 | 
				
			||||||
 | 
										 * from never connected socket.
 | 
				
			||||||
 | 
										 */
 | 
				
			||||||
 | 
										copied = -ENOTCONN;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (!timeo) {
 | 
				
			||||||
 | 
									copied = -EAGAIN;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (copied >= target) { /* Do not sleep, just process backlog. */
 | 
				
			||||||
 | 
								release_sock(sk);
 | 
				
			||||||
 | 
								lock_sock(sk);
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								sk_wait_data(sk, &timeo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((flags & MSG_PEEK) && peek_seq != llc->copied_seq) {
 | 
				
			||||||
 | 
								if (net_ratelimit())
 | 
				
			||||||
 | 
									printk(KERN_DEBUG "LLC(%s:%d): Application "
 | 
				
			||||||
 | 
											  "bug, race in MSG_PEEK.\n",
 | 
				
			||||||
 | 
									       current->comm, current->pid);
 | 
				
			||||||
 | 
								peek_seq = llc->copied_seq;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							continue;
 | 
				
			||||||
 | 
						found_ok_skb:
 | 
				
			||||||
 | 
							/* Ok so how much can we use? */
 | 
				
			||||||
 | 
							used = skb->len - offset;
 | 
				
			||||||
 | 
							if (len < used)
 | 
				
			||||||
 | 
								used = len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!(flags & MSG_TRUNC)) {
 | 
				
			||||||
 | 
								int rc = skb_copy_datagram_iovec(skb, offset,
 | 
				
			||||||
 | 
												 msg->msg_iov, used);
 | 
				
			||||||
 | 
								if (rc) {
 | 
				
			||||||
 | 
									/* Exception. Bailout! */
 | 
				
			||||||
 | 
									if (!copied)
 | 
				
			||||||
 | 
										copied = -EFAULT;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							*seq += used;
 | 
				
			||||||
 | 
							copied += used;
 | 
				
			||||||
 | 
							len -= used;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (used + offset < skb->len)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!(flags & MSG_PEEK)) {
 | 
				
			||||||
 | 
								sk_eat_skb(sk, skb);
 | 
				
			||||||
 | 
								*seq = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} while (len > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 
 | 
				
			||||||
 | 
						 * According to UNIX98, msg_name/msg_namelen are ignored
 | 
				
			||||||
 | 
						 * on connected socket. -ANK
 | 
				
			||||||
 | 
						 * But... af_llc still doesn't have separate sets of methods for
 | 
				
			||||||
 | 
						 * SOCK_DGRAM and SOCK_STREAM :-( So we have to do this test, will
 | 
				
			||||||
 | 
						 * eventually fix this tho :-) -acme
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (sk->sk_type == SOCK_DGRAM)
 | 
				
			||||||
 | 
							goto copy_uaddr;
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	release_sock(sk);
 | 
						release_sock(sk);
 | 
				
			||||||
	return rc ? : copied;
 | 
						return copied;
 | 
				
			||||||
 | 
					copy_uaddr:
 | 
				
			||||||
 | 
						if (uaddr != NULL && skb != NULL) {
 | 
				
			||||||
 | 
							memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
 | 
				
			||||||
 | 
							msg->msg_namelen = sizeof(*uaddr);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						goto out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -740,7 +828,6 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
 | 
				
			||||||
	struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name;
 | 
						struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name;
 | 
				
			||||||
	int flags = msg->msg_flags;
 | 
						int flags = msg->msg_flags;
 | 
				
			||||||
	int noblock = flags & MSG_DONTWAIT;
 | 
						int noblock = flags & MSG_DONTWAIT;
 | 
				
			||||||
	struct net_device *dev;
 | 
					 | 
				
			||||||
	struct sk_buff *skb;
 | 
						struct sk_buff *skb;
 | 
				
			||||||
	size_t size = 0;
 | 
						size_t size = 0;
 | 
				
			||||||
	int rc = -EINVAL, copied = 0, hdrlen;
 | 
						int rc = -EINVAL, copied = 0, hdrlen;
 | 
				
			||||||
| 
						 | 
					@ -763,19 +850,17 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
 | 
				
			||||||
		if (rc)
 | 
							if (rc)
 | 
				
			||||||
			goto release;
 | 
								goto release;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dev = llc->dev;
 | 
						hdrlen = llc->dev->hard_header_len + llc_ui_header_len(sk, addr);
 | 
				
			||||||
	hdrlen = dev->hard_header_len + llc_ui_header_len(sk, addr);
 | 
					 | 
				
			||||||
	size = hdrlen + len;
 | 
						size = hdrlen + len;
 | 
				
			||||||
	if (size > dev->mtu)
 | 
						if (size > llc->dev->mtu)
 | 
				
			||||||
		size = dev->mtu;
 | 
							size = llc->dev->mtu;
 | 
				
			||||||
	copied = size - hdrlen;
 | 
						copied = size - hdrlen;
 | 
				
			||||||
	release_sock(sk);
 | 
						release_sock(sk);
 | 
				
			||||||
	skb = sock_alloc_send_skb(sk, size, noblock, &rc);
 | 
						skb = sock_alloc_send_skb(sk, size, noblock, &rc);
 | 
				
			||||||
	lock_sock(sk);
 | 
						lock_sock(sk);
 | 
				
			||||||
	if (!skb)
 | 
						if (!skb)
 | 
				
			||||||
		goto release;
 | 
							goto release;
 | 
				
			||||||
	skb->sk	      = sk;
 | 
						skb->dev      = llc->dev;
 | 
				
			||||||
	skb->dev      = dev;
 | 
					 | 
				
			||||||
	skb->protocol = llc_proto_type(addr->sllc_arphrd);
 | 
						skb->protocol = llc_proto_type(addr->sllc_arphrd);
 | 
				
			||||||
	skb_reserve(skb, hdrlen); 
 | 
						skb_reserve(skb, hdrlen); 
 | 
				
			||||||
	rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied);
 | 
						rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied);
 | 
				
			||||||
| 
						 | 
					@ -800,15 +885,13 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
 | 
				
			||||||
	if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua))
 | 
						if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = llc_ui_send_data(sk, skb, noblock);
 | 
						rc = llc_ui_send_data(sk, skb, noblock);
 | 
				
			||||||
	if (rc)
 | 
					 | 
				
			||||||
		dprintk("%s: llc_ui_send_data failed: %d\n", __FUNCTION__, rc);
 | 
					 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	if (rc)
 | 
						if (rc) {
 | 
				
			||||||
		kfree_skb(skb);
 | 
							kfree_skb(skb);
 | 
				
			||||||
release:
 | 
					release:
 | 
				
			||||||
	if (rc)
 | 
					 | 
				
			||||||
		dprintk("%s: failed sending from %02X to %02X: %d\n",
 | 
							dprintk("%s: failed sending from %02X to %02X: %d\n",
 | 
				
			||||||
			__FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc);
 | 
								__FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	release_sock(sk);
 | 
						release_sock(sk);
 | 
				
			||||||
	return rc ? : copied;
 | 
						return rc ? : copied;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -895,7 +978,7 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
 | 
				
			||||||
	int rc = -EINVAL, opt;
 | 
						int rc = -EINVAL, opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lock_sock(sk);
 | 
						lock_sock(sk);
 | 
				
			||||||
	if (level != SOL_LLC || optlen != sizeof(int))
 | 
						if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = get_user(opt, (int __user *)optval);
 | 
						rc = get_user(opt, (int __user *)optval);
 | 
				
			||||||
	if (rc)
 | 
						if (rc)
 | 
				
			||||||
| 
						 | 
					@ -915,22 +998,22 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
 | 
				
			||||||
	case LLC_OPT_ACK_TMR_EXP:
 | 
						case LLC_OPT_ACK_TMR_EXP:
 | 
				
			||||||
		if (opt > LLC_OPT_MAX_ACK_TMR_EXP)
 | 
							if (opt > LLC_OPT_MAX_ACK_TMR_EXP)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		llc->ack_timer.expire = opt;
 | 
							llc->ack_timer.expire = opt * HZ;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LLC_OPT_P_TMR_EXP:
 | 
						case LLC_OPT_P_TMR_EXP:
 | 
				
			||||||
		if (opt > LLC_OPT_MAX_P_TMR_EXP)
 | 
							if (opt > LLC_OPT_MAX_P_TMR_EXP)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		llc->pf_cycle_timer.expire = opt;
 | 
							llc->pf_cycle_timer.expire = opt * HZ;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LLC_OPT_REJ_TMR_EXP:
 | 
						case LLC_OPT_REJ_TMR_EXP:
 | 
				
			||||||
		if (opt > LLC_OPT_MAX_REJ_TMR_EXP)
 | 
							if (opt > LLC_OPT_MAX_REJ_TMR_EXP)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		llc->rej_sent_timer.expire = opt;
 | 
							llc->rej_sent_timer.expire = opt * HZ;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LLC_OPT_BUSY_TMR_EXP:
 | 
						case LLC_OPT_BUSY_TMR_EXP:
 | 
				
			||||||
		if (opt > LLC_OPT_MAX_BUSY_TMR_EXP)
 | 
							if (opt > LLC_OPT_MAX_BUSY_TMR_EXP)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		llc->busy_state_timer.expire = opt;
 | 
							llc->busy_state_timer.expire = opt * HZ;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LLC_OPT_TX_WIN:
 | 
						case LLC_OPT_TX_WIN:
 | 
				
			||||||
		if (opt > LLC_OPT_MAX_WIN)
 | 
							if (opt > LLC_OPT_MAX_WIN)
 | 
				
			||||||
| 
						 | 
					@ -970,7 +1053,7 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
 | 
				
			||||||
	int val = 0, len = 0, rc = -EINVAL;
 | 
						int val = 0, len = 0, rc = -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lock_sock(sk);
 | 
						lock_sock(sk);
 | 
				
			||||||
	if (level != SOL_LLC)
 | 
						if (unlikely(level != SOL_LLC))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = get_user(len, optlen);
 | 
						rc = get_user(len, optlen);
 | 
				
			||||||
	if (rc)
 | 
						if (rc)
 | 
				
			||||||
| 
						 | 
					@ -980,17 +1063,17 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	switch (optname) {
 | 
						switch (optname) {
 | 
				
			||||||
	case LLC_OPT_RETRY:
 | 
						case LLC_OPT_RETRY:
 | 
				
			||||||
		val = llc->n2;				break;
 | 
							val = llc->n2;					break;
 | 
				
			||||||
	case LLC_OPT_SIZE:
 | 
						case LLC_OPT_SIZE:
 | 
				
			||||||
		val = llc->n1;				break;
 | 
							val = llc->n1;					break;
 | 
				
			||||||
	case LLC_OPT_ACK_TMR_EXP:
 | 
						case LLC_OPT_ACK_TMR_EXP:
 | 
				
			||||||
		val = llc->ack_timer.expire;		break;
 | 
							val = llc->ack_timer.expire / HZ;		break;
 | 
				
			||||||
	case LLC_OPT_P_TMR_EXP:
 | 
						case LLC_OPT_P_TMR_EXP:
 | 
				
			||||||
		val = llc->pf_cycle_timer.expire;	break;
 | 
							val = llc->pf_cycle_timer.expire / HZ;		break;
 | 
				
			||||||
	case LLC_OPT_REJ_TMR_EXP:
 | 
						case LLC_OPT_REJ_TMR_EXP:
 | 
				
			||||||
		val = llc->rej_sent_timer.expire;	break;
 | 
							val = llc->rej_sent_timer.expire / HZ;		break;
 | 
				
			||||||
	case LLC_OPT_BUSY_TMR_EXP:
 | 
						case LLC_OPT_BUSY_TMR_EXP:
 | 
				
			||||||
		val = llc->busy_state_timer.expire;	break;
 | 
							val = llc->busy_state_timer.expire / HZ;	break;
 | 
				
			||||||
	case LLC_OPT_TX_WIN:
 | 
						case LLC_OPT_TX_WIN:
 | 
				
			||||||
		val = llc->k;				break;
 | 
							val = llc->k;				break;
 | 
				
			||||||
	case LLC_OPT_RX_WIN:
 | 
						case LLC_OPT_RX_WIN:
 | 
				
			||||||
| 
						 | 
					@ -1034,8 +1117,12 @@ static struct proto_ops llc_ui_ops = {
 | 
				
			||||||
	.sendpage    = sock_no_sendpage,
 | 
						.sendpage    = sock_no_sendpage,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
 | 
					static char llc_proc_err_msg[] __initdata =
 | 
				
			||||||
extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
 | 
					        KERN_CRIT "LLC: Unable to register the proc_fs entries\n";
 | 
				
			||||||
 | 
					static char llc_sysctl_err_msg[] __initdata =
 | 
				
			||||||
 | 
					        KERN_CRIT "LLC: Unable to register the sysctl entries\n";
 | 
				
			||||||
 | 
					static char llc_sock_err_msg[] __initdata =
 | 
				
			||||||
 | 
					        KERN_CRIT "LLC: Unable to register the network family\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init llc2_init(void)
 | 
					static int __init llc2_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1048,13 +1135,28 @@ static int __init llc2_init(void)
 | 
				
			||||||
	llc_station_init();
 | 
						llc_station_init();
 | 
				
			||||||
	llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
 | 
						llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
 | 
				
			||||||
	rc = llc_proc_init();
 | 
						rc = llc_proc_init();
 | 
				
			||||||
	if (rc != 0)
 | 
						if (rc != 0) {
 | 
				
			||||||
 | 
							printk(llc_proc_err_msg);
 | 
				
			||||||
		goto out_unregister_llc_proto;
 | 
							goto out_unregister_llc_proto;
 | 
				
			||||||
	sock_register(&llc_ui_family_ops);
 | 
						}
 | 
				
			||||||
 | 
						rc = llc_sysctl_init();
 | 
				
			||||||
 | 
						if (rc) {
 | 
				
			||||||
 | 
							printk(llc_sysctl_err_msg);
 | 
				
			||||||
 | 
							goto out_proc;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rc = sock_register(&llc_ui_family_ops);
 | 
				
			||||||
 | 
						if (rc) {
 | 
				
			||||||
 | 
							printk(llc_sock_err_msg);
 | 
				
			||||||
 | 
							goto out_sysctl;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
 | 
						llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
 | 
				
			||||||
	llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
 | 
						llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
 | 
					out_sysctl:
 | 
				
			||||||
 | 
						llc_sysctl_exit();
 | 
				
			||||||
 | 
					out_proc:
 | 
				
			||||||
 | 
						llc_proc_exit();
 | 
				
			||||||
out_unregister_llc_proto:
 | 
					out_unregister_llc_proto:
 | 
				
			||||||
	proto_unregister(&llc_proto);
 | 
						proto_unregister(&llc_proto);
 | 
				
			||||||
	goto out;
 | 
						goto out;
 | 
				
			||||||
| 
						 | 
					@ -1067,6 +1169,7 @@ static void __exit llc2_exit(void)
 | 
				
			||||||
	llc_remove_pack(LLC_DEST_CONN);
 | 
						llc_remove_pack(LLC_DEST_CONN);
 | 
				
			||||||
	sock_unregister(PF_LLC);
 | 
						sock_unregister(PF_LLC);
 | 
				
			||||||
	llc_proc_exit();
 | 
						llc_proc_exit();
 | 
				
			||||||
 | 
						llc_sysctl_exit();
 | 
				
			||||||
	proto_unregister(&llc_proto);
 | 
						proto_unregister(&llc_proto);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,23 +60,10 @@ int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOTCONN;
 | 
						struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
	u8 dsap;
 | 
					 | 
				
			||||||
	struct llc_sap *sap;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	llc_pdu_decode_dsap(skb, &dsap);
 | 
						ev->ind_prim = LLC_CONN_PRIM;
 | 
				
			||||||
	sap = llc_sap_find(dsap);
 | 
						return 0;
 | 
				
			||||||
	if (sap) {
 | 
					 | 
				
			||||||
		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
					 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		llc_pdu_decode_sa(skb, llc->daddr.mac);
 | 
					 | 
				
			||||||
		llc_pdu_decode_da(skb, llc->laddr.mac);
 | 
					 | 
				
			||||||
		llc->dev = skb->dev;
 | 
					 | 
				
			||||||
		ev->ind_prim = LLC_CONN_PRIM;
 | 
					 | 
				
			||||||
		rc = 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
| 
						 | 
					@ -120,10 +107,8 @@ int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
			reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
 | 
								reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
 | 
				
			||||||
	} else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)
 | 
						} else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)
 | 
				
			||||||
		reason = LLC_DISC_REASON_ACK_TMR_EXP;
 | 
							reason = LLC_DISC_REASON_ACK_TMR_EXP;
 | 
				
			||||||
	else {
 | 
						else
 | 
				
			||||||
		reason = 0;
 | 
					 | 
				
			||||||
		rc = -EINVAL;
 | 
							rc = -EINVAL;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!rc) {
 | 
						if (!rc) {
 | 
				
			||||||
		ev->reason   = reason;
 | 
							ev->reason   = reason;
 | 
				
			||||||
		ev->ind_prim = LLC_DISC_PRIM;
 | 
							ev->ind_prim = LLC_DISC_PRIM;
 | 
				
			||||||
| 
						 | 
					@ -160,9 +145,6 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
			   LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) {
 | 
								   LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) {
 | 
				
			||||||
			reason = LLC_RESET_REASON_REMOTE;
 | 
								reason = LLC_RESET_REASON_REMOTE;
 | 
				
			||||||
			rc = 0;
 | 
								rc = 0;
 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			reason = 0;
 | 
					 | 
				
			||||||
			rc  = 1;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LLC_CONN_EV_TYPE_ACK_TMR:
 | 
						case LLC_CONN_EV_TYPE_ACK_TMR:
 | 
				
			||||||
| 
						 | 
					@ -172,8 +154,7 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
		if (llc->retry_count > llc->n2) {
 | 
							if (llc->retry_count > llc->n2) {
 | 
				
			||||||
			reason = LLC_RESET_REASON_LOCAL;
 | 
								reason = LLC_RESET_REASON_LOCAL;
 | 
				
			||||||
			rc = 0;
 | 
								rc = 0;
 | 
				
			||||||
		} else
 | 
							}
 | 
				
			||||||
			rc = 1;
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!rc) {
 | 
						if (!rc) {
 | 
				
			||||||
| 
						 | 
					@ -217,18 +198,17 @@ int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
 | 
				
			||||||
int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_CMD);
 | 
									    llc->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
		llc_pdu_init_as_disc_cmd(nskb, 1);
 | 
							llc_pdu_init_as_disc_cmd(nskb, 1);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
		llc_conn_ac_set_p_flag_1(sk, skb);
 | 
							llc_conn_ac_set_p_flag_1(sk, skb);
 | 
				
			||||||
| 
						 | 
					@ -243,20 +223,19 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
		u8 f_bit;
 | 
							u8 f_bit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_decode_pf_bit(skb, &f_bit);
 | 
							llc_pdu_decode_pf_bit(skb, &f_bit);
 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_dm_rsp(nskb, f_bit);
 | 
							llc_pdu_init_as_dm_rsp(nskb, f_bit);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -270,19 +249,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
		u8 f_bit = 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_dm_rsp(nskb, f_bit);
 | 
							llc_pdu_init_as_dm_rsp(nskb, 1);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -306,17 +283,16 @@ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
		llc_pdu_decode_pf_bit(skb, &f_bit);
 | 
							llc_pdu_decode_pf_bit(skb, &f_bit);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		f_bit = 0;
 | 
							f_bit = 0;
 | 
				
			||||||
	nskb = llc_alloc_frame();
 | 
						nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
 | 
							llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
 | 
				
			||||||
					 llc->vR, INCORRECT);
 | 
										 llc->vR, INCORRECT);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -330,21 +306,19 @@ free:
 | 
				
			||||||
int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		u8 f_bit = 0;
 | 
					 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
		struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;
 | 
							struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
 | 
							llc_pdu_init_as_frmr_rsp(nskb, pdu, 0, llc->vS,
 | 
				
			||||||
					 llc->vR, INCORRECT);
 | 
										 llc->vR, INCORRECT);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -360,21 +334,20 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	u8 f_bit;
 | 
						u8 f_bit;
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb;
 | 
						struct sk_buff *nskb;
 | 
				
			||||||
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	llc_pdu_decode_pf_bit(skb, &f_bit);
 | 
						llc_pdu_decode_pf_bit(skb, &f_bit);
 | 
				
			||||||
	nskb = llc_alloc_frame();
 | 
						nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
		struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
							struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
 | 
							llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
 | 
				
			||||||
					 llc->vR, INCORRECT);
 | 
										 llc->vR, INCORRECT);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -395,7 +368,7 @@ int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
			    llc->daddr.lsap, LLC_PDU_CMD);
 | 
								    llc->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
	llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
 | 
						llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
 | 
				
			||||||
	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 | 
						rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
	if (!rc) {
 | 
						if (likely(!rc)) {
 | 
				
			||||||
		llc_conn_send_pdu(sk, skb);
 | 
							llc_conn_send_pdu(sk, skb);
 | 
				
			||||||
		llc_conn_ac_inc_vs_by_1(sk, skb);
 | 
							llc_conn_ac_inc_vs_by_1(sk, skb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -412,7 +385,7 @@ static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
			    llc->daddr.lsap, LLC_PDU_CMD);
 | 
								    llc->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
	llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
 | 
						llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
 | 
				
			||||||
	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 | 
						rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
	if (!rc) {
 | 
						if (likely(!rc)) {
 | 
				
			||||||
		llc_conn_send_pdu(sk, skb);
 | 
							llc_conn_send_pdu(sk, skb);
 | 
				
			||||||
		llc_conn_ac_inc_vs_by_1(sk, skb);
 | 
							llc_conn_ac_inc_vs_by_1(sk, skb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -429,7 +402,7 @@ int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
			    llc->daddr.lsap, LLC_PDU_CMD);
 | 
								    llc->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
	llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
 | 
						llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
 | 
				
			||||||
	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 | 
						rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
	if (!rc) {
 | 
						if (likely(!rc)) {
 | 
				
			||||||
		llc_conn_send_pdu(sk, skb);
 | 
							llc_conn_send_pdu(sk, skb);
 | 
				
			||||||
		llc_conn_ac_inc_vs_by_1(sk, skb);
 | 
							llc_conn_ac_inc_vs_by_1(sk, skb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -451,18 +424,17 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
 | 
				
			||||||
	u8 nr;
 | 
						u8 nr;
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
 | 
							llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (!rc)
 | 
							if (likely(!rc))
 | 
				
			||||||
			llc_conn_send_pdu(sk, nskb);
 | 
								llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			kfree_skb(skb);
 | 
								kfree_skb(skb);
 | 
				
			||||||
| 
						 | 
					@ -487,18 +459,17 @@ int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_CMD);
 | 
									    llc->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
		llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
 | 
							llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -512,19 +483,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		u8 f_bit = 1;
 | 
					 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
 | 
							llc_pdu_init_as_rej_rsp(nskb, 1, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -538,19 +507,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
		u8 f_bit = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
 | 
							llc_pdu_init_as_rej_rsp(nskb, 0, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -564,18 +531,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_CMD);
 | 
									    llc->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
		llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
 | 
							llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -589,19 +555,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
		u8 f_bit = 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
 | 
							llc_pdu_init_as_rnr_rsp(nskb, 1, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -615,19 +579,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		u8 f_bit = 0;
 | 
					 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
 | 
							llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -645,7 +607,7 @@ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	if (!llc->remote_busy_flag) {
 | 
						if (!llc->remote_busy_flag) {
 | 
				
			||||||
		llc->remote_busy_flag = 1;
 | 
							llc->remote_busy_flag = 1;
 | 
				
			||||||
		mod_timer(&llc->busy_state_timer.timer,
 | 
							mod_timer(&llc->busy_state_timer.timer,
 | 
				
			||||||
			 jiffies + llc->busy_state_timer.expire * HZ);
 | 
								 jiffies + llc->busy_state_timer.expire);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -653,18 +615,17 @@ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
 | 
							llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -678,18 +639,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_CMD);
 | 
									    llc->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
		llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
 | 
							llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -703,19 +663,18 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
		u8 f_bit = 1;
 | 
							u8 f_bit = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
 | 
							llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -729,19 +688,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
		u8 f_bit = 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
 | 
							llc_pdu_init_as_rr_rsp(nskb, 1, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -755,18 +712,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
 | 
							llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -780,18 +736,17 @@ free:
 | 
				
			||||||
int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
 | 
							llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -815,8 +770,8 @@ void llc_conn_set_p_flag(struct sock *sk, u8 value)
 | 
				
			||||||
int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
					 | 
				
			||||||
	struct llc_sock *llc = llc_sk(sk);
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
| 
						 | 
					@ -824,12 +779,11 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (llc->dev->flags & IFF_LOOPBACK)
 | 
							if (llc->dev->flags & IFF_LOOPBACK)
 | 
				
			||||||
			dmac = llc->dev->dev_addr;
 | 
								dmac = llc->dev->dev_addr;
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_CMD);
 | 
									    llc->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
		llc_pdu_init_as_sabme_cmd(nskb, 1);
 | 
							llc_pdu_init_as_sabme_cmd(nskb, 1);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
		llc_conn_set_p_flag(sk, 1);
 | 
							llc_conn_set_p_flag(sk, 1);
 | 
				
			||||||
| 
						 | 
					@ -845,11 +799,11 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 f_bit;
 | 
						u8 f_bit;
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	llc_pdu_decode_pf_bit(skb, &f_bit);
 | 
						llc_pdu_decode_pf_bit(skb, &f_bit);
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
							nskb->dev = llc->dev;
 | 
				
			||||||
| 
						 | 
					@ -857,7 +811,7 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_ua_rsp(nskb, f_bit);
 | 
							llc_pdu_init_as_ua_rsp(nskb, f_bit);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -886,7 +840,7 @@ int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	llc_conn_set_p_flag(sk, 1);
 | 
						llc_conn_set_p_flag(sk, 1);
 | 
				
			||||||
	mod_timer(&llc->pf_cycle_timer.timer,
 | 
						mod_timer(&llc->pf_cycle_timer.timer,
 | 
				
			||||||
		  jiffies + llc->pf_cycle_timer.expire * HZ);
 | 
							  jiffies + llc->pf_cycle_timer.expire);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -957,7 +911,7 @@ static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
 | 
				
			||||||
			    llc->daddr.lsap, LLC_PDU_RSP);
 | 
								    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
	llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
 | 
						llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
 | 
				
			||||||
	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 | 
						rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
	if (!rc) {
 | 
						if (likely(!rc)) {
 | 
				
			||||||
		llc_conn_send_pdu(sk, skb);
 | 
							llc_conn_send_pdu(sk, skb);
 | 
				
			||||||
		llc_conn_ac_inc_vs_by_1(sk, skb);
 | 
							llc_conn_ac_inc_vs_by_1(sk, skb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1001,18 +955,17 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
 | 
				
			||||||
					       struct sk_buff *skb)
 | 
										       struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = -ENOBUFS;
 | 
						int rc = -ENOBUFS;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
						struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nskb) {
 | 
						if (nskb) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		struct llc_sap *sap = llc->sap;
 | 
							struct llc_sap *sap = llc->sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nskb->dev = llc->dev;
 | 
					 | 
				
			||||||
		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
							llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
 | 
				
			||||||
				    llc->daddr.lsap, LLC_PDU_RSP);
 | 
									    llc->daddr.lsap, LLC_PDU_RSP);
 | 
				
			||||||
		llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
 | 
							llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
 | 
				
			||||||
		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
							rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
 | 
				
			||||||
		if (rc)
 | 
							if (unlikely(rc))
 | 
				
			||||||
			goto free;
 | 
								goto free;
 | 
				
			||||||
		llc_conn_send_pdu(sk, nskb);
 | 
							llc_conn_send_pdu(sk, nskb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1165,7 +1118,7 @@ int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_sock *llc = llc_sk(sk);
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire * HZ);
 | 
						mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1174,7 +1127,7 @@ int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	struct llc_sock *llc = llc_sk(sk);
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mod_timer(&llc->rej_sent_timer.timer,
 | 
						mod_timer(&llc->rej_sent_timer.timer,
 | 
				
			||||||
		  jiffies + llc->rej_sent_timer.expire * HZ);
 | 
							  jiffies + llc->rej_sent_timer.expire);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1185,7 +1138,7 @@ int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!timer_pending(&llc->ack_timer.timer))
 | 
						if (!timer_pending(&llc->ack_timer.timer))
 | 
				
			||||||
		mod_timer(&llc->ack_timer.timer,
 | 
							mod_timer(&llc->ack_timer.timer,
 | 
				
			||||||
			  jiffies + llc->ack_timer.expire * HZ);
 | 
								  jiffies + llc->ack_timer.expire);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1233,7 +1186,7 @@ int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (unacked)
 | 
							if (unacked)
 | 
				
			||||||
			mod_timer(&llc->ack_timer.timer,
 | 
								mod_timer(&llc->ack_timer.timer,
 | 
				
			||||||
				  jiffies + llc->ack_timer.expire * HZ);
 | 
									  jiffies + llc->ack_timer.expire);
 | 
				
			||||||
	} else if (llc->failed_data_req) {
 | 
						} else if (llc->failed_data_req) {
 | 
				
			||||||
		u8 f_bit;
 | 
							u8 f_bit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1354,13 +1307,13 @@ int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
 | 
					static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128;
 | 
						llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
 | 
					static void llc_conn_tmr_common_cb(unsigned long timeout_data, u8 type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock *sk = (struct sock *)timeout_data;
 | 
						struct sock *sk = (struct sock *)timeout_data;
 | 
				
			||||||
	struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
 | 
						struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
 | 
				
			||||||
| 
						 | 
					@ -1369,59 +1322,31 @@ void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
 | 
				
			||||||
	if (skb) {
 | 
						if (skb) {
 | 
				
			||||||
		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
							struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		skb->sk  = sk;
 | 
							skb_set_owner_r(skb, sk);
 | 
				
			||||||
		ev->type = LLC_CONN_EV_TYPE_P_TMR;
 | 
							ev->type = type;
 | 
				
			||||||
		llc_process_tmr_ev(sk, skb);
 | 
							llc_process_tmr_ev(sk, skb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bh_unlock_sock(sk);
 | 
						bh_unlock_sock(sk);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void llc_conn_busy_tmr_cb(unsigned long timeout_data)
 | 
					void llc_conn_busy_tmr_cb(unsigned long timeout_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock *sk = (struct sock *)timeout_data;
 | 
						llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR);
 | 
				
			||||||
	struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bh_lock_sock(sk);
 | 
					 | 
				
			||||||
	if (skb) {
 | 
					 | 
				
			||||||
		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		skb->sk  = sk;
 | 
					 | 
				
			||||||
		ev->type = LLC_CONN_EV_TYPE_BUSY_TMR;
 | 
					 | 
				
			||||||
		llc_process_tmr_ev(sk, skb);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	bh_unlock_sock(sk);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void llc_conn_ack_tmr_cb(unsigned long timeout_data)
 | 
					void llc_conn_ack_tmr_cb(unsigned long timeout_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock* sk = (struct sock *)timeout_data;
 | 
						llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR);
 | 
				
			||||||
	struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bh_lock_sock(sk);
 | 
					 | 
				
			||||||
	if (skb) {
 | 
					 | 
				
			||||||
		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		skb->sk  = sk;
 | 
					 | 
				
			||||||
		ev->type = LLC_CONN_EV_TYPE_ACK_TMR;
 | 
					 | 
				
			||||||
		llc_process_tmr_ev(sk, skb);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	bh_unlock_sock(sk);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void llc_conn_rej_tmr_cb(unsigned long timeout_data)
 | 
					void llc_conn_rej_tmr_cb(unsigned long timeout_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock *sk = (struct sock *)timeout_data;
 | 
						llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR);
 | 
				
			||||||
	struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bh_lock_sock(sk);
 | 
					 | 
				
			||||||
	if (skb) {
 | 
					 | 
				
			||||||
		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		skb->sk  = sk;
 | 
					 | 
				
			||||||
		ev->type = LLC_CONN_EV_TYPE_REJ_TMR;
 | 
					 | 
				
			||||||
		llc_process_tmr_ev(sk, skb);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	bh_unlock_sock(sk);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@
 | 
				
			||||||
#include <net/llc_conn.h>
 | 
					#include <net/llc_conn.h>
 | 
				
			||||||
#include <net/llc_sap.h>
 | 
					#include <net/llc_sap.h>
 | 
				
			||||||
#include <net/sock.h>
 | 
					#include <net/sock.h>
 | 
				
			||||||
 | 
					#include <net/llc_c_ac.h>
 | 
				
			||||||
#include <net/llc_c_ev.h>
 | 
					#include <net/llc_c_ev.h>
 | 
				
			||||||
#include <net/llc_pdu.h>
 | 
					#include <net/llc_pdu.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,8 +47,6 @@
 | 
				
			||||||
#define dprintk(args...)
 | 
					#define dprintk(args...)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern u16 llc_circular_between(u8 a, u8 b, u8 c);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	llc_util_ns_inside_rx_window - check if sequence number is in rx window
 | 
					 *	llc_util_ns_inside_rx_window - check if sequence number is in rx window
 | 
				
			||||||
 *	@ns: sequence number of received pdu.
 | 
					 *	@ns: sequence number of received pdu.
 | 
				
			||||||
| 
						 | 
					@ -99,7 +98,7 @@ out:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->prim == LLC_CONN_PRIM &&
 | 
						return ev->prim == LLC_CONN_PRIM &&
 | 
				
			||||||
	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 | 
						       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -107,7 +106,7 @@ int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->prim == LLC_DATA_PRIM &&
 | 
						return ev->prim == LLC_DATA_PRIM &&
 | 
				
			||||||
	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 | 
						       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -115,7 +114,7 @@ int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->prim == LLC_DISC_PRIM &&
 | 
						return ev->prim == LLC_DISC_PRIM &&
 | 
				
			||||||
	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 | 
						       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -123,7 +122,7 @@ int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->prim == LLC_RESET_PRIM &&
 | 
						return ev->prim == LLC_RESET_PRIM &&
 | 
				
			||||||
	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 | 
						       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -131,7 +130,7 @@ int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
 | 
						return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
 | 
				
			||||||
	       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
 | 
						       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -139,7 +138,7 @@ int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
 | 
						return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
 | 
				
			||||||
	       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
 | 
						       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -152,7 +151,7 @@ int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
						const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 | 
				
			||||||
	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
 | 
						       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -160,7 +159,7 @@ int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
						const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 | 
				
			||||||
	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
 | 
						       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -168,7 +167,7 @@ int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
						const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 | 
				
			||||||
	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
 | 
						       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -176,7 +175,7 @@ int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return llc_conn_space(sk, skb) &&
 | 
						return llc_conn_space(sk, skb) &&
 | 
				
			||||||
	       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
						       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -186,7 +185,7 @@ int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return llc_conn_space(sk, skb) &&
 | 
						return llc_conn_space(sk, skb) &&
 | 
				
			||||||
	       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
						       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -197,9 +196,9 @@ int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
 | 
					int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
 | 
				
			||||||
					      struct sk_buff *skb)
 | 
										      struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	u8 vr = llc_sk(sk)->vR;
 | 
						const u8 vr = llc_sk(sk)->vR;
 | 
				
			||||||
	u8 ns = LLC_I_GET_NS(pdu);
 | 
						const u8 ns = LLC_I_GET_NS(pdu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
	       LLC_I_PF_IS_0(pdu) && ns != vr &&
 | 
						       LLC_I_PF_IS_0(pdu) && ns != vr &&
 | 
				
			||||||
| 
						 | 
					@ -209,9 +208,9 @@ int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
 | 
				
			||||||
int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
 | 
					int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
 | 
				
			||||||
					      struct sk_buff *skb)
 | 
										      struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	u8 vr = llc_sk(sk)->vR;
 | 
						const u8 vr = llc_sk(sk)->vR;
 | 
				
			||||||
	u8 ns = LLC_I_GET_NS(pdu);
 | 
						const u8 ns = LLC_I_GET_NS(pdu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
	       LLC_I_PF_IS_1(pdu) && ns != vr &&
 | 
						       LLC_I_PF_IS_1(pdu) && ns != vr &&
 | 
				
			||||||
| 
						 | 
					@ -221,10 +220,11 @@ int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
 | 
				
			||||||
int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
 | 
					int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
 | 
				
			||||||
					     struct sk_buff *skb)
 | 
										     struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	u8 vr = llc_sk(sk)->vR;
 | 
						const u8 vr = llc_sk(sk)->vR;
 | 
				
			||||||
	u8 ns = LLC_I_GET_NS(pdu);
 | 
						const u8 ns = LLC_I_GET_NS(pdu);
 | 
				
			||||||
	u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
 | 
						const u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
 | 
							ns != vr &&
 | 
				
			||||||
		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 | 
							 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 | 
				
			||||||
	if (!rc)
 | 
						if (!rc)
 | 
				
			||||||
		dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
 | 
							dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
 | 
				
			||||||
| 
						 | 
					@ -234,7 +234,7 @@ int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return llc_conn_space(sk, skb) &&
 | 
						return llc_conn_space(sk, skb) &&
 | 
				
			||||||
	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
						       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -244,7 +244,7 @@ int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
	       LLC_I_PF_IS_1(pdu) &&
 | 
						       LLC_I_PF_IS_1(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -253,7 +253,7 @@ int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return llc_conn_space(sk, skb) &&
 | 
						return llc_conn_space(sk, skb) &&
 | 
				
			||||||
	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
						       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -263,9 +263,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
 | 
					int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
 | 
				
			||||||
					      struct sk_buff *skb)
 | 
										      struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	u8 vr = llc_sk(sk)->vR;
 | 
						const u8 vr = llc_sk(sk)->vR;
 | 
				
			||||||
	u8 ns = LLC_I_GET_NS(pdu);
 | 
						const u8 ns = LLC_I_GET_NS(pdu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
	       LLC_I_PF_IS_0(pdu) && ns != vr &&
 | 
						       LLC_I_PF_IS_0(pdu) && ns != vr &&
 | 
				
			||||||
| 
						 | 
					@ -275,9 +275,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
 | 
				
			||||||
int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
 | 
					int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
 | 
				
			||||||
					      struct sk_buff *skb)
 | 
										      struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	u8 vr = llc_sk(sk)->vR;
 | 
						const u8 vr = llc_sk(sk)->vR;
 | 
				
			||||||
	u8 ns = LLC_I_GET_NS(pdu);
 | 
						const u8 ns = LLC_I_GET_NS(pdu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
	       LLC_I_PF_IS_1(pdu) && ns != vr &&
 | 
						       LLC_I_PF_IS_1(pdu) && ns != vr &&
 | 
				
			||||||
| 
						 | 
					@ -287,9 +287,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
 | 
				
			||||||
int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
 | 
					int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
 | 
				
			||||||
					      struct sk_buff *skb)
 | 
										      struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	u8 vr = llc_sk(sk)->vR;
 | 
						const u8 vr = llc_sk(sk)->vR;
 | 
				
			||||||
	u8 ns = LLC_I_GET_NS(pdu);
 | 
						const u8 ns = LLC_I_GET_NS(pdu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
 | 
				
			||||||
	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 | 
						       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -298,10 +298,11 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
 | 
				
			||||||
int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
 | 
					int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
 | 
				
			||||||
					     struct sk_buff *skb)
 | 
										     struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	u8 vr = llc_sk(sk)->vR;
 | 
						const u8 vr = llc_sk(sk)->vR;
 | 
				
			||||||
	u8 ns = LLC_I_GET_NS(pdu);
 | 
						const u8 ns = LLC_I_GET_NS(pdu);
 | 
				
			||||||
	u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
 | 
						const u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 | 
				
			||||||
 | 
							ns != vr &&
 | 
				
			||||||
		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 | 
							 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 | 
				
			||||||
	if (!rc)
 | 
						if (!rc)
 | 
				
			||||||
		dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
 | 
							dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
 | 
				
			||||||
| 
						 | 
					@ -311,7 +312,7 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_0(pdu) &&
 | 
						       LLC_S_PF_IS_0(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -320,7 +321,7 @@ int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_1(pdu) &&
 | 
						       LLC_S_PF_IS_1(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -329,7 +330,7 @@ int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_0(pdu) &&
 | 
						       LLC_S_PF_IS_0(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -338,7 +339,7 @@ int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_1(pdu) &&
 | 
						       LLC_S_PF_IS_1(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -347,7 +348,7 @@ int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
						const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
 | 
						       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -355,7 +356,7 @@ int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_0(pdu) &&
 | 
						       LLC_S_PF_IS_0(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -364,7 +365,7 @@ int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_1(pdu) &&
 | 
						       LLC_S_PF_IS_1(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -373,7 +374,7 @@ int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_0(pdu) &&
 | 
						       LLC_S_PF_IS_0(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -382,7 +383,7 @@ int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_1(pdu) &&
 | 
						       LLC_S_PF_IS_1(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -391,7 +392,7 @@ int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_0(pdu) &&
 | 
						       LLC_S_PF_IS_0(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -400,7 +401,7 @@ int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
	       LLC_S_PF_IS_1(pdu) &&
 | 
						       LLC_S_PF_IS_1(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -409,7 +410,7 @@ int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return llc_conn_space(sk, skb) &&
 | 
						return llc_conn_space(sk, skb) &&
 | 
				
			||||||
	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -419,7 +420,7 @@ int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return llc_conn_space(sk, skb) &&
 | 
						return llc_conn_space(sk, skb) &&
 | 
				
			||||||
	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
						       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 | 
				
			||||||
| 
						 | 
					@ -429,7 +430,7 @@ int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
						const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 | 
						return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 | 
				
			||||||
	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
 | 
						       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					@ -446,7 +447,7 @@ int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 rc = 1;
 | 
						u16 rc = 1;
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (LLC_PDU_IS_CMD(pdu)) {
 | 
						if (LLC_PDU_IS_CMD(pdu)) {
 | 
				
			||||||
		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
 | 
							if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
 | 
				
			||||||
| 
						 | 
					@ -461,7 +462,7 @@ int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 rc = 1;
 | 
						u16 rc = 1;
 | 
				
			||||||
	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
						const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (LLC_PDU_IS_CMD(pdu)) {
 | 
						if (LLC_PDU_IS_CMD(pdu)) {
 | 
				
			||||||
		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
 | 
							if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
 | 
				
			||||||
| 
						 | 
					@ -477,32 +478,10 @@ int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u16 rc = 1;
 | 
					 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (LLC_PDU_IS_RSP(pdu)) {
 | 
					 | 
				
			||||||
		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
 | 
					 | 
				
			||||||
			if (LLC_I_PF_IS_1(pdu))
 | 
					 | 
				
			||||||
				rc = 0;
 | 
					 | 
				
			||||||
		} else if (LLC_PDU_TYPE_IS_U(pdu))
 | 
					 | 
				
			||||||
			switch (LLC_U_PDU_RSP(pdu)) {
 | 
					 | 
				
			||||||
			case LLC_2_PDU_RSP_UA:
 | 
					 | 
				
			||||||
			case LLC_2_PDU_RSP_DM:
 | 
					 | 
				
			||||||
			case LLC_2_PDU_RSP_FRMR:
 | 
					 | 
				
			||||||
				if (LLC_U_PF_IS_1(pdu))
 | 
					 | 
				
			||||||
					rc = 0;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 rc = 1;
 | 
						u16 rc = 1;
 | 
				
			||||||
	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
						const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (LLC_PDU_IS_RSP(pdu)) {
 | 
						if (LLC_PDU_IS_RSP(pdu)) {
 | 
				
			||||||
		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
 | 
							if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
 | 
				
			||||||
| 
						 | 
					@ -524,9 +503,9 @@ int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
 | 
				
			||||||
					       struct sk_buff *skb)
 | 
										       struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 rc = 1;
 | 
						u16 rc = 1;
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	u8 vs = llc_sk(sk)->vS;
 | 
						const u8 vs = llc_sk(sk)->vS;
 | 
				
			||||||
	u8 nr = LLC_I_GET_NR(pdu);
 | 
						const u8 nr = LLC_I_GET_NR(pdu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (LLC_PDU_IS_CMD(pdu) &&
 | 
						if (LLC_PDU_IS_CMD(pdu) &&
 | 
				
			||||||
	    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
 | 
						    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
 | 
				
			||||||
| 
						 | 
					@ -542,9 +521,9 @@ int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
 | 
				
			||||||
					       struct sk_buff *skb)
 | 
										       struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 rc = 1;
 | 
						u16 rc = 1;
 | 
				
			||||||
	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
						const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 | 
				
			||||||
	u8 vs = llc_sk(sk)->vS;
 | 
						const u8 vs = llc_sk(sk)->vS;
 | 
				
			||||||
	u8 nr = LLC_I_GET_NR(pdu);
 | 
						const u8 nr = LLC_I_GET_NR(pdu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (LLC_PDU_IS_RSP(pdu) &&
 | 
						if (LLC_PDU_IS_RSP(pdu) &&
 | 
				
			||||||
	    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
 | 
						    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
 | 
				
			||||||
| 
						 | 
					@ -563,28 +542,28 @@ int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->type != LLC_CONN_EV_TYPE_P_TMR;
 | 
						return ev->type != LLC_CONN_EV_TYPE_P_TMR;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
 | 
						return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
 | 
						return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
 | 
						return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -596,7 +575,7 @@ int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
 | 
						return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
 | 
				
			||||||
	       ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
 | 
						       ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,11 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
 | 
				
			||||||
/* Offset table on connection states transition diagram */
 | 
					/* Offset table on connection states transition diagram */
 | 
				
			||||||
static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
 | 
					static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sysctl_llc2_ack_timeout = LLC2_ACK_TIME * HZ;
 | 
				
			||||||
 | 
					int sysctl_llc2_p_timeout = LLC2_P_TIME * HZ;
 | 
				
			||||||
 | 
					int sysctl_llc2_rej_timeout = LLC2_REJ_TIME * HZ;
 | 
				
			||||||
 | 
					int sysctl_llc2_busy_timeout = LLC2_BUSY_TIME * HZ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	llc_conn_state_process - sends event to connection state machine
 | 
					 *	llc_conn_state_process - sends event to connection state machine
 | 
				
			||||||
 *	@sk: connection
 | 
					 *	@sk: connection
 | 
				
			||||||
| 
						 | 
					@ -53,7 +58,7 @@ static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
 | 
				
			||||||
int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
 | 
					int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc;
 | 
						int rc;
 | 
				
			||||||
	struct llc_sock *llc = llc_sk(sk);
 | 
						struct llc_sock *llc = llc_sk(skb->sk);
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -63,13 +68,16 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	skb_get(skb);
 | 
						skb_get(skb);
 | 
				
			||||||
	ev->ind_prim = ev->cfm_prim = 0;
 | 
						ev->ind_prim = ev->cfm_prim = 0;
 | 
				
			||||||
	rc = llc_conn_service(sk, skb); /* sending event to state machine */
 | 
						/*
 | 
				
			||||||
	if (rc) {
 | 
						 * Send event to state machine
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						rc = llc_conn_service(skb->sk, skb);
 | 
				
			||||||
 | 
						if (unlikely(rc != 0)) {
 | 
				
			||||||
		printk(KERN_ERR "%s: llc_conn_service failed\n", __FUNCTION__);
 | 
							printk(KERN_ERR "%s: llc_conn_service failed\n", __FUNCTION__);
 | 
				
			||||||
		goto out_kfree_skb;
 | 
							goto out_kfree_skb;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ev->ind_prim && !ev->cfm_prim) {
 | 
						if (unlikely(!ev->ind_prim && !ev->cfm_prim)) {
 | 
				
			||||||
		/* indicate or confirm not required */
 | 
							/* indicate or confirm not required */
 | 
				
			||||||
		/* XXX this is not very pretty, perhaps we should store
 | 
							/* XXX this is not very pretty, perhaps we should store
 | 
				
			||||||
		 * XXX indicate/confirm-needed state in the llc_conn_state_ev
 | 
							 * XXX indicate/confirm-needed state in the llc_conn_state_ev
 | 
				
			||||||
| 
						 | 
					@ -80,13 +88,13 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
		goto out_skb_put;
 | 
							goto out_skb_put;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ev->ind_prim && ev->cfm_prim) /* Paranoia */
 | 
						if (unlikely(ev->ind_prim && ev->cfm_prim)) /* Paranoia */
 | 
				
			||||||
		skb_get(skb);
 | 
							skb_get(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (ev->ind_prim) {
 | 
						switch (ev->ind_prim) {
 | 
				
			||||||
	case LLC_DATA_PRIM:
 | 
						case LLC_DATA_PRIM:
 | 
				
			||||||
		llc_save_primitive(skb, LLC_DATA_PRIM);
 | 
							llc_save_primitive(sk, skb, LLC_DATA_PRIM);
 | 
				
			||||||
		if (sock_queue_rcv_skb(sk, skb)) {
 | 
							if (unlikely(sock_queue_rcv_skb(sk, skb))) {
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * shouldn't happen
 | 
								 * shouldn't happen
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
| 
						 | 
					@ -95,13 +103,14 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
			kfree_skb(skb);
 | 
								kfree_skb(skb);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LLC_CONN_PRIM: {
 | 
						case LLC_CONN_PRIM:
 | 
				
			||||||
		struct sock *parent = skb->sk;
 | 
							/*
 | 
				
			||||||
 | 
							 * Can't be sock_queue_rcv_skb, because we have to leave the
 | 
				
			||||||
		skb->sk = sk;
 | 
							 * skb->sk pointing to the newly created struct sock in
 | 
				
			||||||
		skb_queue_tail(&parent->sk_receive_queue, skb);
 | 
							 * llc_conn_handler. -acme
 | 
				
			||||||
		sk->sk_state_change(parent);
 | 
							 */
 | 
				
			||||||
	}
 | 
							skb_queue_tail(&sk->sk_receive_queue, skb);
 | 
				
			||||||
 | 
							sk->sk_state_change(sk);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LLC_DISC_PRIM:
 | 
						case LLC_DISC_PRIM:
 | 
				
			||||||
		sock_hold(sk);
 | 
							sock_hold(sk);
 | 
				
			||||||
| 
						 | 
					@ -111,8 +120,8 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
			sk->sk_socket->state  = SS_UNCONNECTED;
 | 
								sk->sk_socket->state  = SS_UNCONNECTED;
 | 
				
			||||||
			sk->sk_state          = TCP_CLOSE;
 | 
								sk->sk_state          = TCP_CLOSE;
 | 
				
			||||||
			if (!sock_flag(sk, SOCK_DEAD)) {
 | 
								if (!sock_flag(sk, SOCK_DEAD)) {
 | 
				
			||||||
				sk->sk_state_change(sk);
 | 
					 | 
				
			||||||
				sock_set_flag(sk, SOCK_DEAD);
 | 
									sock_set_flag(sk, SOCK_DEAD);
 | 
				
			||||||
 | 
									sk->sk_state_change(sk);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		kfree_skb(skb);
 | 
							kfree_skb(skb);
 | 
				
			||||||
| 
						 | 
					@ -465,7 +474,7 @@ static int llc_exec_conn_trans_actions(struct sock *sk,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	llc_lookup_established - Finds connection for the remote/local sap/mac
 | 
					 *	__llc_lookup_established - Finds connection for the remote/local sap/mac
 | 
				
			||||||
 *	@sap: SAP
 | 
					 *	@sap: SAP
 | 
				
			||||||
 *	@daddr: address of remote LLC (MAC + SAP)
 | 
					 *	@daddr: address of remote LLC (MAC + SAP)
 | 
				
			||||||
 *	@laddr: address of local LLC (MAC + SAP)
 | 
					 *	@laddr: address of local LLC (MAC + SAP)
 | 
				
			||||||
| 
						 | 
					@ -473,14 +482,16 @@ static int llc_exec_conn_trans_actions(struct sock *sk,
 | 
				
			||||||
 *	Search connection list of the SAP and finds connection using the remote
 | 
					 *	Search connection list of the SAP and finds connection using the remote
 | 
				
			||||||
 *	mac, remote sap, local mac, and local sap. Returns pointer for
 | 
					 *	mac, remote sap, local mac, and local sap. Returns pointer for
 | 
				
			||||||
 *	connection found, %NULL otherwise.
 | 
					 *	connection found, %NULL otherwise.
 | 
				
			||||||
 | 
					 *	Caller has to make sure local_bh is disabled.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
 | 
					static struct sock *__llc_lookup_established(struct llc_sap *sap,
 | 
				
			||||||
				    struct llc_addr *laddr)
 | 
										     struct llc_addr *daddr,
 | 
				
			||||||
 | 
										     struct llc_addr *laddr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock *rc;
 | 
						struct sock *rc;
 | 
				
			||||||
	struct hlist_node *node;
 | 
						struct hlist_node *node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	read_lock_bh(&sap->sk_list.lock);
 | 
						read_lock(&sap->sk_list.lock);
 | 
				
			||||||
	sk_for_each(rc, node, &sap->sk_list.list) {
 | 
						sk_for_each(rc, node, &sap->sk_list.list) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(rc);
 | 
							struct llc_sock *llc = llc_sk(rc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -494,10 +505,22 @@ struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rc = NULL;
 | 
						rc = NULL;
 | 
				
			||||||
found:
 | 
					found:
 | 
				
			||||||
	read_unlock_bh(&sap->sk_list.lock);
 | 
						read_unlock(&sap->sk_list.lock);
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sock *llc_lookup_established(struct llc_sap *sap,
 | 
				
			||||||
 | 
									    struct llc_addr *daddr,
 | 
				
			||||||
 | 
									    struct llc_addr *laddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sock *sk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
 | 
						sk = __llc_lookup_established(sap, daddr, laddr);
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
						return sk;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	llc_lookup_listener - Finds listener for local MAC + SAP
 | 
					 *	llc_lookup_listener - Finds listener for local MAC + SAP
 | 
				
			||||||
 *	@sap: SAP
 | 
					 *	@sap: SAP
 | 
				
			||||||
| 
						 | 
					@ -506,6 +529,7 @@ found:
 | 
				
			||||||
 *	Search connection list of the SAP and finds connection listening on
 | 
					 *	Search connection list of the SAP and finds connection listening on
 | 
				
			||||||
 *	local mac, and local sap. Returns pointer for parent socket found,
 | 
					 *	local mac, and local sap. Returns pointer for parent socket found,
 | 
				
			||||||
 *	%NULL otherwise.
 | 
					 *	%NULL otherwise.
 | 
				
			||||||
 | 
					 *	Caller has to make sure local_bh is disabled.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static struct sock *llc_lookup_listener(struct llc_sap *sap,
 | 
					static struct sock *llc_lookup_listener(struct llc_sap *sap,
 | 
				
			||||||
					struct llc_addr *laddr)
 | 
										struct llc_addr *laddr)
 | 
				
			||||||
| 
						 | 
					@ -513,7 +537,7 @@ static struct sock *llc_lookup_listener(struct llc_sap *sap,
 | 
				
			||||||
	struct sock *rc;
 | 
						struct sock *rc;
 | 
				
			||||||
	struct hlist_node *node;
 | 
						struct hlist_node *node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	read_lock_bh(&sap->sk_list.lock);
 | 
						read_lock(&sap->sk_list.lock);
 | 
				
			||||||
	sk_for_each(rc, node, &sap->sk_list.list) {
 | 
						sk_for_each(rc, node, &sap->sk_list.list) {
 | 
				
			||||||
		struct llc_sock *llc = llc_sk(rc);
 | 
							struct llc_sock *llc = llc_sk(rc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -527,10 +551,19 @@ static struct sock *llc_lookup_listener(struct llc_sap *sap,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rc = NULL;
 | 
						rc = NULL;
 | 
				
			||||||
found:
 | 
					found:
 | 
				
			||||||
	read_unlock_bh(&sap->sk_list.lock);
 | 
						read_unlock(&sap->sk_list.lock);
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct sock *__llc_lookup(struct llc_sap *sap,
 | 
				
			||||||
 | 
									 struct llc_addr *daddr,
 | 
				
			||||||
 | 
									 struct llc_addr *laddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sock *sk = __llc_lookup_established(sap, daddr, laddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sk ? : llc_lookup_listener(sap, laddr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	llc_data_accept_state - designates if in this state data can be sent.
 | 
					 *	llc_data_accept_state - designates if in this state data can be sent.
 | 
				
			||||||
 *	@state: state of connection.
 | 
					 *	@state: state of connection.
 | 
				
			||||||
| 
						 | 
					@ -544,14 +577,14 @@ u8 llc_data_accept_state(u8 state)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	find_next_offset - finds offset for next category of transitions
 | 
					 *	llc_find_next_offset - finds offset for next category of transitions
 | 
				
			||||||
 *	@state: state table.
 | 
					 *	@state: state table.
 | 
				
			||||||
 *	@offset: start offset.
 | 
					 *	@offset: start offset.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *	Finds offset of next category of transitions in transition table.
 | 
					 *	Finds offset of next category of transitions in transition table.
 | 
				
			||||||
 *	Returns the start index of next category.
 | 
					 *	Returns the start index of next category.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static u16 find_next_offset(struct llc_conn_state *state, u16 offset)
 | 
					static u16 __init llc_find_next_offset(struct llc_conn_state *state, u16 offset)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 cnt = 0;
 | 
						u16 cnt = 0;
 | 
				
			||||||
	struct llc_conn_state_trans **next_trans;
 | 
						struct llc_conn_state_trans **next_trans;
 | 
				
			||||||
| 
						 | 
					@ -578,8 +611,8 @@ void __init llc_build_offset_table(void)
 | 
				
			||||||
		next_offset = 0;
 | 
							next_offset = 0;
 | 
				
			||||||
		for (ev_type = 0; ev_type < NBR_CONN_EV; ev_type++) {
 | 
							for (ev_type = 0; ev_type < NBR_CONN_EV; ev_type++) {
 | 
				
			||||||
			llc_offset_table[state][ev_type] = next_offset;
 | 
								llc_offset_table[state][ev_type] = next_offset;
 | 
				
			||||||
			next_offset += find_next_offset(curr_state,
 | 
								next_offset += llc_find_next_offset(curr_state,
 | 
				
			||||||
							next_offset) + 1;
 | 
												    next_offset) + 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -623,6 +656,7 @@ static int llc_find_offset(int state, int ev_type)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk)
 | 
					void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						llc_sap_hold(sap);
 | 
				
			||||||
	write_lock_bh(&sap->sk_list.lock);
 | 
						write_lock_bh(&sap->sk_list.lock);
 | 
				
			||||||
	llc_sk(sk)->sap = sap;
 | 
						llc_sk(sk)->sap = sap;
 | 
				
			||||||
	sk_add_node(sk, &sap->sk_list.list);
 | 
						sk_add_node(sk, &sap->sk_list.list);
 | 
				
			||||||
| 
						 | 
					@ -642,6 +676,7 @@ void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk)
 | 
				
			||||||
	write_lock_bh(&sap->sk_list.lock);
 | 
						write_lock_bh(&sap->sk_list.lock);
 | 
				
			||||||
	sk_del_node_init(sk);
 | 
						sk_del_node_init(sk);
 | 
				
			||||||
	write_unlock_bh(&sap->sk_list.lock);
 | 
						write_unlock_bh(&sap->sk_list.lock);
 | 
				
			||||||
 | 
						llc_sap_put(sap);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -654,15 +689,34 @@ void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk)
 | 
				
			||||||
static int llc_conn_rcv(struct sock* sk, struct sk_buff *skb)
 | 
					static int llc_conn_rcv(struct sock* sk, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
						struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 | 
				
			||||||
	struct llc_sock *llc = llc_sk(sk);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!llc->dev)
 | 
					 | 
				
			||||||
		llc->dev = skb->dev;
 | 
					 | 
				
			||||||
	ev->type   = LLC_CONN_EV_TYPE_PDU;
 | 
						ev->type   = LLC_CONN_EV_TYPE_PDU;
 | 
				
			||||||
	ev->reason = 0;
 | 
						ev->reason = 0;
 | 
				
			||||||
	return llc_conn_state_process(sk, skb);
 | 
						return llc_conn_state_process(sk, skb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct sock *llc_create_incoming_sock(struct sock *sk,
 | 
				
			||||||
 | 
										     struct net_device *dev,
 | 
				
			||||||
 | 
										     struct llc_addr *saddr,
 | 
				
			||||||
 | 
										     struct llc_addr *daddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sock *newsk = llc_sk_alloc(sk->sk_family, GFP_ATOMIC,
 | 
				
			||||||
 | 
										  sk->sk_prot);
 | 
				
			||||||
 | 
						struct llc_sock *newllc, *llc = llc_sk(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!newsk)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						newllc = llc_sk(newsk);
 | 
				
			||||||
 | 
						memcpy(&newllc->laddr, daddr, sizeof(newllc->laddr));
 | 
				
			||||||
 | 
						memcpy(&newllc->daddr, saddr, sizeof(newllc->daddr));
 | 
				
			||||||
 | 
						newllc->dev = dev;
 | 
				
			||||||
 | 
						dev_hold(dev);
 | 
				
			||||||
 | 
						llc_sap_add_socket(llc->sap, newsk);
 | 
				
			||||||
 | 
						llc_sap_hold(llc->sap);
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						return newsk;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
 | 
					void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_addr saddr, daddr;
 | 
						struct llc_addr saddr, daddr;
 | 
				
			||||||
| 
						 | 
					@ -673,35 +727,35 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
	llc_pdu_decode_da(skb, daddr.mac);
 | 
						llc_pdu_decode_da(skb, daddr.mac);
 | 
				
			||||||
	llc_pdu_decode_dsap(skb, &daddr.lsap);
 | 
						llc_pdu_decode_dsap(skb, &daddr.lsap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sk = llc_lookup_established(sap, &saddr, &daddr);
 | 
						sk = __llc_lookup(sap, &saddr, &daddr);
 | 
				
			||||||
	if (!sk) {
 | 
						if (!sk)
 | 
				
			||||||
		/*
 | 
							goto drop;
 | 
				
			||||||
		 * Didn't find an active connection; verify if there
 | 
					 | 
				
			||||||
		 * is a listening socket for this llc addr
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		struct llc_sock *llc;
 | 
					 | 
				
			||||||
		struct sock *parent = llc_lookup_listener(sap, &daddr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!parent) {
 | 
					 | 
				
			||||||
			dprintk("llc_lookup_listener failed!\n");
 | 
					 | 
				
			||||||
			goto drop;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC, parent->sk_prot);
 | 
					 | 
				
			||||||
		if (!sk) {
 | 
					 | 
				
			||||||
			sock_put(parent);
 | 
					 | 
				
			||||||
			goto drop;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		llc = llc_sk(sk);
 | 
					 | 
				
			||||||
		memcpy(&llc->laddr, &daddr, sizeof(llc->laddr));
 | 
					 | 
				
			||||||
		memcpy(&llc->daddr, &saddr, sizeof(llc->daddr));
 | 
					 | 
				
			||||||
		llc_sap_add_socket(sap, sk);
 | 
					 | 
				
			||||||
		sock_hold(sk);
 | 
					 | 
				
			||||||
		sock_put(parent);
 | 
					 | 
				
			||||||
		skb->sk = parent;
 | 
					 | 
				
			||||||
	} else
 | 
					 | 
				
			||||||
		skb->sk = sk;
 | 
					 | 
				
			||||||
	bh_lock_sock(sk);
 | 
						bh_lock_sock(sk);
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * This has to be done here and not at the upper layer ->accept
 | 
				
			||||||
 | 
						 * method because of the way the PROCOM state machine works:
 | 
				
			||||||
 | 
						 * it needs to set several state variables (see, for instance,
 | 
				
			||||||
 | 
						 * llc_adm_actions_2 in net/llc/llc_c_st.c) and send a packet to
 | 
				
			||||||
 | 
						 * the originator of the new connection, and this state has to be
 | 
				
			||||||
 | 
						 * in the newly created struct sock private area. -acme
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (unlikely(sk->sk_state == TCP_LISTEN)) {
 | 
				
			||||||
 | 
							struct sock *newsk = llc_create_incoming_sock(sk, skb->dev,
 | 
				
			||||||
 | 
												      &saddr, &daddr);
 | 
				
			||||||
 | 
							if (!newsk)
 | 
				
			||||||
 | 
								goto drop_unlock;
 | 
				
			||||||
 | 
							skb_set_owner_r(skb, newsk);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Can't be skb_set_owner_r, this will be done at the
 | 
				
			||||||
 | 
							 * llc_conn_state_process function, later on, when we will use
 | 
				
			||||||
 | 
							 * skb_queue_rcv_skb to send it to upper layers, this is
 | 
				
			||||||
 | 
							 * another trick required to cope with how the PROCOM state
 | 
				
			||||||
 | 
							 * machine works. -acme
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							skb->sk = sk;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (!sock_owned_by_user(sk))
 | 
						if (!sock_owned_by_user(sk))
 | 
				
			||||||
		llc_conn_rcv(sk, skb);
 | 
							llc_conn_rcv(sk, skb);
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
| 
						 | 
					@ -709,11 +763,16 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
		llc_set_backlog_type(skb, LLC_PACKET);
 | 
							llc_set_backlog_type(skb, LLC_PACKET);
 | 
				
			||||||
		sk_add_backlog(sk, skb);
 | 
							sk_add_backlog(sk, skb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
	bh_unlock_sock(sk);
 | 
						bh_unlock_sock(sk);
 | 
				
			||||||
	sock_put(sk);
 | 
						sock_put(sk);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
drop:
 | 
					drop:
 | 
				
			||||||
	kfree_skb(skb);
 | 
						kfree_skb(skb);
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					drop_unlock:
 | 
				
			||||||
 | 
						kfree_skb(skb);
 | 
				
			||||||
 | 
						goto out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef LLC_REFCNT_DEBUG
 | 
					#undef LLC_REFCNT_DEBUG
 | 
				
			||||||
| 
						 | 
					@ -721,32 +780,6 @@ drop:
 | 
				
			||||||
static atomic_t llc_sock_nr;
 | 
					static atomic_t llc_sock_nr;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 *	llc_release_sockets - releases all sockets in a sap
 | 
					 | 
				
			||||||
 *	@sap: sap to release its sockets
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *	Releases all connections of a sap. Returns 0 if all actions complete
 | 
					 | 
				
			||||||
 *	successfully, nonzero otherwise
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int llc_release_sockets(struct llc_sap *sap)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int rc = 0;
 | 
					 | 
				
			||||||
	struct sock *sk;
 | 
					 | 
				
			||||||
	struct hlist_node *node;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	write_lock_bh(&sap->sk_list.lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sk_for_each(sk, node, &sap->sk_list.list) {
 | 
					 | 
				
			||||||
		llc_sk(sk)->state = LLC_CONN_STATE_TEMP;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (llc_send_disc(sk))
 | 
					 | 
				
			||||||
			rc = 1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	write_unlock_bh(&sap->sk_list.lock);
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	llc_backlog_rcv - Processes rx frames and expired timers.
 | 
					 *	llc_backlog_rcv - Processes rx frames and expired timers.
 | 
				
			||||||
 *	@sk: LLC sock (p8022 connection)
 | 
					 *	@sk: LLC sock (p8022 connection)
 | 
				
			||||||
| 
						 | 
					@ -762,14 +795,14 @@ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	int rc = 0;
 | 
						int rc = 0;
 | 
				
			||||||
	struct llc_sock *llc = llc_sk(sk);
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (llc_backlog_type(skb) == LLC_PACKET) {
 | 
						if (likely(llc_backlog_type(skb) == LLC_PACKET)) {
 | 
				
			||||||
		if (llc->state > 1) /* not closed */
 | 
							if (likely(llc->state > 1)) /* not closed */
 | 
				
			||||||
			rc = llc_conn_rcv(sk, skb);
 | 
								rc = llc_conn_rcv(sk, skb);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			goto out_kfree_skb;
 | 
								goto out_kfree_skb;
 | 
				
			||||||
	} else if (llc_backlog_type(skb) == LLC_EVENT) {
 | 
						} else if (llc_backlog_type(skb) == LLC_EVENT) {
 | 
				
			||||||
		/* timer expiration event */
 | 
							/* timer expiration event */
 | 
				
			||||||
		if (llc->state > 1)  /* not closed */
 | 
							if (likely(llc->state > 1))  /* not closed */
 | 
				
			||||||
			rc = llc_conn_state_process(sk, skb);
 | 
								rc = llc_conn_state_process(sk, skb);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			goto out_kfree_skb;
 | 
								goto out_kfree_skb;
 | 
				
			||||||
| 
						 | 
					@ -799,22 +832,22 @@ static void llc_sk_init(struct sock* sk)
 | 
				
			||||||
	llc->dec_step = llc->connect_step = 1;
 | 
						llc->dec_step = llc->connect_step = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_timer(&llc->ack_timer.timer);
 | 
						init_timer(&llc->ack_timer.timer);
 | 
				
			||||||
	llc->ack_timer.expire	      = LLC_ACK_TIME;
 | 
						llc->ack_timer.expire	      = sysctl_llc2_ack_timeout;
 | 
				
			||||||
	llc->ack_timer.timer.data     = (unsigned long)sk;
 | 
						llc->ack_timer.timer.data     = (unsigned long)sk;
 | 
				
			||||||
	llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
 | 
						llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_timer(&llc->pf_cycle_timer.timer);
 | 
						init_timer(&llc->pf_cycle_timer.timer);
 | 
				
			||||||
	llc->pf_cycle_timer.expire	   = LLC_P_TIME;
 | 
						llc->pf_cycle_timer.expire	   = sysctl_llc2_p_timeout;
 | 
				
			||||||
	llc->pf_cycle_timer.timer.data     = (unsigned long)sk;
 | 
						llc->pf_cycle_timer.timer.data     = (unsigned long)sk;
 | 
				
			||||||
	llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb;
 | 
						llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_timer(&llc->rej_sent_timer.timer);
 | 
						init_timer(&llc->rej_sent_timer.timer);
 | 
				
			||||||
	llc->rej_sent_timer.expire	   = LLC_REJ_TIME;
 | 
						llc->rej_sent_timer.expire	   = sysctl_llc2_rej_timeout;
 | 
				
			||||||
	llc->rej_sent_timer.timer.data     = (unsigned long)sk;
 | 
						llc->rej_sent_timer.timer.data     = (unsigned long)sk;
 | 
				
			||||||
	llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb;
 | 
						llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_timer(&llc->busy_state_timer.timer);
 | 
						init_timer(&llc->busy_state_timer.timer);
 | 
				
			||||||
	llc->busy_state_timer.expire	     = LLC_BUSY_TIME;
 | 
						llc->busy_state_timer.expire	     = sysctl_llc2_busy_timeout;
 | 
				
			||||||
	llc->busy_state_timer.timer.data     = (unsigned long)sk;
 | 
						llc->busy_state_timer.timer.data     = (unsigned long)sk;
 | 
				
			||||||
	llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb;
 | 
						llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -834,7 +867,8 @@ static void llc_sk_init(struct sock* sk)
 | 
				
			||||||
 *	Allocates a LLC sock and initializes it. Returns the new LLC sock
 | 
					 *	Allocates a LLC sock and initializes it. Returns the new LLC sock
 | 
				
			||||||
 *	or %NULL if there's no memory available for one
 | 
					 *	or %NULL if there's no memory available for one
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct sock *llc_sk_alloc(int family, int priority, struct proto *prot)
 | 
					struct sock *llc_sk_alloc(int family, unsigned int __nocast priority,
 | 
				
			||||||
 | 
								 struct proto *prot)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock *sk = sk_alloc(family, priority, prot, 1);
 | 
						struct sock *sk = sk_alloc(family, priority, prot, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,7 @@ static struct llc_sap *llc_sap_alloc(void)
 | 
				
			||||||
		sap->state = LLC_SAP_STATE_ACTIVE;
 | 
							sap->state = LLC_SAP_STATE_ACTIVE;
 | 
				
			||||||
		memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
 | 
							memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
 | 
				
			||||||
		rwlock_init(&sap->sk_list.lock);
 | 
							rwlock_init(&sap->sk_list.lock);
 | 
				
			||||||
 | 
							atomic_set(&sap->refcnt, 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return sap;
 | 
						return sap;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -52,9 +53,7 @@ static struct llc_sap *llc_sap_alloc(void)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void llc_add_sap(struct llc_sap *sap)
 | 
					static void llc_add_sap(struct llc_sap *sap)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	write_lock_bh(&llc_sap_list_lock);
 | 
					 | 
				
			||||||
	list_add_tail(&sap->node, &llc_sap_list);
 | 
						list_add_tail(&sap->node, &llc_sap_list);
 | 
				
			||||||
	write_unlock_bh(&llc_sap_list_lock);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -70,11 +69,25 @@ static void llc_del_sap(struct llc_sap *sap)
 | 
				
			||||||
	write_unlock_bh(&llc_sap_list_lock);
 | 
						write_unlock_bh(&llc_sap_list_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct llc_sap *__llc_sap_find(unsigned char sap_value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct llc_sap* sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(sap, &llc_sap_list, node)
 | 
				
			||||||
 | 
							if (sap->laddr.lsap == sap_value)
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
						sap = NULL;
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						return sap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	llc_sap_find - searchs a SAP in station
 | 
					 *	llc_sap_find - searchs a SAP in station
 | 
				
			||||||
 *	@sap_value: sap to be found
 | 
					 *	@sap_value: sap to be found
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *	Searchs for a sap in the sap list of the LLC's station upon the sap ID.
 | 
					 *	Searchs for a sap in the sap list of the LLC's station upon the sap ID.
 | 
				
			||||||
 | 
					 *	If the sap is found it will be refcounted and the user will have to do
 | 
				
			||||||
 | 
					 *	a llc_sap_put after use.
 | 
				
			||||||
 *	Returns the sap or %NULL if not found.
 | 
					 *	Returns the sap or %NULL if not found.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct llc_sap *llc_sap_find(unsigned char sap_value)
 | 
					struct llc_sap *llc_sap_find(unsigned char sap_value)
 | 
				
			||||||
| 
						 | 
					@ -82,11 +95,9 @@ struct llc_sap *llc_sap_find(unsigned char sap_value)
 | 
				
			||||||
	struct llc_sap* sap;
 | 
						struct llc_sap* sap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	read_lock_bh(&llc_sap_list_lock);
 | 
						read_lock_bh(&llc_sap_list_lock);
 | 
				
			||||||
	list_for_each_entry(sap, &llc_sap_list, node)
 | 
						sap = __llc_sap_find(sap_value);
 | 
				
			||||||
		if (sap->laddr.lsap == sap_value)
 | 
						if (sap)
 | 
				
			||||||
			goto out;
 | 
							llc_sap_hold(sap);
 | 
				
			||||||
	sap = NULL;
 | 
					 | 
				
			||||||
out:
 | 
					 | 
				
			||||||
	read_unlock_bh(&llc_sap_list_lock);
 | 
						read_unlock_bh(&llc_sap_list_lock);
 | 
				
			||||||
	return sap;
 | 
						return sap;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -106,19 +117,20 @@ struct llc_sap *llc_sap_open(unsigned char lsap,
 | 
				
			||||||
					 struct packet_type *pt,
 | 
										 struct packet_type *pt,
 | 
				
			||||||
					 struct net_device *orig_dev))
 | 
										 struct net_device *orig_dev))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct llc_sap *sap = llc_sap_find(lsap);
 | 
						struct llc_sap *sap = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sap) { /* SAP already exists */
 | 
						write_lock_bh(&llc_sap_list_lock);
 | 
				
			||||||
		sap = NULL;
 | 
						if (__llc_sap_find(lsap)) /* SAP already exists */
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	sap = llc_sap_alloc();
 | 
						sap = llc_sap_alloc();
 | 
				
			||||||
	if (!sap)
 | 
						if (!sap)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	sap->laddr.lsap = lsap;
 | 
						sap->laddr.lsap = lsap;
 | 
				
			||||||
	sap->rcv_func	= func;
 | 
						sap->rcv_func	= func;
 | 
				
			||||||
 | 
						llc_sap_hold(sap);
 | 
				
			||||||
	llc_add_sap(sap);
 | 
						llc_add_sap(sap);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
 | 
						write_unlock_bh(&llc_sap_list_lock);
 | 
				
			||||||
	return sap;
 | 
						return sap;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,14 +47,11 @@ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	int rc = -ECONNABORTED;
 | 
						int rc = -ECONNABORTED;
 | 
				
			||||||
	struct llc_sock *llc = llc_sk(sk);
 | 
						struct llc_sock *llc = llc_sk(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (llc->state == LLC_CONN_STATE_ADM)
 | 
						if (unlikely(llc->state == LLC_CONN_STATE_ADM))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = -EBUSY;
 | 
						rc = -EBUSY;
 | 
				
			||||||
	if (llc_data_accept_state(llc->state)) { /* data_conn_refuse */
 | 
						if (unlikely(llc_data_accept_state(llc->state) || /* data_conn_refuse */
 | 
				
			||||||
		llc->failed_data_req = 1;
 | 
							     llc->p_flag)) {
 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (llc->p_flag) {
 | 
					 | 
				
			||||||
		llc->failed_data_req = 1;
 | 
							llc->failed_data_req = 1;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -110,6 +107,7 @@ int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
 | 
				
			||||||
		ev->type      = LLC_CONN_EV_TYPE_PRIM;
 | 
							ev->type      = LLC_CONN_EV_TYPE_PRIM;
 | 
				
			||||||
		ev->prim      = LLC_CONN_PRIM;
 | 
							ev->prim      = LLC_CONN_PRIM;
 | 
				
			||||||
		ev->prim_type = LLC_PRIM_TYPE_REQ;
 | 
							ev->prim_type = LLC_PRIM_TYPE_REQ;
 | 
				
			||||||
 | 
							skb_set_owner_w(skb, sk);
 | 
				
			||||||
		rc = llc_conn_state_process(sk, skb);
 | 
							rc = llc_conn_state_process(sk, skb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
out_put:
 | 
					out_put:
 | 
				
			||||||
| 
						 | 
					@ -144,6 +142,7 @@ int llc_send_disc(struct sock *sk)
 | 
				
			||||||
	skb = alloc_skb(0, GFP_ATOMIC);
 | 
						skb = alloc_skb(0, GFP_ATOMIC);
 | 
				
			||||||
	if (!skb)
 | 
						if (!skb)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
						skb_set_owner_w(skb, sk);
 | 
				
			||||||
	sk->sk_state  = TCP_CLOSING;
 | 
						sk->sk_state  = TCP_CLOSING;
 | 
				
			||||||
	ev	      = llc_conn_ev(skb);
 | 
						ev	      = llc_conn_ev(skb);
 | 
				
			||||||
	ev->type      = LLC_CONN_EV_TYPE_PRIM;
 | 
						ev->type      = LLC_CONN_EV_TYPE_PRIM;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,15 +99,19 @@ out:
 | 
				
			||||||
static inline int llc_fixup_skb(struct sk_buff *skb)
 | 
					static inline int llc_fixup_skb(struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 llc_len = 2;
 | 
						u8 llc_len = 2;
 | 
				
			||||||
	struct llc_pdu_sn *pdu;
 | 
						struct llc_pdu_un *pdu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!pskb_may_pull(skb, sizeof(*pdu)))
 | 
						if (unlikely(!pskb_may_pull(skb, sizeof(*pdu))))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pdu = (struct llc_pdu_sn *)skb->data;
 | 
						pdu = (struct llc_pdu_un *)skb->data;
 | 
				
			||||||
	if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U)
 | 
						if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U)
 | 
				
			||||||
		llc_len = 1;
 | 
							llc_len = 1;
 | 
				
			||||||
	llc_len += 2;
 | 
						llc_len += 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (unlikely(!pskb_may_pull(skb, llc_len)))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	skb->h.raw += llc_len;
 | 
						skb->h.raw += llc_len;
 | 
				
			||||||
	skb_pull(skb, llc_len);
 | 
						skb_pull(skb, llc_len);
 | 
				
			||||||
	if (skb->protocol == htons(ETH_P_802_2)) {
 | 
						if (skb->protocol == htons(ETH_P_802_2)) {
 | 
				
			||||||
| 
						 | 
					@ -166,17 +170,22 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (sap->rcv_func) {
 | 
						if (sap->rcv_func) {
 | 
				
			||||||
		sap->rcv_func(skb, dev, pt, orig_dev);
 | 
							sap->rcv_func(skb, dev, pt, orig_dev);
 | 
				
			||||||
		goto out;
 | 
							goto out_put;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dest = llc_pdu_type(skb);
 | 
						dest = llc_pdu_type(skb);
 | 
				
			||||||
	if (unlikely(!dest || !llc_type_handlers[dest - 1]))
 | 
						if (unlikely(!dest || !llc_type_handlers[dest - 1]))
 | 
				
			||||||
		goto drop;
 | 
							goto drop_put;
 | 
				
			||||||
	llc_type_handlers[dest - 1](sap, skb);
 | 
						llc_type_handlers[dest - 1](sap, skb);
 | 
				
			||||||
 | 
					out_put:
 | 
				
			||||||
 | 
						llc_sap_put(sap);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
drop:
 | 
					drop:
 | 
				
			||||||
	kfree_skb(skb);
 | 
						kfree_skb(skb);
 | 
				
			||||||
	goto out;
 | 
						goto out;
 | 
				
			||||||
 | 
					drop_put:
 | 
				
			||||||
 | 
						kfree_skb(skb);
 | 
				
			||||||
 | 
						goto out_put;
 | 
				
			||||||
handle_station:
 | 
					handle_station:
 | 
				
			||||||
	if (!llc_station_handler)
 | 
						if (!llc_station_handler)
 | 
				
			||||||
		goto drop;
 | 
							goto drop;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,7 +98,7 @@ int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
 | 
				
			||||||
			    dsap, LLC_PDU_CMD);
 | 
								    dsap, LLC_PDU_CMD);
 | 
				
			||||||
	llc_pdu_init_as_ui_cmd(skb);
 | 
						llc_pdu_init_as_ui_cmd(skb);
 | 
				
			||||||
	rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
 | 
						rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
 | 
				
			||||||
	if (!rc)
 | 
						if (likely(!rc))
 | 
				
			||||||
		rc = dev_queue_xmit(skb);
 | 
							rc = dev_queue_xmit(skb);
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,7 +134,7 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v)
 | 
				
			||||||
	llc_ui_format_mac(seq, llc->daddr.mac);
 | 
						llc_ui_format_mac(seq, llc->daddr.mac);
 | 
				
			||||||
	seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap,
 | 
						seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap,
 | 
				
			||||||
		   atomic_read(&sk->sk_wmem_alloc),
 | 
							   atomic_read(&sk->sk_wmem_alloc),
 | 
				
			||||||
		   atomic_read(&sk->sk_rmem_alloc),
 | 
							   atomic_read(&sk->sk_rmem_alloc) - llc->copied_seq,
 | 
				
			||||||
		   sk->sk_state,
 | 
							   sk->sk_state,
 | 
				
			||||||
		   sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1,
 | 
							   sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1,
 | 
				
			||||||
		   llc->link);
 | 
							   llc->link);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,7 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
			    ev->daddr.lsap, LLC_PDU_CMD);
 | 
								    ev->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
	llc_pdu_init_as_ui_cmd(skb);
 | 
						llc_pdu_init_as_ui_cmd(skb);
 | 
				
			||||||
	rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
 | 
						rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
 | 
				
			||||||
	if (!rc)
 | 
						if (likely(!rc))
 | 
				
			||||||
		rc = dev_queue_xmit(skb);
 | 
							rc = dev_queue_xmit(skb);
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -81,7 +81,7 @@ int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
			    ev->daddr.lsap, LLC_PDU_CMD);
 | 
								    ev->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
	llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
 | 
						llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
 | 
				
			||||||
	rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
 | 
						rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
 | 
				
			||||||
	if (!rc)
 | 
						if (likely(!rc))
 | 
				
			||||||
		rc = dev_queue_xmit(skb);
 | 
							rc = dev_queue_xmit(skb);
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -103,15 +103,14 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
	llc_pdu_decode_sa(skb, mac_da);
 | 
						llc_pdu_decode_sa(skb, mac_da);
 | 
				
			||||||
	llc_pdu_decode_da(skb, mac_sa);
 | 
						llc_pdu_decode_da(skb, mac_sa);
 | 
				
			||||||
	llc_pdu_decode_ssap(skb, &dsap);
 | 
						llc_pdu_decode_ssap(skb, &dsap);
 | 
				
			||||||
	nskb = llc_alloc_frame();
 | 
						nskb = llc_alloc_frame(NULL, skb->dev);
 | 
				
			||||||
	if (!nskb)
 | 
						if (!nskb)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	nskb->dev = skb->dev;
 | 
					 | 
				
			||||||
	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
 | 
						llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
 | 
				
			||||||
			    LLC_PDU_RSP);
 | 
								    LLC_PDU_RSP);
 | 
				
			||||||
	llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);
 | 
						llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);
 | 
				
			||||||
	rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
 | 
						rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
 | 
				
			||||||
	if (!rc)
 | 
						if (likely(!rc))
 | 
				
			||||||
		rc = dev_queue_xmit(nskb);
 | 
							rc = dev_queue_xmit(nskb);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
| 
						 | 
					@ -135,7 +134,7 @@ int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
			    ev->daddr.lsap, LLC_PDU_CMD);
 | 
								    ev->daddr.lsap, LLC_PDU_CMD);
 | 
				
			||||||
	llc_pdu_init_as_test_cmd(skb);
 | 
						llc_pdu_init_as_test_cmd(skb);
 | 
				
			||||||
	rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
 | 
						rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
 | 
				
			||||||
	if (!rc)
 | 
						if (likely(!rc))
 | 
				
			||||||
		rc = dev_queue_xmit(skb);
 | 
							rc = dev_queue_xmit(skb);
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -149,15 +148,14 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
	llc_pdu_decode_sa(skb, mac_da);
 | 
						llc_pdu_decode_sa(skb, mac_da);
 | 
				
			||||||
	llc_pdu_decode_da(skb, mac_sa);
 | 
						llc_pdu_decode_da(skb, mac_sa);
 | 
				
			||||||
	llc_pdu_decode_ssap(skb, &dsap);
 | 
						llc_pdu_decode_ssap(skb, &dsap);
 | 
				
			||||||
	nskb = llc_alloc_frame();
 | 
						nskb = llc_alloc_frame(NULL, skb->dev);
 | 
				
			||||||
	if (!nskb)
 | 
						if (!nskb)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	nskb->dev = skb->dev;
 | 
					 | 
				
			||||||
	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
 | 
						llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
 | 
				
			||||||
			    LLC_PDU_RSP);
 | 
								    LLC_PDU_RSP);
 | 
				
			||||||
	llc_pdu_init_as_test_rsp(nskb, skb);
 | 
						llc_pdu_init_as_test_rsp(nskb, skb);
 | 
				
			||||||
	rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
 | 
						rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
 | 
				
			||||||
	if (!rc)
 | 
						if (likely(!rc))
 | 
				
			||||||
		rc = dev_queue_xmit(nskb);
 | 
							rc = dev_queue_xmit(nskb);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,11 +26,12 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	llc_alloc_frame - allocates sk_buff for frame
 | 
					 *	llc_alloc_frame - allocates sk_buff for frame
 | 
				
			||||||
 | 
					 *	@dev: network device this skb will be sent over
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *	Allocates an sk_buff for frame and initializes sk_buff fields.
 | 
					 *	Allocates an sk_buff for frame and initializes sk_buff fields.
 | 
				
			||||||
 *	Returns allocated skb or %NULL when out of memory.
 | 
					 *	Returns allocated skb or %NULL when out of memory.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct sk_buff *llc_alloc_frame(void)
 | 
					struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
 | 
						struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,18 +39,23 @@ struct sk_buff *llc_alloc_frame(void)
 | 
				
			||||||
		skb_reserve(skb, 50);
 | 
							skb_reserve(skb, 50);
 | 
				
			||||||
		skb->nh.raw   = skb->h.raw = skb->data;
 | 
							skb->nh.raw   = skb->h.raw = skb->data;
 | 
				
			||||||
		skb->protocol = htons(ETH_P_802_2);
 | 
							skb->protocol = htons(ETH_P_802_2);
 | 
				
			||||||
		skb->dev      = dev_base->next;
 | 
							skb->dev      = dev;
 | 
				
			||||||
		skb->mac.raw  = skb->head;
 | 
							skb->mac.raw  = skb->head;
 | 
				
			||||||
 | 
							if (sk != NULL)
 | 
				
			||||||
 | 
								skb_set_owner_w(skb, sk);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return skb;
 | 
						return skb;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void llc_save_primitive(struct sk_buff* skb, u8 prim)
 | 
					void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
 | 
						struct sockaddr_llc *addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (skb->sk->sk_type == SOCK_STREAM) /* See UNIX98 */
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
       /* save primitive for use by the user. */
 | 
					       /* save primitive for use by the user. */
 | 
				
			||||||
	addr->sllc_family = skb->sk->sk_family;
 | 
						addr		  = llc_ui_skb_cb(skb);
 | 
				
			||||||
 | 
						addr->sllc_family = sk->sk_family;
 | 
				
			||||||
	addr->sllc_arphrd = skb->dev->type;
 | 
						addr->sllc_arphrd = skb->dev->type;
 | 
				
			||||||
	addr->sllc_test   = prim == LLC_TEST_PRIM;
 | 
						addr->sllc_test   = prim == LLC_TEST_PRIM;
 | 
				
			||||||
	addr->sllc_xid    = prim == LLC_XID_PRIM;
 | 
						addr->sllc_xid    = prim == LLC_XID_PRIM;
 | 
				
			||||||
| 
						 | 
					@ -189,7 +195,7 @@ static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
		if (skb->sk->sk_state == TCP_LISTEN)
 | 
							if (skb->sk->sk_state == TCP_LISTEN)
 | 
				
			||||||
			kfree_skb(skb);
 | 
								kfree_skb(skb);
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			llc_save_primitive(skb, ev->prim);
 | 
								llc_save_primitive(skb->sk, skb, ev->prim);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* queue skb to the user. */
 | 
								/* queue skb to the user. */
 | 
				
			||||||
			if (sock_queue_rcv_skb(skb->sk, skb))
 | 
								if (sock_queue_rcv_skb(skb->sk, skb))
 | 
				
			||||||
| 
						 | 
					@ -308,7 +314,7 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sk = llc_lookup_dgram(sap, &laddr);
 | 
						sk = llc_lookup_dgram(sap, &laddr);
 | 
				
			||||||
	if (sk) {
 | 
						if (sk) {
 | 
				
			||||||
		skb->sk = sk;
 | 
							skb_set_owner_r(skb, sk);
 | 
				
			||||||
		llc_sap_rcv(sap, skb);
 | 
							llc_sap_rcv(sap, skb);
 | 
				
			||||||
		sock_put(sk);
 | 
							sock_put(sk);
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,10 @@ struct llc_station {
 | 
				
			||||||
	struct sk_buff_head	    mac_pdu_q;
 | 
						struct sk_buff_head	    mac_pdu_q;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LLC_STATION_ACK_TIME (3 * HZ)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sysctl_llc_station_ack_timeout = LLC_STATION_ACK_TIME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Types of events (possible values in 'ev->type') */
 | 
					/* Types of events (possible values in 'ev->type') */
 | 
				
			||||||
#define LLC_STATION_EV_TYPE_SIMPLE	1
 | 
					#define LLC_STATION_EV_TYPE_SIMPLE	1
 | 
				
			||||||
#define LLC_STATION_EV_TYPE_CONDITION	2
 | 
					#define LLC_STATION_EV_TYPE_CONDITION	2
 | 
				
			||||||
| 
						 | 
					@ -218,7 +222,8 @@ static void llc_station_send_pdu(struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int llc_station_ac_start_ack_timer(struct sk_buff *skb)
 | 
					static int llc_station_ac_start_ack_timer(struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	mod_timer(&llc_main_station.ack_timer, jiffies + LLC_ACK_TIME * HZ);
 | 
						mod_timer(&llc_main_station.ack_timer,
 | 
				
			||||||
 | 
							  jiffies + sysctl_llc_station_ack_timeout);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -249,14 +254,14 @@ static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb)
 | 
				
			||||||
static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
 | 
					static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc = 1;
 | 
						int rc = 1;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!nskb)
 | 
						if (!nskb)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
 | 
						llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
 | 
				
			||||||
	llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
 | 
						llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
 | 
				
			||||||
	rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa);
 | 
						rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa);
 | 
				
			||||||
	if (rc)
 | 
						if (unlikely(rc))
 | 
				
			||||||
		goto free;
 | 
							goto free;
 | 
				
			||||||
	llc_station_send_pdu(nskb);
 | 
						llc_station_send_pdu(nskb);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
| 
						 | 
					@ -270,18 +275,17 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 mac_da[ETH_ALEN], dsap;
 | 
						u8 mac_da[ETH_ALEN], dsap;
 | 
				
			||||||
	int rc = 1;
 | 
						int rc = 1;
 | 
				
			||||||
	struct sk_buff* nskb = llc_alloc_frame();
 | 
						struct sk_buff* nskb = llc_alloc_frame(NULL, skb->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!nskb)
 | 
						if (!nskb)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = 0;
 | 
						rc = 0;
 | 
				
			||||||
	nskb->dev = skb->dev;
 | 
					 | 
				
			||||||
	llc_pdu_decode_sa(skb, mac_da);
 | 
						llc_pdu_decode_sa(skb, mac_da);
 | 
				
			||||||
	llc_pdu_decode_ssap(skb, &dsap);
 | 
						llc_pdu_decode_ssap(skb, &dsap);
 | 
				
			||||||
	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
 | 
						llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
 | 
				
			||||||
	llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
 | 
						llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
 | 
				
			||||||
	rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
 | 
						rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
 | 
				
			||||||
	if (rc)
 | 
						if (unlikely(rc))
 | 
				
			||||||
		goto free;
 | 
							goto free;
 | 
				
			||||||
	llc_station_send_pdu(nskb);
 | 
						llc_station_send_pdu(nskb);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
| 
						 | 
					@ -295,18 +299,17 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 mac_da[ETH_ALEN], dsap;
 | 
						u8 mac_da[ETH_ALEN], dsap;
 | 
				
			||||||
	int rc = 1;
 | 
						int rc = 1;
 | 
				
			||||||
	struct sk_buff *nskb = llc_alloc_frame();
 | 
						struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!nskb)
 | 
						if (!nskb)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	rc = 0;
 | 
						rc = 0;
 | 
				
			||||||
	nskb->dev = skb->dev;
 | 
					 | 
				
			||||||
	llc_pdu_decode_sa(skb, mac_da);
 | 
						llc_pdu_decode_sa(skb, mac_da);
 | 
				
			||||||
	llc_pdu_decode_ssap(skb, &dsap);
 | 
						llc_pdu_decode_ssap(skb, &dsap);
 | 
				
			||||||
	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
 | 
						llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
 | 
				
			||||||
       	llc_pdu_init_as_test_rsp(nskb, skb);
 | 
					       	llc_pdu_init_as_test_rsp(nskb, skb);
 | 
				
			||||||
	rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
 | 
						rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
 | 
				
			||||||
	if (rc)
 | 
						if (unlikely(rc))
 | 
				
			||||||
		goto free;
 | 
							goto free;
 | 
				
			||||||
	llc_station_send_pdu(nskb);
 | 
						llc_station_send_pdu(nskb);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
| 
						 | 
					@ -689,7 +692,8 @@ int __init llc_station_init(void)
 | 
				
			||||||
	init_timer(&llc_main_station.ack_timer);
 | 
						init_timer(&llc_main_station.ack_timer);
 | 
				
			||||||
	llc_main_station.ack_timer.data     = (unsigned long)&llc_main_station;
 | 
						llc_main_station.ack_timer.data     = (unsigned long)&llc_main_station;
 | 
				
			||||||
	llc_main_station.ack_timer.function = llc_station_ack_tmr_cb;
 | 
						llc_main_station.ack_timer.function = llc_station_ack_tmr_cb;
 | 
				
			||||||
 | 
						llc_main_station.ack_timer.expires  = jiffies +
 | 
				
			||||||
 | 
											sysctl_llc_station_ack_timeout;
 | 
				
			||||||
	skb = alloc_skb(0, GFP_ATOMIC);
 | 
						skb = alloc_skb(0, GFP_ATOMIC);
 | 
				
			||||||
	if (!skb)
 | 
						if (!skb)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
| 
						 | 
					@ -697,7 +701,6 @@ int __init llc_station_init(void)
 | 
				
			||||||
	llc_set_station_handler(llc_station_rcv);
 | 
						llc_set_station_handler(llc_station_rcv);
 | 
				
			||||||
	ev = llc_station_ev(skb);
 | 
						ev = llc_station_ev(skb);
 | 
				
			||||||
	memset(ev, 0, sizeof(*ev));
 | 
						memset(ev, 0, sizeof(*ev));
 | 
				
			||||||
	llc_main_station.ack_timer.expires = jiffies + 3 * HZ;
 | 
					 | 
				
			||||||
	llc_main_station.maximum_retry	= 1;
 | 
						llc_main_station.maximum_retry	= 1;
 | 
				
			||||||
	llc_main_station.state		= LLC_STATION_STATE_DOWN;
 | 
						llc_main_station.state		= LLC_STATION_STATE_DOWN;
 | 
				
			||||||
	ev->type	= LLC_STATION_EV_TYPE_SIMPLE;
 | 
						ev->type	= LLC_STATION_EV_TYPE_SIMPLE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										131
									
								
								net/llc/sysctl_net_llc.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								net/llc/sysctl_net_llc.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,131 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * sysctl_net_llc.c: sysctl interface to LLC net subsystem.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/config.h>
 | 
				
			||||||
 | 
					#include <linux/mm.h>
 | 
				
			||||||
 | 
					#include <linux/init.h>
 | 
				
			||||||
 | 
					#include <linux/sysctl.h>
 | 
				
			||||||
 | 
					#include <net/llc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CONFIG_SYSCTL
 | 
				
			||||||
 | 
					#error This file should not be compiled without CONFIG_SYSCTL defined
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct ctl_table llc2_timeout_table[] = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name	= NET_LLC2_ACK_TIMEOUT,
 | 
				
			||||||
 | 
							.procname	= "ack",
 | 
				
			||||||
 | 
							.data		= &sysctl_llc2_ack_timeout,
 | 
				
			||||||
 | 
							.maxlen		= sizeof(long),
 | 
				
			||||||
 | 
							.mode		= 0644,
 | 
				
			||||||
 | 
							.proc_handler   = &proc_dointvec_jiffies,
 | 
				
			||||||
 | 
							.strategy       = &sysctl_jiffies,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name	= NET_LLC2_BUSY_TIMEOUT,
 | 
				
			||||||
 | 
							.procname	= "busy",
 | 
				
			||||||
 | 
							.data		= &sysctl_llc2_busy_timeout,
 | 
				
			||||||
 | 
							.maxlen		= sizeof(long),
 | 
				
			||||||
 | 
							.mode		= 0644,
 | 
				
			||||||
 | 
							.proc_handler   = &proc_dointvec_jiffies,
 | 
				
			||||||
 | 
							.strategy       = &sysctl_jiffies,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name	= NET_LLC2_P_TIMEOUT,
 | 
				
			||||||
 | 
							.procname	= "p",
 | 
				
			||||||
 | 
							.data		= &sysctl_llc2_p_timeout,
 | 
				
			||||||
 | 
							.maxlen		= sizeof(long),
 | 
				
			||||||
 | 
							.mode		= 0644,
 | 
				
			||||||
 | 
							.proc_handler   = &proc_dointvec_jiffies,
 | 
				
			||||||
 | 
							.strategy       = &sysctl_jiffies,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name	= NET_LLC2_REJ_TIMEOUT,
 | 
				
			||||||
 | 
							.procname	= "rej",
 | 
				
			||||||
 | 
							.data		= &sysctl_llc2_rej_timeout,
 | 
				
			||||||
 | 
							.maxlen		= sizeof(long),
 | 
				
			||||||
 | 
							.mode		= 0644,
 | 
				
			||||||
 | 
							.proc_handler   = &proc_dointvec_jiffies,
 | 
				
			||||||
 | 
							.strategy       = &sysctl_jiffies,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{ 0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct ctl_table llc_station_table[] = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name	= NET_LLC_STATION_ACK_TIMEOUT,
 | 
				
			||||||
 | 
							.procname	= "ack_timeout",
 | 
				
			||||||
 | 
							.data		= &sysctl_llc_station_ack_timeout,
 | 
				
			||||||
 | 
							.maxlen		= sizeof(long),
 | 
				
			||||||
 | 
							.mode		= 0644,
 | 
				
			||||||
 | 
							.proc_handler   = &proc_dointvec_jiffies,
 | 
				
			||||||
 | 
							.strategy       = &sysctl_jiffies,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{ 0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct ctl_table llc2_dir_timeout_table[] = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name	= NET_LLC2,
 | 
				
			||||||
 | 
							.procname	= "timeout",
 | 
				
			||||||
 | 
							.mode		= 0555,
 | 
				
			||||||
 | 
							.child		= llc2_timeout_table,
 | 
				
			||||||
 | 
					       	},
 | 
				
			||||||
 | 
						{ 0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct ctl_table llc_table[] = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name	= NET_LLC2,
 | 
				
			||||||
 | 
							.procname	= "llc2",
 | 
				
			||||||
 | 
							.mode		= 0555,
 | 
				
			||||||
 | 
							.child		= llc2_dir_timeout_table,
 | 
				
			||||||
 | 
					       	},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name       = NET_LLC_STATION,
 | 
				
			||||||
 | 
							.procname       = "station",
 | 
				
			||||||
 | 
							.mode           = 0555,
 | 
				
			||||||
 | 
							.child          = llc_station_table,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{ 0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct ctl_table llc_dir_table[] = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name	= NET_LLC,
 | 
				
			||||||
 | 
							.procname	= "llc",
 | 
				
			||||||
 | 
							.mode		= 0555,
 | 
				
			||||||
 | 
							.child		= llc_table,
 | 
				
			||||||
 | 
					       	},
 | 
				
			||||||
 | 
						{ 0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct ctl_table llc_root_table[] = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.ctl_name	= CTL_NET,
 | 
				
			||||||
 | 
							.procname	= "net",
 | 
				
			||||||
 | 
							.mode		= 0555,
 | 
				
			||||||
 | 
							.child		= llc_dir_table,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{ 0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct ctl_table_header *llc_table_header;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int __init llc_sysctl_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						llc_table_header = register_sysctl_table(llc_root_table, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return llc_table_header ? 0 : -ENOMEM;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void llc_sysctl_exit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (llc_table_header) {
 | 
				
			||||||
 | 
							unregister_sysctl_table(llc_table_header);
 | 
				
			||||||
 | 
							llc_table_header = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -761,12 +761,6 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
 | 
				
			||||||
	if (dev->hard_header) {
 | 
						if (dev->hard_header) {
 | 
				
			||||||
		int res;
 | 
							int res;
 | 
				
			||||||
		err = -EINVAL;
 | 
							err = -EINVAL;
 | 
				
			||||||
		if (saddr) {
 | 
					 | 
				
			||||||
			if (saddr->sll_halen != dev->addr_len)
 | 
					 | 
				
			||||||
				goto out_free;
 | 
					 | 
				
			||||||
			if (saddr->sll_hatype != dev->type)
 | 
					 | 
				
			||||||
				goto out_free;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len);
 | 
							res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len);
 | 
				
			||||||
		if (sock->type != SOCK_DGRAM) {
 | 
							if (sock->type != SOCK_DGRAM) {
 | 
				
			||||||
			skb->tail = skb->data;
 | 
								skb->tail = skb->data;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1700,7 +1700,9 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
 | 
				
			||||||
	struct socket *sock;
 | 
						struct socket *sock;
 | 
				
			||||||
	char address[MAX_SOCK_ADDR];
 | 
						char address[MAX_SOCK_ADDR];
 | 
				
			||||||
	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
 | 
						struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
 | 
				
			||||||
	unsigned char ctl[sizeof(struct cmsghdr) + 20];	/* 20 is size of ipv6_pktinfo */
 | 
						unsigned char ctl[sizeof(struct cmsghdr) + 20]
 | 
				
			||||||
 | 
								__attribute__ ((aligned (sizeof(__kernel_size_t))));
 | 
				
			||||||
 | 
								/* 20 is size of ipv6_pktinfo */
 | 
				
			||||||
	unsigned char *ctl_buf = ctl;
 | 
						unsigned char *ctl_buf = ctl;
 | 
				
			||||||
	struct msghdr msg_sys;
 | 
						struct msghdr msg_sys;
 | 
				
			||||||
	int err, ctl_len, iov_size, total_len;
 | 
						int err, ctl_len, iov_size, total_len;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue