Lines Matching refs:session

158 static void l2tp_session_free(struct l2tp_session *session)  in l2tp_session_free()  argument
160 trace_free_session(session); in l2tp_session_free()
161 if (session->tunnel) in l2tp_session_free()
162 l2tp_tunnel_dec_refcount(session->tunnel); in l2tp_session_free()
163 kfree(session); in l2tp_session_free()
191 void l2tp_session_inc_refcount(struct l2tp_session *session) in l2tp_session_inc_refcount() argument
193 refcount_inc(&session->ref_count); in l2tp_session_inc_refcount()
197 void l2tp_session_dec_refcount(struct l2tp_session *session) in l2tp_session_dec_refcount() argument
199 if (refcount_dec_and_test(&session->ref_count)) in l2tp_session_dec_refcount()
200 l2tp_session_free(session); in l2tp_session_dec_refcount()
247 struct l2tp_session *session; in l2tp_tunnel_get_session() local
252 hlist_for_each_entry_rcu(session, session_list, hlist) in l2tp_tunnel_get_session()
253 if (session->session_id == session_id) { in l2tp_tunnel_get_session()
254 l2tp_session_inc_refcount(session); in l2tp_tunnel_get_session()
257 return session; in l2tp_tunnel_get_session()
268 struct l2tp_session *session; in l2tp_session_get() local
273 hlist_for_each_entry_rcu(session, session_list, global_hlist) in l2tp_session_get()
274 if (session->session_id == session_id) { in l2tp_session_get()
275 l2tp_session_inc_refcount(session); in l2tp_session_get()
278 return session; in l2tp_session_get()
289 struct l2tp_session *session; in l2tp_session_get_nth() local
294 hlist_for_each_entry_rcu(session, &tunnel->session_hlist[hash], hlist) { in l2tp_session_get_nth()
296 l2tp_session_inc_refcount(session); in l2tp_session_get_nth()
298 return session; in l2tp_session_get_nth()
317 struct l2tp_session *session; in l2tp_session_get_by_ifname() local
321 hlist_for_each_entry_rcu(session, &pn->l2tp_session_hlist[hash], global_hlist) { in l2tp_session_get_by_ifname()
322 if (!strcmp(session->ifname, ifname)) { in l2tp_session_get_by_ifname()
323 l2tp_session_inc_refcount(session); in l2tp_session_get_by_ifname()
326 return session; in l2tp_session_get_by_ifname()
337 int l2tp_session_register(struct l2tp_session *session, in l2tp_session_register() argument
346 head = l2tp_session_id_hash(tunnel, session->session_id); in l2tp_session_register()
355 if (session_walk->session_id == session->session_id) { in l2tp_session_register()
362 g_head = l2tp_session_id_hash_2(pn, session->session_id); in l2tp_session_register()
370 if (session_walk->session_id == session->session_id && in l2tp_session_register()
378 hlist_add_head_rcu(&session->global_hlist, g_head); in l2tp_session_register()
385 hlist_add_head_rcu(&session->hlist, head); in l2tp_session_register()
388 trace_register_session(session); in l2tp_session_register()
408 static void l2tp_recv_queue_skb(struct l2tp_session *session, struct sk_buff *skb) in l2tp_recv_queue_skb() argument
414 spin_lock_bh(&session->reorder_q.lock); in l2tp_recv_queue_skb()
415 skb_queue_walk_safe(&session->reorder_q, skbp, tmp) { in l2tp_recv_queue_skb()
417 __skb_queue_before(&session->reorder_q, skbp, skb); in l2tp_recv_queue_skb()
418 atomic_long_inc(&session->stats.rx_oos_packets); in l2tp_recv_queue_skb()
423 __skb_queue_tail(&session->reorder_q, skb); in l2tp_recv_queue_skb()
426 spin_unlock_bh(&session->reorder_q.lock); in l2tp_recv_queue_skb()
431 static void l2tp_recv_dequeue_skb(struct l2tp_session *session, struct sk_buff *skb) in l2tp_recv_dequeue_skb() argument
433 struct l2tp_tunnel *tunnel = session->tunnel; in l2tp_recv_dequeue_skb()
443 atomic_long_inc(&session->stats.rx_packets); in l2tp_recv_dequeue_skb()
444 atomic_long_add(length, &session->stats.rx_bytes); in l2tp_recv_dequeue_skb()
448 session->nr++; in l2tp_recv_dequeue_skb()
449 session->nr &= session->nr_max; in l2tp_recv_dequeue_skb()
450 trace_session_seqnum_update(session); in l2tp_recv_dequeue_skb()
454 if (session->recv_skb) in l2tp_recv_dequeue_skb()
455 (*session->recv_skb)(session, skb, L2TP_SKB_CB(skb)->length); in l2tp_recv_dequeue_skb()
463 static void l2tp_recv_dequeue(struct l2tp_session *session) in l2tp_recv_dequeue() argument
473 spin_lock_bh(&session->reorder_q.lock); in l2tp_recv_dequeue()
474 skb_queue_walk_safe(&session->reorder_q, skb, tmp) { in l2tp_recv_dequeue()
479 atomic_long_inc(&session->stats.rx_seq_discards); in l2tp_recv_dequeue()
480 atomic_long_inc(&session->stats.rx_errors); in l2tp_recv_dequeue()
481 trace_session_pkt_expired(session, cb->ns); in l2tp_recv_dequeue()
482 session->reorder_skip = 1; in l2tp_recv_dequeue()
483 __skb_unlink(skb, &session->reorder_q); in l2tp_recv_dequeue()
489 if (session->reorder_skip) { in l2tp_recv_dequeue()
490 session->reorder_skip = 0; in l2tp_recv_dequeue()
491 session->nr = cb->ns; in l2tp_recv_dequeue()
492 trace_session_seqnum_reset(session); in l2tp_recv_dequeue()
494 if (cb->ns != session->nr) in l2tp_recv_dequeue()
497 __skb_unlink(skb, &session->reorder_q); in l2tp_recv_dequeue()
502 spin_unlock_bh(&session->reorder_q.lock); in l2tp_recv_dequeue()
503 l2tp_recv_dequeue_skb(session, skb); in l2tp_recv_dequeue()
508 spin_unlock_bh(&session->reorder_q.lock); in l2tp_recv_dequeue()
511 static int l2tp_seq_check_rx_window(struct l2tp_session *session, u32 nr) in l2tp_seq_check_rx_window() argument
515 if (nr >= session->nr) in l2tp_seq_check_rx_window()
516 nws = nr - session->nr; in l2tp_seq_check_rx_window()
518 nws = (session->nr_max + 1) - (session->nr - nr); in l2tp_seq_check_rx_window()
520 return nws < session->nr_window_size; in l2tp_seq_check_rx_window()
526 static int l2tp_recv_data_seq(struct l2tp_session *session, struct sk_buff *skb) in l2tp_recv_data_seq() argument
530 if (!l2tp_seq_check_rx_window(session, cb->ns)) { in l2tp_recv_data_seq()
534 trace_session_pkt_outside_rx_window(session, cb->ns); in l2tp_recv_data_seq()
538 if (session->reorder_timeout != 0) { in l2tp_recv_data_seq()
542 l2tp_recv_queue_skb(session, skb); in l2tp_recv_data_seq()
551 if (cb->ns == session->nr) { in l2tp_recv_data_seq()
552 skb_queue_tail(&session->reorder_q, skb); in l2tp_recv_data_seq()
555 u32 nr_next = (session->nr_oos + 1) & session->nr_max; in l2tp_recv_data_seq()
558 session->nr_oos_count++; in l2tp_recv_data_seq()
560 session->nr_oos_count = 0; in l2tp_recv_data_seq()
562 session->nr_oos = nr_oos; in l2tp_recv_data_seq()
563 if (session->nr_oos_count > session->nr_oos_count_max) { in l2tp_recv_data_seq()
564 session->reorder_skip = 1; in l2tp_recv_data_seq()
566 if (!session->reorder_skip) { in l2tp_recv_data_seq()
567 atomic_long_inc(&session->stats.rx_seq_discards); in l2tp_recv_data_seq()
568 trace_session_pkt_oos(session, cb->ns); in l2tp_recv_data_seq()
571 skb_queue_tail(&session->reorder_q, skb); in l2tp_recv_data_seq()
640 void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, in l2tp_recv_common() argument
644 struct l2tp_tunnel *tunnel = session->tunnel; in l2tp_recv_common()
648 if (session->peer_cookie_len > 0) { in l2tp_recv_common()
649 if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) { in l2tp_recv_common()
652 session->session_id); in l2tp_recv_common()
653 atomic_long_inc(&session->stats.rx_cookie_discards); in l2tp_recv_common()
656 ptr += session->peer_cookie_len; in l2tp_recv_common()
677 } else if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { in l2tp_recv_common()
693 if (!session->lns_mode && !session->send_seq) { in l2tp_recv_common()
694 trace_session_seqnum_lns_enable(session); in l2tp_recv_common()
695 session->send_seq = 1; in l2tp_recv_common()
696 l2tp_session_set_header_len(session, tunnel->version); in l2tp_recv_common()
702 if (session->recv_seq) { in l2tp_recv_common()
704 session->name); in l2tp_recv_common()
705 atomic_long_inc(&session->stats.rx_seq_discards); in l2tp_recv_common()
714 if (!session->lns_mode && session->send_seq) { in l2tp_recv_common()
715 trace_session_seqnum_lns_disable(session); in l2tp_recv_common()
716 session->send_seq = 0; in l2tp_recv_common()
717 l2tp_session_set_header_len(session, tunnel->version); in l2tp_recv_common()
718 } else if (session->send_seq) { in l2tp_recv_common()
720 session->name); in l2tp_recv_common()
721 atomic_long_inc(&session->stats.rx_seq_discards); in l2tp_recv_common()
749 (session->reorder_timeout ? session->reorder_timeout : HZ); in l2tp_recv_common()
755 if (l2tp_recv_data_seq(session, skb)) in l2tp_recv_common()
762 skb_queue_tail(&session->reorder_q, skb); in l2tp_recv_common()
766 l2tp_recv_dequeue(session); in l2tp_recv_common()
771 atomic_long_inc(&session->stats.rx_errors); in l2tp_recv_common()
778 static void l2tp_session_queue_purge(struct l2tp_session *session) in l2tp_session_queue_purge() argument
782 while ((skb = skb_dequeue(&session->reorder_q))) { in l2tp_session_queue_purge()
783 atomic_long_inc(&session->stats.rx_errors); in l2tp_session_queue_purge()
796 struct l2tp_session *session = NULL; in l2tp_udp_recv_core() local
858 session = l2tp_tunnel_get_session(tunnel, session_id); in l2tp_udp_recv_core()
859 if (!session || !session->recv_skb) { in l2tp_udp_recv_core()
860 if (session) in l2tp_udp_recv_core()
861 l2tp_session_dec_refcount(session); in l2tp_udp_recv_core()
870 l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) { in l2tp_udp_recv_core()
871 l2tp_session_dec_refcount(session); in l2tp_udp_recv_core()
875 l2tp_recv_common(session, skb, ptr, optr, hdrflags, length); in l2tp_udp_recv_core()
876 l2tp_session_dec_refcount(session); in l2tp_udp_recv_core()
928 static int l2tp_build_l2tpv2_header(struct l2tp_session *session, void *buf) in l2tp_build_l2tpv2_header() argument
930 struct l2tp_tunnel *tunnel = session->tunnel; in l2tp_build_l2tpv2_header()
935 u32 session_id = session->peer_session_id; in l2tp_build_l2tpv2_header()
937 if (session->send_seq) in l2tp_build_l2tpv2_header()
944 if (session->send_seq) { in l2tp_build_l2tpv2_header()
945 *bufp++ = htons(session->ns); in l2tp_build_l2tpv2_header()
947 session->ns++; in l2tp_build_l2tpv2_header()
948 session->ns &= 0xffff; in l2tp_build_l2tpv2_header()
949 trace_session_seqnum_update(session); in l2tp_build_l2tpv2_header()
955 static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf) in l2tp_build_l2tpv3_header() argument
957 struct l2tp_tunnel *tunnel = session->tunnel; in l2tp_build_l2tpv3_header()
972 *((__be32 *)bufp) = htonl(session->peer_session_id); in l2tp_build_l2tpv3_header()
974 if (session->cookie_len) { in l2tp_build_l2tpv3_header()
975 memcpy(bufp, &session->cookie[0], session->cookie_len); in l2tp_build_l2tpv3_header()
976 bufp += session->cookie_len; in l2tp_build_l2tpv3_header()
978 if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { in l2tp_build_l2tpv3_header()
981 if (session->send_seq) { in l2tp_build_l2tpv3_header()
982 l2h = 0x40000000 | session->ns; in l2tp_build_l2tpv3_header()
983 session->ns++; in l2tp_build_l2tpv3_header()
984 session->ns &= 0xffffff; in l2tp_build_l2tpv3_header()
985 trace_session_seqnum_update(session); in l2tp_build_l2tpv3_header()
1012 static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, unsigned int *len) in l2tp_xmit_core() argument
1014 struct l2tp_tunnel *tunnel = session->tunnel; in l2tp_xmit_core()
1027 headroom = NET_SKB_PAD + sizeof(struct iphdr) + uhlen + session->hdr_len; in l2tp_xmit_core()
1035 l2tp_build_l2tpv2_header(session, __skb_push(skb, session->hdr_len)); in l2tp_xmit_core()
1037 l2tp_build_l2tpv3_header(session, __skb_push(skb, session->hdr_len)); in l2tp_xmit_core()
1074 udp_len = uhlen + session->hdr_len + data_len; in l2tp_xmit_core()
1104 int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb) in l2tp_xmit_skb() argument
1109 ret = l2tp_xmit_core(session, skb, &len); in l2tp_xmit_skb()
1111 atomic_long_inc(&session->tunnel->stats.tx_packets); in l2tp_xmit_skb()
1112 atomic_long_add(len, &session->tunnel->stats.tx_bytes); in l2tp_xmit_skb()
1113 atomic_long_inc(&session->stats.tx_packets); in l2tp_xmit_skb()
1114 atomic_long_add(len, &session->stats.tx_bytes); in l2tp_xmit_skb()
1116 atomic_long_inc(&session->tunnel->stats.tx_errors); in l2tp_xmit_skb()
1117 atomic_long_inc(&session->stats.tx_errors); in l2tp_xmit_skb()
1166 static void l2tp_session_unhash(struct l2tp_session *session) in l2tp_session_unhash() argument
1168 struct l2tp_tunnel *tunnel = session->tunnel; in l2tp_session_unhash()
1174 hlist_del_init_rcu(&session->hlist); in l2tp_session_unhash()
1182 hlist_del_init_rcu(&session->global_hlist); in l2tp_session_unhash()
1194 struct l2tp_session *session; in l2tp_tunnel_closeall() local
1201 hlist_for_each_entry_rcu(session, &tunnel->session_hlist[hash], hlist) { in l2tp_tunnel_closeall()
1202 hlist_del_init_rcu(&session->hlist); in l2tp_tunnel_closeall()
1205 l2tp_session_delete(session); in l2tp_tunnel_closeall()
1548 void l2tp_session_delete(struct l2tp_session *session) in l2tp_session_delete() argument
1550 if (test_and_set_bit(0, &session->dead)) in l2tp_session_delete()
1553 trace_delete_session(session); in l2tp_session_delete()
1554 l2tp_session_unhash(session); in l2tp_session_delete()
1555 l2tp_session_queue_purge(session); in l2tp_session_delete()
1556 if (session->session_close) in l2tp_session_delete()
1557 (*session->session_close)(session); in l2tp_session_delete()
1559 l2tp_session_dec_refcount(session); in l2tp_session_delete()
1566 void l2tp_session_set_header_len(struct l2tp_session *session, int version) in l2tp_session_set_header_len() argument
1569 session->hdr_len = 6; in l2tp_session_set_header_len()
1570 if (session->send_seq) in l2tp_session_set_header_len()
1571 session->hdr_len += 4; in l2tp_session_set_header_len()
1573 session->hdr_len = 4 + session->cookie_len; in l2tp_session_set_header_len()
1574 session->hdr_len += l2tp_get_l2specific_len(session); in l2tp_session_set_header_len()
1575 if (session->tunnel->encap == L2TP_ENCAPTYPE_UDP) in l2tp_session_set_header_len()
1576 session->hdr_len += 4; in l2tp_session_set_header_len()
1584 struct l2tp_session *session; in l2tp_session_create() local
1586 session = kzalloc(sizeof(*session) + priv_size, GFP_KERNEL); in l2tp_session_create()
1587 if (session) { in l2tp_session_create()
1588 session->magic = L2TP_SESSION_MAGIC; in l2tp_session_create()
1589 session->tunnel = tunnel; in l2tp_session_create()
1591 session->session_id = session_id; in l2tp_session_create()
1592 session->peer_session_id = peer_session_id; in l2tp_session_create()
1593 session->nr = 0; in l2tp_session_create()
1595 session->nr_max = 0xffff; in l2tp_session_create()
1597 session->nr_max = 0xffffff; in l2tp_session_create()
1598 session->nr_window_size = session->nr_max / 2; in l2tp_session_create()
1599 session->nr_oos_count_max = 4; in l2tp_session_create()
1602 session->reorder_skip = 1; in l2tp_session_create()
1604 sprintf(&session->name[0], "sess %u/%u", in l2tp_session_create()
1605 tunnel->tunnel_id, session->session_id); in l2tp_session_create()
1607 skb_queue_head_init(&session->reorder_q); in l2tp_session_create()
1609 INIT_HLIST_NODE(&session->hlist); in l2tp_session_create()
1610 INIT_HLIST_NODE(&session->global_hlist); in l2tp_session_create()
1613 session->pwtype = cfg->pw_type; in l2tp_session_create()
1614 session->send_seq = cfg->send_seq; in l2tp_session_create()
1615 session->recv_seq = cfg->recv_seq; in l2tp_session_create()
1616 session->lns_mode = cfg->lns_mode; in l2tp_session_create()
1617 session->reorder_timeout = cfg->reorder_timeout; in l2tp_session_create()
1618 session->l2specific_type = cfg->l2specific_type; in l2tp_session_create()
1619 session->cookie_len = cfg->cookie_len; in l2tp_session_create()
1620 memcpy(&session->cookie[0], &cfg->cookie[0], cfg->cookie_len); in l2tp_session_create()
1621 session->peer_cookie_len = cfg->peer_cookie_len; in l2tp_session_create()
1622 memcpy(&session->peer_cookie[0], &cfg->peer_cookie[0], cfg->peer_cookie_len); in l2tp_session_create()
1625 l2tp_session_set_header_len(session, tunnel->version); in l2tp_session_create()
1627 refcount_set(&session->ref_count, 1); in l2tp_session_create()
1629 return session; in l2tp_session_create()