diff options
Diffstat (limited to 'drivers/net/ppp/ppp_generic.c')
| -rw-r--r-- | drivers/net/ppp/ppp_generic.c | 78 | 
1 files changed, 52 insertions, 26 deletions
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 72ff14b811c..d5b77ef3a21 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -143,9 +143,8 @@ struct ppp {  	struct sk_buff_head mrq;	/* MP: receive reconstruction queue */  #endif /* CONFIG_PPP_MULTILINK */  #ifdef CONFIG_PPP_FILTER -	struct sock_filter *pass_filter;	/* filter for packets to pass */ -	struct sock_filter *active_filter;/* filter for pkts to reset idle */ -	unsigned pass_len, active_len; +	struct sk_filter *pass_filter;	/* filter for packets to pass */ +	struct sk_filter *active_filter;/* filter for pkts to reset idle */  #endif /* CONFIG_PPP_FILTER */  	struct net	*ppp_net;	/* the net we belong to */  	struct ppp_link_stats stats64;	/* 64 bit network stats */ @@ -540,7 +539,7 @@ static int get_filter(void __user *arg, struct sock_filter **p)  {  	struct sock_fprog uprog;  	struct sock_filter *code = NULL; -	int len, err; +	int len;  	if (copy_from_user(&uprog, arg, sizeof(uprog)))  		return -EFAULT; @@ -555,12 +554,6 @@ static int get_filter(void __user *arg, struct sock_filter **p)  	if (IS_ERR(code))  		return PTR_ERR(code); -	err = sk_chk_filter(code, uprog.len); -	if (err) { -		kfree(code); -		return err; -	} -  	*p = code;  	return uprog.len;  } @@ -755,28 +748,52 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)  	case PPPIOCSPASS:  	{  		struct sock_filter *code; +  		err = get_filter(argp, &code);  		if (err >= 0) { +			struct sock_fprog_kern fprog = { +				.len = err, +				.filter = code, +			}; +  			ppp_lock(ppp); -			kfree(ppp->pass_filter); -			ppp->pass_filter = code; -			ppp->pass_len = err; +			if (ppp->pass_filter) { +				sk_unattached_filter_destroy(ppp->pass_filter); +				ppp->pass_filter = NULL; +			} +			if (fprog.filter != NULL) +				err = sk_unattached_filter_create(&ppp->pass_filter, +								  &fprog); +			else +				err = 0; +			kfree(code);  			ppp_unlock(ppp); -			err = 0;  		}  		break;  	}  	case PPPIOCSACTIVE:  	{  		struct sock_filter *code; +  		err = get_filter(argp, &code);  		if (err >= 0) { +			struct sock_fprog_kern fprog = { +				.len = err, +				.filter = code, +			}; +  			ppp_lock(ppp); -			kfree(ppp->active_filter); -			ppp->active_filter = code; -			ppp->active_len = err; +			if (ppp->active_filter) { +				sk_unattached_filter_destroy(ppp->active_filter); +				ppp->active_filter = NULL; +			} +			if (fprog.filter != NULL) +				err = sk_unattached_filter_create(&ppp->active_filter, +								  &fprog); +			else +				err = 0; +			kfree(code);  			ppp_unlock(ppp); -			err = 0;  		}  		break;  	} @@ -1184,7 +1201,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)  		   a four-byte PPP header on each packet */  		*skb_push(skb, 2) = 1;  		if (ppp->pass_filter && -		    sk_run_filter(skb, ppp->pass_filter) == 0) { +		    SK_RUN_FILTER(ppp->pass_filter, skb) == 0) {  			if (ppp->debug & 1)  				netdev_printk(KERN_DEBUG, ppp->dev,  					      "PPP: outbound frame " @@ -1194,7 +1211,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)  		}  		/* if this packet passes the active filter, record the time */  		if (!(ppp->active_filter && -		      sk_run_filter(skb, ppp->active_filter) == 0)) +		      SK_RUN_FILTER(ppp->active_filter, skb) == 0))  			ppp->last_xmit = jiffies;  		skb_pull(skb, 2);  #else @@ -1818,7 +1835,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)  			*skb_push(skb, 2) = 0;  			if (ppp->pass_filter && -			    sk_run_filter(skb, ppp->pass_filter) == 0) { +			    SK_RUN_FILTER(ppp->pass_filter, skb) == 0) {  				if (ppp->debug & 1)  					netdev_printk(KERN_DEBUG, ppp->dev,  						      "PPP: inbound frame " @@ -1827,7 +1844,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)  				return;  			}  			if (!(ppp->active_filter && -			      sk_run_filter(skb, ppp->active_filter) == 0)) +			      SK_RUN_FILTER(ppp->active_filter, skb) == 0))  				ppp->last_recv = jiffies;  			__skb_pull(skb, 2);  		} else @@ -2672,6 +2689,10 @@ ppp_create_interface(struct net *net, int unit, int *retp)  	ppp->minseq = -1;  	skb_queue_head_init(&ppp->mrq);  #endif /* CONFIG_PPP_MULTILINK */ +#ifdef CONFIG_PPP_FILTER +	ppp->pass_filter = NULL; +	ppp->active_filter = NULL; +#endif /* CONFIG_PPP_FILTER */  	/*  	 * drum roll: don't forget to set @@ -2802,10 +2823,15 @@ static void ppp_destroy_interface(struct ppp *ppp)  	skb_queue_purge(&ppp->mrq);  #endif /* CONFIG_PPP_MULTILINK */  #ifdef CONFIG_PPP_FILTER -	kfree(ppp->pass_filter); -	ppp->pass_filter = NULL; -	kfree(ppp->active_filter); -	ppp->active_filter = NULL; +	if (ppp->pass_filter) { +		sk_unattached_filter_destroy(ppp->pass_filter); +		ppp->pass_filter = NULL; +	} + +	if (ppp->active_filter) { +		sk_unattached_filter_destroy(ppp->active_filter); +		ppp->active_filter = NULL; +	}  #endif /* CONFIG_PPP_FILTER */  	kfree_skb(ppp->xmit_pending);  | 
