diff options
| author | Daniel Borkmann <dborkman@redhat.com> | 2014-03-28 13:58:23 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-03-31 00:45:09 -0400 |
| commit | 568f194e8bd16c353ad50f9ab95d98b20578a39d (patch) | |
| tree | 768ccdcbc54ce05bcae257a0600f350cd0b1c5c5 /drivers/net/ppp | |
| parent | 164d8c6665213c931645578310256da7b1259331 (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.c | 60 |
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); |
