Project

General

Profile

Bug #1952 » 0001-gtp-identify-tunnel-via-GTP-version-TEID-family.patch

pablo, 01/30/2024 12:18 PM

View differences:

drivers/net/gtp.c
140 140
}
141 141

  
142 142
/* Resolve a PDP context structure based on the 64bit TID. */
143
static struct pdp_ctx *gtp0_pdp_find(struct gtp_dev *gtp, u64 tid)
143
static struct pdp_ctx *gtp0_pdp_find(struct gtp_dev *gtp, u64 tid, u16 family)
144 144
{
145 145
	struct hlist_head *head;
146 146
	struct pdp_ctx *pdp;
......
148 148
	head = &gtp->tid_hash[gtp0_hashfn(tid) % gtp->hash_size];
149 149

  
150 150
	hlist_for_each_entry_rcu(pdp, head, hlist_tid) {
151
		if (pdp->gtp_version == GTP_V0 &&
151
		if (pdp->af == family &&
152
		    pdp->gtp_version == GTP_V0 &&
152 153
		    pdp->u.v0.tid == tid)
153 154
			return pdp;
154 155
	}
......
156 157
}
157 158

  
158 159
/* Resolve a PDP context structure based on the 32bit TEI. */
159
static struct pdp_ctx *gtp1_pdp_find(struct gtp_dev *gtp, u32 tid)
160
static struct pdp_ctx *gtp1_pdp_find(struct gtp_dev *gtp, u32 tid, u16 family)
160 161
{
161 162
	struct hlist_head *head;
162 163
	struct pdp_ctx *pdp;
......
164 165
	head = &gtp->tid_hash[gtp1u_hashfn(tid) % gtp->hash_size];
165 166

  
166 167
	hlist_for_each_entry_rcu(pdp, head, hlist_tid) {
167
		if (pdp->gtp_version == GTP_V1 &&
168
		if (pdp->af == family &&
169
		    pdp->gtp_version == GTP_V1 &&
168 170
		    pdp->u.v1.i_tei == tid)
169 171
			return pdp;
170 172
	}
......
304 306
}
305 307

  
306 308
static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb,
307
		  unsigned int hdrlen, unsigned int role)
309
		  unsigned int hdrlen, unsigned int role, __u16 inner_proto)
308 310
{
309
	__u16 inner_proto;
310

  
311
	if (gtp_inner_proto(skb, hdrlen, &inner_proto) < 0) {
312
		netdev_dbg(pctx->dev, "GTP packet does not encapsulate an IP packet\n");
313
		return -1;
314
	}
315

  
316 311
	if (!gtp_check_ms(skb, pctx, hdrlen, role, inner_proto)) {
317 312
		netdev_dbg(pctx->dev, "No PDP ctx for this MS\n");
318 313
		return 1;
......
561 556
				       msg, 0, GTP_GENL_MCGRP, GFP_ATOMIC);
562 557
}
563 558

  
559
static int gtp_proto_to_family(__u16 proto)
560
{
561
	switch (proto) {
562
	case ETH_P_IP:
563
		return AF_INET;
564
	case ETH_P_IPV6:
565
		return AF_INET6;
566
	default:
567
		WARN_ON_ONCE(1);
568
		break;
569
	}
570

  
571
	return AF_UNSPEC;
572
}
573

  
564 574
/* 1 means pass up to the stack, -1 means drop and 0 means decapsulated. */
565 575
static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
566 576
{
......
568 578
			      sizeof(struct gtp0_header);
569 579
	struct gtp0_header *gtp0;
570 580
	struct pdp_ctx *pctx;
581
	__u16 inner_proto;
571 582

  
572 583
	if (!pskb_may_pull(skb, hdrlen))
573 584
		return -1;
......
590 601
	if (gtp0->type != GTP_TPDU)
591 602
		return 1;
592 603

  
593
	pctx = gtp0_pdp_find(gtp, be64_to_cpu(gtp0->tid));
604
	if (gtp_inner_proto(skb, hdrlen, &inner_proto) < 0) {
605
		netdev_dbg(pctx->dev, "GTP packet does not encapsulate an IP packet\n");
606
		return -1;
607
	}
608

  
609
	pctx = gtp0_pdp_find(gtp, be64_to_cpu(gtp0->tid),
610
			     gtp_proto_to_family(inner_proto));
594 611
	if (!pctx) {
595 612
		netdev_dbg(gtp->dev, "No PDP ctx to decap skb=%p\n", skb);
596 613
		return 1;
597 614
	}
598 615

  
599
	return gtp_rx(pctx, skb, hdrlen, gtp->role);
616
	return gtp_rx(pctx, skb, hdrlen, gtp->role, inner_proto);
600 617
}
601 618

  
602 619
/* msg_type has to be GTP_ECHO_REQ or GTP_ECHO_RSP */
......
767 784
			      sizeof(struct gtp1_header);
768 785
	struct gtp1_header *gtp1;
769 786
	struct pdp_ctx *pctx;
787
	__u16 inner_proto;
770 788

  
771 789
	if (!pskb_may_pull(skb, hdrlen))
772 790
		return -1;
......
802 820
	if (!pskb_may_pull(skb, hdrlen))
803 821
		return -1;
804 822

  
823
	if (gtp_inner_proto(skb, hdrlen, &inner_proto) < 0) {
824
		netdev_dbg(pctx->dev, "GTP packet does not encapsulate an IP packet\n");
825
		return -1;
826
	}
827

  
805 828
	gtp1 = (struct gtp1_header *)(skb->data + sizeof(struct udphdr));
806 829

  
807
	pctx = gtp1_pdp_find(gtp, ntohl(gtp1->tid));
830
	pctx = gtp1_pdp_find(gtp, ntohl(gtp1->tid),
831
			     gtp_proto_to_family(inner_proto));
808 832
	if (!pctx) {
809 833
		netdev_dbg(gtp->dev, "No PDP ctx to decap skb=%p\n", skb);
810 834
		return 1;
......
814 838
	    gtp_parse_exthdrs(skb, &hdrlen) < 0)
815 839
		return -1;
816 840

  
817
	return gtp_rx(pctx, skb, hdrlen, gtp->role);
841
	return gtp_rx(pctx, skb, hdrlen, gtp->role, inner_proto);
818 842
}
819 843

  
820 844
static void __gtp_encap_destroy(struct sock *sk)
......
1832 1856
		found = true;
1833 1857
	if (version == GTP_V0)
1834 1858
		pctx_tid = gtp0_pdp_find(gtp,
1835
					 nla_get_u64(info->attrs[GTPA_TID]));
1859
					 nla_get_u64(info->attrs[GTPA_TID]),
1860
					 family);
1836 1861
	else if (version == GTP_V1)
1837 1862
		pctx_tid = gtp1_pdp_find(gtp,
1838
					 nla_get_u32(info->attrs[GTPA_I_TEI]));
1863
					 nla_get_u32(info->attrs[GTPA_I_TEI]),
1864
					 family);
1839 1865
	if (pctx_tid)
1840 1866
		found = true;
1841 1867

  
......
2014 2040
					    struct nlattr *nla[])
2015 2041
{
2016 2042
	struct gtp_dev *gtp;
2043
	int family;
2044

  
2045
	if (nla[GTPA_FAMILY])
2046
		family = nla_get_u8(nla[GTPA_FAMILY]);
2047
	else
2048
		family = AF_INET;
2017 2049

  
2018 2050
	gtp = gtp_find_dev(net, nla);
2019 2051
	if (!gtp)
......
2022 2054
	if (nla[GTPA_MS_ADDRESS]) {
2023 2055
		__be32 ip = nla_get_be32(nla[GTPA_MS_ADDRESS]);
2024 2056

  
2057
		if (family != AF_INET)
2058
			return ERR_PTR(-EINVAL);
2059

  
2025 2060
		return ipv4_pdp_find(gtp, ip);
2026 2061
	} else if (nla[GTPA_MS_ADDR6]) {
2027 2062
		struct in6_addr addr = nla_get_in6_addr(nla[GTPA_MS_ADDR6]);
2028 2063

  
2064
		if (family != AF_INET6)
2065
			return ERR_PTR(-EINVAL);
2066

  
2029 2067
		return ipv6_pdp_find(gtp, &addr);
2030 2068
	} else if (nla[GTPA_VERSION]) {
2031 2069
		u32 gtp_version = nla_get_u32(nla[GTPA_VERSION]);
2032 2070

  
2033
		if (gtp_version == GTP_V0 && nla[GTPA_TID])
2034
			return gtp0_pdp_find(gtp, nla_get_u64(nla[GTPA_TID]));
2035
		else if (gtp_version == GTP_V1 && nla[GTPA_I_TEI])
2036
			return gtp1_pdp_find(gtp, nla_get_u32(nla[GTPA_I_TEI]));
2071
		if (gtp_version == GTP_V0 && nla[GTPA_TID]) {
2072
			return gtp0_pdp_find(gtp, nla_get_u64(nla[GTPA_TID]),
2073
					     family);
2074
		} else if (gtp_version == GTP_V1 && nla[GTPA_I_TEI]) {
2075
			return gtp1_pdp_find(gtp, nla_get_u32(nla[GTPA_I_TEI]),
2076
					     family);
2077
		}
2037 2078
	}
2038 2079

  
2039 2080
	return ERR_PTR(-EINVAL);
(15-15/33)
Add picture from clipboard (Maximum size: 48.8 MB)