aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ppp
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-03-28 13:58:23 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-31 00:45:09 -0400
commit568f194e8bd16c353ad50f9ab95d98b20578a39d (patch)
tree768ccdcbc54ce05bcae257a0600f350cd0b1c5c5 /drivers/net/ppp
parent164d8c6665213c931645578310256da7b1259331 (diff)
net: ppp: use sk_unattached_filter api
For the ppp driver, there are currently two open-coded BPF filters in use, that is, pass_filter and active_filter. Migrate both to make proper use of sk_unattached_filter_{create,destroy} API so that the actual BPF code is decoupled from direct access, and filters can be jited as a side-effect by the internal filter compiler. Joint work with Alexei Starovoitov. Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Cc: Paul Mackerras <paulus@samba.org> Cc: linux-ppp@vger.kernel.org Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ppp')
-rw-r--r--drivers/net/ppp/ppp_generic.c60
1 files changed, 41 insertions, 19 deletions
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 72ff14b811c6..e3923ebb693f 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -143,9 +143,8 @@ struct ppp {
143 struct sk_buff_head mrq; /* MP: receive reconstruction queue */ 143 struct sk_buff_head mrq; /* MP: receive reconstruction queue */
144#endif /* CONFIG_PPP_MULTILINK */ 144#endif /* CONFIG_PPP_MULTILINK */
145#ifdef CONFIG_PPP_FILTER 145#ifdef CONFIG_PPP_FILTER
146 struct sock_filter *pass_filter; /* filter for packets to pass */ 146 struct sk_filter *pass_filter; /* filter for packets to pass */
147 struct sock_filter *active_filter;/* filter for pkts to reset idle */ 147 struct sk_filter *active_filter;/* filter for pkts to reset idle */
148 unsigned pass_len, active_len;
149#endif /* CONFIG_PPP_FILTER */ 148#endif /* CONFIG_PPP_FILTER */
150 struct net *ppp_net; /* the net we belong to */ 149 struct net *ppp_net; /* the net we belong to */
151 struct ppp_link_stats stats64; /* 64 bit network stats */ 150 struct ppp_link_stats stats64; /* 64 bit network stats */
@@ -755,28 +754,42 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
755 case PPPIOCSPASS: 754 case PPPIOCSPASS:
756 { 755 {
757 struct sock_filter *code; 756 struct sock_filter *code;
757
758 err = get_filter(argp, &code); 758 err = get_filter(argp, &code);
759 if (err >= 0) { 759 if (err >= 0) {
760 struct sock_fprog fprog = {
761 .len = err,
762 .filter = code,
763 };
764
760 ppp_lock(ppp); 765 ppp_lock(ppp);
761 kfree(ppp->pass_filter); 766 if (ppp->pass_filter)
762 ppp->pass_filter = code; 767 sk_unattached_filter_destroy(ppp->pass_filter);
763 ppp->pass_len = err; 768 err = sk_unattached_filter_create(&ppp->pass_filter,
769 &fprog);
770 kfree(code);
764 ppp_unlock(ppp); 771 ppp_unlock(ppp);
765 err = 0;
766 } 772 }
767 break; 773 break;
768 } 774 }
769 case PPPIOCSACTIVE: 775 case PPPIOCSACTIVE:
770 { 776 {
771 struct sock_filter *code; 777 struct sock_filter *code;
778
772 err = get_filter(argp, &code); 779 err = get_filter(argp, &code);
773 if (err >= 0) { 780 if (err >= 0) {
781 struct sock_fprog fprog = {
782 .len = err,
783 .filter = code,
784 };
785
774 ppp_lock(ppp); 786 ppp_lock(ppp);
775 kfree(ppp->active_filter); 787 if (ppp->active_filter)
776 ppp->active_filter = code; 788 sk_unattached_filter_destroy(ppp->active_filter);
777 ppp->active_len = err; 789 err = sk_unattached_filter_create(&ppp->active_filter,
790 &fprog);
791 kfree(code);
778 ppp_unlock(ppp); 792 ppp_unlock(ppp);
779 err = 0;
780 } 793 }
781 break; 794 break;
782 } 795 }
@@ -1184,7 +1197,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
1184 a four-byte PPP header on each packet */ 1197 a four-byte PPP header on each packet */
1185 *skb_push(skb, 2) = 1; 1198 *skb_push(skb, 2) = 1;
1186 if (ppp->pass_filter && 1199 if (ppp->pass_filter &&
1187 sk_run_filter(skb, ppp->pass_filter) == 0) { 1200 SK_RUN_FILTER(ppp->pass_filter, skb) == 0) {
1188 if (ppp->debug & 1) 1201 if (ppp->debug & 1)
1189 netdev_printk(KERN_DEBUG, ppp->dev, 1202 netdev_printk(KERN_DEBUG, ppp->dev,
1190 "PPP: outbound frame " 1203 "PPP: outbound frame "
@@ -1194,7 +1207,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
1194 } 1207 }
1195 /* if this packet passes the active filter, record the time */ 1208 /* if this packet passes the active filter, record the time */
1196 if (!(ppp->active_filter && 1209 if (!(ppp->active_filter &&
1197 sk_run_filter(skb, ppp->active_filter) == 0)) 1210 SK_RUN_FILTER(ppp->active_filter, skb) == 0))
1198 ppp->last_xmit = jiffies; 1211 ppp->last_xmit = jiffies;
1199 skb_pull(skb, 2); 1212 skb_pull(skb, 2);
1200#else 1213#else
@@ -1818,7 +1831,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
1818 1831
1819 *skb_push(skb, 2) = 0; 1832 *skb_push(skb, 2) = 0;
1820 if (ppp->pass_filter && 1833 if (ppp->pass_filter &&
1821 sk_run_filter(skb, ppp->pass_filter) == 0) { 1834 SK_RUN_FILTER(ppp->pass_filter, skb) == 0) {
1822 if (ppp->debug & 1) 1835 if (ppp->debug & 1)
1823 netdev_printk(KERN_DEBUG, ppp->dev, 1836 netdev_printk(KERN_DEBUG, ppp->dev,
1824 "PPP: inbound frame " 1837 "PPP: inbound frame "
@@ -1827,7 +1840,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
1827 return; 1840 return;
1828 } 1841 }
1829 if (!(ppp->active_filter && 1842 if (!(ppp->active_filter &&
1830 sk_run_filter(skb, ppp->active_filter) == 0)) 1843 SK_RUN_FILTER(ppp->active_filter, skb) == 0))
1831 ppp->last_recv = jiffies; 1844 ppp->last_recv = jiffies;
1832 __skb_pull(skb, 2); 1845 __skb_pull(skb, 2);
1833 } else 1846 } else
@@ -2672,6 +2685,10 @@ ppp_create_interface(struct net *net, int unit, int *retp)
2672 ppp->minseq = -1; 2685 ppp->minseq = -1;
2673 skb_queue_head_init(&ppp->mrq); 2686 skb_queue_head_init(&ppp->mrq);
2674#endif /* CONFIG_PPP_MULTILINK */ 2687#endif /* CONFIG_PPP_MULTILINK */
2688#ifdef CONFIG_PPP_FILTER
2689 ppp->pass_filter = NULL;
2690 ppp->active_filter = NULL;
2691#endif /* CONFIG_PPP_FILTER */
2675 2692
2676 /* 2693 /*
2677 * drum roll: don't forget to set 2694 * drum roll: don't forget to set
@@ -2802,10 +2819,15 @@ static void ppp_destroy_interface(struct ppp *ppp)
2802 skb_queue_purge(&ppp->mrq); 2819 skb_queue_purge(&ppp->mrq);
2803#endif /* CONFIG_PPP_MULTILINK */ 2820#endif /* CONFIG_PPP_MULTILINK */
2804#ifdef CONFIG_PPP_FILTER 2821#ifdef CONFIG_PPP_FILTER
2805 kfree(ppp->pass_filter); 2822 if (ppp->pass_filter) {
2806 ppp->pass_filter = NULL; 2823 sk_unattached_filter_destroy(ppp->pass_filter);
2807 kfree(ppp->active_filter); 2824 ppp->pass_filter = NULL;
2808 ppp->active_filter = NULL; 2825 }
2826
2827 if (ppp->active_filter) {
2828 sk_unattached_filter_destroy(ppp->active_filter);
2829 ppp->active_filter = NULL;
2830 }
2809#endif /* CONFIG_PPP_FILTER */ 2831#endif /* CONFIG_PPP_FILTER */
2810 2832
2811 kfree_skb(ppp->xmit_pending); 2833 kfree_skb(ppp->xmit_pending);