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 = >p->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 = >p->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);
|