Lines Matching full:pch
269 static void ppp_channel_push(struct channel *pch);
271 struct channel *pch);
278 struct channel *pch);
293 static int ppp_connect_channel(struct channel *pch, int unit);
294 static int ppp_disconnect_channel(struct channel *pch);
295 static void ppp_destroy_channel(struct channel *pch);
646 static int ppp_bridge_channels(struct channel *pch, struct channel *pchb) in ppp_bridge_channels() argument
648 spin_lock(&pch->upl); in ppp_bridge_channels()
649 if (rcu_dereference_protected(pch->ppp, lockdep_is_held(&pch->upl)) || in ppp_bridge_channels()
650 rcu_dereference_protected(pch->bridge, lockdep_is_held(&pch->upl))) { in ppp_bridge_channels()
651 spin_unlock(&pch->upl); in ppp_bridge_channels()
655 rcu_assign_pointer(pch->bridge, pchb); in ppp_bridge_channels()
656 spin_unlock(&pch->upl); in ppp_bridge_channels()
664 refcount_inc(&pch->file.refcnt); in ppp_bridge_channels()
665 rcu_assign_pointer(pchb->bridge, pch); in ppp_bridge_channels()
671 spin_lock(&pch->upl); in ppp_bridge_channels()
672 /* Re-read pch->bridge with upl held in case it was modified concurrently */ in ppp_bridge_channels()
673 pchb = rcu_dereference_protected(pch->bridge, lockdep_is_held(&pch->upl)); in ppp_bridge_channels()
674 RCU_INIT_POINTER(pch->bridge, NULL); in ppp_bridge_channels()
675 spin_unlock(&pch->upl); in ppp_bridge_channels()
685 static int ppp_unbridge_channels(struct channel *pch) in ppp_unbridge_channels() argument
689 spin_lock(&pch->upl); in ppp_unbridge_channels()
690 pchb = rcu_dereference_protected(pch->bridge, lockdep_is_held(&pch->upl)); in ppp_unbridge_channels()
692 spin_unlock(&pch->upl); in ppp_unbridge_channels()
695 RCU_INIT_POINTER(pch->bridge, NULL); in ppp_unbridge_channels()
696 spin_unlock(&pch->upl); in ppp_unbridge_channels()
698 /* Only modify pchb if phcb->bridge points back to pch. in ppp_unbridge_channels()
705 if (pchbb == pch) in ppp_unbridge_channels()
711 if (pchbb == pch) in ppp_unbridge_channels()
712 if (refcount_dec_and_test(&pch->file.refcnt)) in ppp_unbridge_channels()
713 ppp_destroy_channel(pch); in ppp_unbridge_channels()
756 struct channel *pch, *pchb; in ppp_ioctl() local
760 pch = PF_TO_CHANNEL(pf); in ppp_ioctl()
766 err = ppp_connect_channel(pch, unit); in ppp_ioctl()
770 err = ppp_disconnect_channel(pch); in ppp_ioctl()
788 err = ppp_bridge_channels(pch, pchb); in ppp_ioctl()
795 err = ppp_unbridge_channels(pch); in ppp_ioctl()
799 down_read(&pch->chan_sem); in ppp_ioctl()
800 chan = pch->chan; in ppp_ioctl()
804 up_read(&pch->chan_sem); in ppp_ioctl()
1597 struct channel *pch; in ppp_fill_forward_path() local
1602 pch = list_first_or_null_rcu(&ppp->channels, struct channel, clist); in ppp_fill_forward_path()
1603 if (!pch) in ppp_fill_forward_path()
1606 chan = READ_ONCE(pch->chan); in ppp_fill_forward_path()
1882 struct channel *pch; in ppp_push() local
1899 pch = list_entry(list, struct channel, clist); in ppp_push()
1901 spin_lock(&pch->downl); in ppp_push()
1902 if (pch->chan) { in ppp_push()
1903 if (pch->chan->ops->start_xmit(pch->chan, skb)) in ppp_push()
1910 spin_unlock(&pch->downl); in ppp_push()
1946 struct channel *pch; in ppp_mp_explode() local
1960 list_for_each_entry(pch, &ppp->channels, clist) { in ppp_mp_explode()
1961 if (pch->chan) { in ppp_mp_explode()
1962 pch->avail = 1; in ppp_mp_explode()
1964 pch->speed = pch->chan->speed; in ppp_mp_explode()
1966 pch->avail = 0; in ppp_mp_explode()
1968 if (pch->avail) { in ppp_mp_explode()
1969 if (skb_queue_empty(&pch->file.xq) || in ppp_mp_explode()
1970 !pch->had_frag) { in ppp_mp_explode()
1971 if (pch->speed == 0) in ppp_mp_explode()
1974 totspeed += pch->speed; in ppp_mp_explode()
1976 pch->avail = 2; in ppp_mp_explode()
1980 if (!pch->had_frag && i < ppp->nxchan) in ppp_mp_explode()
2023 pch = list_entry(list, struct channel, clist); in ppp_mp_explode()
2025 if (!pch->avail) in ppp_mp_explode()
2032 if (pch->avail == 1) { in ppp_mp_explode()
2036 pch->avail = 1; in ppp_mp_explode()
2040 spin_lock(&pch->downl); in ppp_mp_explode()
2041 if (pch->chan == NULL) { in ppp_mp_explode()
2043 if (pch->speed == 0) in ppp_mp_explode()
2046 totspeed -= pch->speed; in ppp_mp_explode()
2048 spin_unlock(&pch->downl); in ppp_mp_explode()
2049 pch->avail = 0; in ppp_mp_explode()
2066 if (pch->speed == 0) { in ppp_mp_explode()
2074 ((totspeed*totfree)/pch->speed)) - hdrlen; in ppp_mp_explode()
2076 flen += ((totfree - nzero)*pch->speed)/totspeed; in ppp_mp_explode()
2077 nbigger -= ((totfree - nzero)*pch->speed)/ in ppp_mp_explode()
2098 pch->avail = 2; in ppp_mp_explode()
2099 spin_unlock(&pch->downl); in ppp_mp_explode()
2108 mtu = pch->chan->mtu - (hdrlen - 2); in ppp_mp_explode()
2135 chan = pch->chan; in ppp_mp_explode()
2136 if (!skb_queue_empty(&pch->file.xq) || in ppp_mp_explode()
2138 skb_queue_tail(&pch->file.xq, frag); in ppp_mp_explode()
2139 pch->had_frag = 1; in ppp_mp_explode()
2144 spin_unlock(&pch->downl); in ppp_mp_explode()
2151 spin_unlock(&pch->downl); in ppp_mp_explode()
2161 static void __ppp_channel_push(struct channel *pch, struct ppp *ppp) in __ppp_channel_push() argument
2165 spin_lock(&pch->downl); in __ppp_channel_push()
2166 if (pch->chan) { in __ppp_channel_push()
2167 while (!skb_queue_empty(&pch->file.xq)) { in __ppp_channel_push()
2168 skb = skb_dequeue(&pch->file.xq); in __ppp_channel_push()
2169 if (!pch->chan->ops->start_xmit(pch->chan, skb)) { in __ppp_channel_push()
2171 skb_queue_head(&pch->file.xq, skb); in __ppp_channel_push()
2177 skb_queue_purge(&pch->file.xq); in __ppp_channel_push()
2179 spin_unlock(&pch->downl); in __ppp_channel_push()
2181 if (skb_queue_empty(&pch->file.xq)) { in __ppp_channel_push()
2187 static void ppp_channel_push(struct channel *pch) in ppp_channel_push() argument
2193 ppp = rcu_dereference_bh(pch->ppp); in ppp_channel_push()
2198 __ppp_channel_push(pch, ppp); in ppp_channel_push()
2202 __ppp_channel_push(pch, NULL); in ppp_channel_push()
2218 ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) in ppp_do_recv() argument
2222 ppp_receive_frame(ppp, skb, pch); in ppp_do_recv()
2273 static bool ppp_channel_bridge_input(struct channel *pch, struct sk_buff *skb) in ppp_channel_bridge_input() argument
2278 pchb = rcu_dereference(pch->bridge); in ppp_channel_bridge_input()
2289 skb_scrub_packet(skb, !net_eq(pch->chan_net, pchb->chan_net)); in ppp_channel_bridge_input()
2305 struct channel *pch = chan->ppp; in ppp_input() local
2309 if (!pch) { in ppp_input()
2315 if (ppp_channel_bridge_input(pch, skb)) in ppp_input()
2319 ppp = rcu_dereference_bh(pch->ppp); in ppp_input()
2332 skb_queue_tail(&pch->file.rq, skb); in ppp_input()
2334 while (pch->file.rq.qlen > PPP_MAX_RQLEN && in ppp_input()
2335 (skb = skb_dequeue(&pch->file.rq))) in ppp_input()
2337 wake_up_interruptible(&pch->file.rwait); in ppp_input()
2339 ppp_do_recv(ppp, skb, pch); in ppp_input()
2350 struct channel *pch = chan->ppp; in ppp_input_error() local
2354 if (!pch) in ppp_input_error()
2358 ppp = rcu_dereference_bh(pch->ppp); in ppp_input_error()
2364 ppp_do_recv(ppp, skb, pch); in ppp_input_error()
2375 ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) in ppp_receive_frame() argument
2383 ppp_receive_mp_frame(ppp, skb, pch); in ppp_receive_frame()
2617 ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) in ppp_receive_mp_frame() argument
2655 pch->lastseq = seq; in ppp_receive_mp_frame()
2906 struct channel *pch; in ppp_register_net_channel() local
2909 pch = kzalloc(sizeof(struct channel), GFP_KERNEL); in ppp_register_net_channel()
2910 if (!pch) in ppp_register_net_channel()
2915 pch->chan = chan; in ppp_register_net_channel()
2916 pch->chan_net = get_net_track(net, &pch->ns_tracker, GFP_KERNEL); in ppp_register_net_channel()
2917 chan->ppp = pch; in ppp_register_net_channel()
2918 init_ppp_file(&pch->file, CHANNEL); in ppp_register_net_channel()
2919 pch->file.hdrlen = chan->hdrlen; in ppp_register_net_channel()
2921 pch->lastseq = -1; in ppp_register_net_channel()
2923 init_rwsem(&pch->chan_sem); in ppp_register_net_channel()
2924 spin_lock_init(&pch->downl); in ppp_register_net_channel()
2925 spin_lock_init(&pch->upl); in ppp_register_net_channel()
2928 pch->file.index = ++pn->last_channel_index; in ppp_register_net_channel()
2929 list_add(&pch->list, &pn->new_channels); in ppp_register_net_channel()
2941 struct channel *pch = chan->ppp; in ppp_channel_index() local
2943 if (pch) in ppp_channel_index()
2944 return pch->file.index; in ppp_channel_index()
2953 struct channel *pch = chan->ppp; in ppp_unit_number() local
2957 if (pch) { in ppp_unit_number()
2959 ppp = rcu_dereference(pch->ppp); in ppp_unit_number()
2972 struct channel *pch = chan->ppp; in ppp_dev_name() local
2976 if (pch) { in ppp_dev_name()
2978 ppp = rcu_dereference(pch->ppp); in ppp_dev_name()
2994 struct channel *pch = chan->ppp; in ppp_unregister_channel() local
2997 if (!pch) in ppp_unregister_channel()
3006 down_write(&pch->chan_sem); in ppp_unregister_channel()
3007 spin_lock_bh(&pch->downl); in ppp_unregister_channel()
3008 WRITE_ONCE(pch->chan, NULL); in ppp_unregister_channel()
3009 spin_unlock_bh(&pch->downl); in ppp_unregister_channel()
3010 up_write(&pch->chan_sem); in ppp_unregister_channel()
3011 ppp_disconnect_channel(pch); in ppp_unregister_channel()
3013 pn = ppp_pernet(pch->chan_net); in ppp_unregister_channel()
3015 list_del(&pch->list); in ppp_unregister_channel()
3018 ppp_unbridge_channels(pch); in ppp_unregister_channel()
3020 pch->file.dead = 1; in ppp_unregister_channel()
3021 wake_up_interruptible(&pch->file.rwait); in ppp_unregister_channel()
3023 if (refcount_dec_and_test(&pch->file.refcnt)) in ppp_unregister_channel()
3024 ppp_destroy_channel(pch); in ppp_unregister_channel()
3034 struct channel *pch = chan->ppp; in ppp_output_wakeup() local
3036 if (!pch) in ppp_output_wakeup()
3038 ppp_channel_push(pch); in ppp_output_wakeup()
3470 struct channel *pch; in ppp_find_channel() local
3472 list_for_each_entry(pch, &pn->new_channels, list) { in ppp_find_channel()
3473 if (pch->file.index == unit) { in ppp_find_channel()
3474 list_move(&pch->list, &pn->all_channels); in ppp_find_channel()
3475 return pch; in ppp_find_channel()
3479 list_for_each_entry(pch, &pn->all_channels, list) { in ppp_find_channel()
3480 if (pch->file.index == unit) in ppp_find_channel()
3481 return pch; in ppp_find_channel()
3491 ppp_connect_channel(struct channel *pch, int unit) in ppp_connect_channel() argument
3498 pn = ppp_pernet(pch->chan_net); in ppp_connect_channel()
3504 spin_lock(&pch->upl); in ppp_connect_channel()
3506 if (rcu_dereference_protected(pch->ppp, lockdep_is_held(&pch->upl)) || in ppp_connect_channel()
3507 rcu_dereference_protected(pch->bridge, lockdep_is_held(&pch->upl))) in ppp_connect_channel()
3511 spin_lock_bh(&pch->downl); in ppp_connect_channel()
3512 if (!pch->chan) { in ppp_connect_channel()
3514 spin_unlock_bh(&pch->downl); in ppp_connect_channel()
3519 if (pch->chan->direct_xmit) in ppp_connect_channel()
3523 spin_unlock_bh(&pch->downl); in ppp_connect_channel()
3524 if (pch->file.hdrlen > ppp->file.hdrlen) in ppp_connect_channel()
3525 ppp->file.hdrlen = pch->file.hdrlen; in ppp_connect_channel()
3526 hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */ in ppp_connect_channel()
3529 list_add_tail_rcu(&pch->clist, &ppp->channels); in ppp_connect_channel()
3531 rcu_assign_pointer(pch->ppp, ppp); in ppp_connect_channel()
3537 spin_unlock(&pch->upl); in ppp_connect_channel()
3547 ppp_disconnect_channel(struct channel *pch) in ppp_disconnect_channel() argument
3552 spin_lock(&pch->upl); in ppp_disconnect_channel()
3553 ppp = rcu_replace_pointer(pch->ppp, NULL, lockdep_is_held(&pch->upl)); in ppp_disconnect_channel()
3554 spin_unlock(&pch->upl); in ppp_disconnect_channel()
3558 list_del_rcu(&pch->clist); in ppp_disconnect_channel()
3573 static void ppp_destroy_channel(struct channel *pch) in ppp_destroy_channel() argument
3575 put_net_track(pch->chan_net, &pch->ns_tracker); in ppp_destroy_channel()
3576 pch->chan_net = NULL; in ppp_destroy_channel()
3580 if (!pch->file.dead) { in ppp_destroy_channel()
3582 pr_err("ppp: destroying undead channel %p !\n", pch); in ppp_destroy_channel()
3585 skb_queue_purge(&pch->file.xq); in ppp_destroy_channel()
3586 skb_queue_purge(&pch->file.rq); in ppp_destroy_channel()
3587 kfree(pch); in ppp_destroy_channel()