Commit 568f194e8bd16c353ad50f9ab95d98b20578a39d

Authored by Daniel Borkmann
Committed by David S. Miller
1 parent 164d8c6665

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>

Showing 1 changed file with 41 additions and 19 deletions Side-by-side Diff

drivers/net/ppp/ppp_generic.c
... ... @@ -143,9 +143,8 @@
143 143 struct sk_buff_head mrq; /* MP: receive reconstruction queue */
144 144 #endif /* CONFIG_PPP_MULTILINK */
145 145 #ifdef CONFIG_PPP_FILTER
146   - struct sock_filter *pass_filter; /* filter for packets to pass */
147   - struct sock_filter *active_filter;/* filter for pkts to reset idle */
148   - unsigned pass_len, active_len;
  146 + struct sk_filter *pass_filter; /* filter for packets to pass */
  147 + struct sk_filter *active_filter;/* filter for pkts to reset idle */
149 148 #endif /* CONFIG_PPP_FILTER */
150 149 struct net *ppp_net; /* the net we belong to */
151 150 struct ppp_link_stats stats64; /* 64 bit network stats */
152 151  
153 152  
154 153  
155 154  
156 155  
157 156  
158 157  
... ... @@ -755,28 +754,42 @@
755 754 case PPPIOCSPASS:
756 755 {
757 756 struct sock_filter *code;
  757 +
758 758 err = get_filter(argp, &code);
759 759 if (err >= 0) {
  760 + struct sock_fprog fprog = {
  761 + .len = err,
  762 + .filter = code,
  763 + };
  764 +
760 765 ppp_lock(ppp);
761   - kfree(ppp->pass_filter);
762   - ppp->pass_filter = code;
763   - ppp->pass_len = err;
  766 + if (ppp->pass_filter)
  767 + sk_unattached_filter_destroy(ppp->pass_filter);
  768 + err = sk_unattached_filter_create(&ppp->pass_filter,
  769 + &fprog);
  770 + kfree(code);
764 771 ppp_unlock(ppp);
765   - err = 0;
766 772 }
767 773 break;
768 774 }
769 775 case PPPIOCSACTIVE:
770 776 {
771 777 struct sock_filter *code;
  778 +
772 779 err = get_filter(argp, &code);
773 780 if (err >= 0) {
  781 + struct sock_fprog fprog = {
  782 + .len = err,
  783 + .filter = code,
  784 + };
  785 +
774 786 ppp_lock(ppp);
775   - kfree(ppp->active_filter);
776   - ppp->active_filter = code;
777   - ppp->active_len = err;
  787 + if (ppp->active_filter)
  788 + sk_unattached_filter_destroy(ppp->active_filter);
  789 + err = sk_unattached_filter_create(&ppp->active_filter,
  790 + &fprog);
  791 + kfree(code);
778 792 ppp_unlock(ppp);
779   - err = 0;
780 793 }
781 794 break;
782 795 }
... ... @@ -1184,7 +1197,7 @@
1184 1197 a four-byte PPP header on each packet */
1185 1198 *skb_push(skb, 2) = 1;
1186 1199 if (ppp->pass_filter &&
1187   - sk_run_filter(skb, ppp->pass_filter) == 0) {
  1200 + SK_RUN_FILTER(ppp->pass_filter, skb) == 0) {
1188 1201 if (ppp->debug & 1)
1189 1202 netdev_printk(KERN_DEBUG, ppp->dev,
1190 1203 "PPP: outbound frame "
... ... @@ -1194,7 +1207,7 @@
1194 1207 }
1195 1208 /* if this packet passes the active filter, record the time */
1196 1209 if (!(ppp->active_filter &&
1197   - sk_run_filter(skb, ppp->active_filter) == 0))
  1210 + SK_RUN_FILTER(ppp->active_filter, skb) == 0))
1198 1211 ppp->last_xmit = jiffies;
1199 1212 skb_pull(skb, 2);
1200 1213 #else
... ... @@ -1818,7 +1831,7 @@
1818 1831  
1819 1832 *skb_push(skb, 2) = 0;
1820 1833 if (ppp->pass_filter &&
1821   - sk_run_filter(skb, ppp->pass_filter) == 0) {
  1834 + SK_RUN_FILTER(ppp->pass_filter, skb) == 0) {
1822 1835 if (ppp->debug & 1)
1823 1836 netdev_printk(KERN_DEBUG, ppp->dev,
1824 1837 "PPP: inbound frame "
... ... @@ -1827,7 +1840,7 @@
1827 1840 return;
1828 1841 }
1829 1842 if (!(ppp->active_filter &&
1830   - sk_run_filter(skb, ppp->active_filter) == 0))
  1843 + SK_RUN_FILTER(ppp->active_filter, skb) == 0))
1831 1844 ppp->last_recv = jiffies;
1832 1845 __skb_pull(skb, 2);
1833 1846 } else
... ... @@ -2672,6 +2685,10 @@
2672 2685 ppp->minseq = -1;
2673 2686 skb_queue_head_init(&ppp->mrq);
2674 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 2694 * drum roll: don't forget to set
... ... @@ -2802,10 +2819,15 @@
2802 2819 skb_queue_purge(&ppp->mrq);
2803 2820 #endif /* CONFIG_PPP_MULTILINK */
2804 2821 #ifdef CONFIG_PPP_FILTER
2805   - kfree(ppp->pass_filter);
2806   - ppp->pass_filter = NULL;
2807   - kfree(ppp->active_filter);
2808   - ppp->active_filter = NULL;
  2822 + if (ppp->pass_filter) {
  2823 + sk_unattached_filter_destroy(ppp->pass_filter);
  2824 + ppp->pass_filter = NULL;
  2825 + }
  2826 +
  2827 + if (ppp->active_filter) {
  2828 + sk_unattached_filter_destroy(ppp->active_filter);
  2829 + ppp->active_filter = NULL;
  2830 + }
2809 2831 #endif /* CONFIG_PPP_FILTER */
2810 2832  
2811 2833 kfree_skb(ppp->xmit_pending);