--- zzzz-none-000/linux-3.18.24/net/l2tp/l2tp_core.c 2015-10-31 20:39:51.000000000 +0000 +++ rtl96-5690pro-762/linux-3.18.24/net/l2tp/l2tp_core.c 2024-08-14 08:36:37.000000000 +0000 @@ -940,6 +940,42 @@ return 1; } +static u32 l2tp_get_tunnelID(struct sk_buff *skb) +{ + unsigned char *ptr; + u16 hdrflags; + u32 tunnel_id; + u16 version; + + /* ptr point to udp header */ + ptr = skb->data; + + /* Point to L2TP header */ + ptr += sizeof(struct udphdr); + + /* Get L2TP header flags */ + hdrflags = ntohs(*(__be16 *) ptr); + + /* Check protocol version */ + version = hdrflags & L2TP_HDR_VER_MASK; + + /* Skip flags */ + ptr += 2; + + if (version == L2TP_HDR_VER_2) { + /* If length is present, skip it */ + if (hdrflags & L2TP_HDRFLAG_L) + ptr += 2; + + /* Extract tunnel and session ID */ + tunnel_id = ntohs(*(__be16 *) ptr); + } + else + return 0; + + return tunnel_id; +} + /* UDP encapsulation receive handler. See net/ipv4/udp.c. * Return codes: * 0 : success. @@ -949,8 +985,19 @@ int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) { struct l2tp_tunnel *tunnel; + u32 tunnel_id=0; - tunnel = l2tp_sock_to_tunnel(sk); + /* QL 20161128 if more than one tunnel is created, only the first udp socket for l2tp control connection + * will be accessed(as all socket may has the same sip/dip/sport/dport), so all tunnel will access one + * tunnel for futher process, this is a big disaster. + * I think we should get tunnel by tunnel ID here to avoid this issue. + */ + //tunnel = l2tp_sock_to_tunnel(sk); + tunnel_id = l2tp_get_tunnelID(skb); + if (tunnel_id) + tunnel = l2tp_tunnel_find(sock_net(sk), tunnel_id); + else + tunnel = l2tp_sock_to_tunnel(sk); if (tunnel == NULL) goto pass_up; @@ -960,11 +1007,13 @@ if (l2tp_udp_recv_core(tunnel, skb, tunnel->recv_payload_hook)) goto pass_up_put; - sock_put(sk); + if (!tunnel_id) + sock_put(sk); return 0; pass_up_put: - sock_put(sk); + if (!tunnel_id) + sock_put(sk); pass_up: return 1; }