Lines Matching refs:pctx

119 static void pdp_context_delete(struct pdp_ctx *pctx);
229 static bool gtp_check_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx, in gtp_check_ms_ipv4() argument
240 return iph->daddr == pctx->ms.addr.s_addr; in gtp_check_ms_ipv4()
242 return iph->saddr == pctx->ms.addr.s_addr; in gtp_check_ms_ipv4()
245 static bool gtp_check_ms_ipv6(struct sk_buff *skb, struct pdp_ctx *pctx, in gtp_check_ms_ipv6() argument
261 ret = ipv6_pdp_addr_equal(&ip6h->daddr, &pctx->ms.addr6); in gtp_check_ms_ipv6()
263 ret = ipv6_pdp_addr_equal(&ip6h->saddr, &pctx->ms.addr6); in gtp_check_ms_ipv6()
272 static bool gtp_check_ms(struct sk_buff *skb, struct pdp_ctx *pctx, in gtp_check_ms() argument
278 return gtp_check_ms_ipv4(skb, pctx, hdrlen, role); in gtp_check_ms()
280 return gtp_check_ms_ipv6(skb, pctx, hdrlen, role); in gtp_check_ms()
309 static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb, in gtp_rx() argument
312 if (!gtp_check_ms(skb, pctx, hdrlen, role, inner_proto)) { in gtp_rx()
313 netdev_dbg(pctx->dev, "No PDP ctx for this MS\n"); in gtp_rx()
319 !net_eq(sock_net(pctx->sk), dev_net(pctx->dev)))) { in gtp_rx()
320 pctx->dev->stats.rx_length_errors++; in gtp_rx()
324 netdev_dbg(pctx->dev, "forwarding packet from GGSN to uplink\n"); in gtp_rx()
333 skb->dev = pctx->dev; in gtp_rx()
335 dev_sw_netstats_rx_add(pctx->dev, skb->len); in gtp_rx()
341 pctx->dev->stats.rx_dropped++; in gtp_rx()
581 struct pdp_ctx *pctx; in gtp0_udp_encap_recv() local
610 pctx = gtp0_pdp_find(gtp, be64_to_cpu(gtp0->tid), in gtp0_udp_encap_recv()
612 if (!pctx) { in gtp0_udp_encap_recv()
617 return gtp_rx(pctx, skb, hdrlen, gtp->role, inner_proto); in gtp0_udp_encap_recv()
787 struct pdp_ctx *pctx; in gtp1u_udp_encap_recv() local
831 pctx = gtp1_pdp_find(gtp, ntohl(gtp1->tid), in gtp1u_udp_encap_recv()
833 if (!pctx) { in gtp1u_udp_encap_recv()
842 return gtp_rx(pctx, skb, hdrlen, gtp->role, inner_proto); in gtp1u_udp_encap_recv()
944 static inline void gtp0_push_header(struct sk_buff *skb, struct pdp_ctx *pctx) in gtp0_push_header() argument
954 gtp0->seq = htons((atomic_inc_return(&pctx->tx_seq) - 1) % 0xffff); in gtp0_push_header()
955 gtp0->flow = htons(pctx->u.v0.flow); in gtp0_push_header()
958 gtp0->tid = cpu_to_be64(pctx->u.v0.tid); in gtp0_push_header()
961 static inline void gtp1_push_header(struct sk_buff *skb, struct pdp_ctx *pctx) in gtp1_push_header() argument
977 gtp1->tid = htonl(pctx->u.v1.o_tei); in gtp1_push_header()
994 struct pdp_ctx *pctx; member
1002 switch (pktinfo->pctx->gtp_version) { in gtp_push_header()
1005 gtp0_push_header(skb, pktinfo->pctx); in gtp_push_header()
1009 gtp1_push_header(skb, pktinfo->pctx); in gtp_push_header()
1016 struct pdp_ctx *pctx, struct rtable *rt, in gtp_set_pktinfo_ipv4() argument
1022 pktinfo->pctx = pctx; in gtp_set_pktinfo_ipv4()
1030 struct pdp_ctx *pctx, struct rt6_info *rt6, in gtp_set_pktinfo_ipv6() argument
1036 pktinfo->pctx = pctx; in gtp_set_pktinfo_ipv6()
1044 struct pdp_ctx *pctx, __u8 tos, in gtp_build_skb_outer_ip4() argument
1052 rt = ip4_route_output_gtp(&fl4, pctx->sk, pctx->peer.addr.s_addr, in gtp_build_skb_outer_ip4()
1053 inet_sk(pctx->sk)->inet_saddr); in gtp_build_skb_outer_ip4()
1056 &pctx->peer.addr.s_addr); in gtp_build_skb_outer_ip4()
1063 &pctx->peer.addr.s_addr); in gtp_build_skb_outer_ip4()
1073 switch (pctx->gtp_version) { in gtp_build_skb_outer_ip4()
1096 gtp_set_pktinfo_ipv4(pktinfo, pctx->sk, tos, pctx, rt, &fl4, dev); in gtp_build_skb_outer_ip4()
1109 struct pdp_ctx *pctx, __u8 tos) in gtp_build_skb_outer_ip6() argument
1116 rt = ip6_route_output_gtp(net, &fl6, pctx->sk, &pctx->peer.addr6, in gtp_build_skb_outer_ip6()
1117 &inet6_sk(pctx->sk)->saddr); in gtp_build_skb_outer_ip6()
1120 &pctx->peer.addr6); in gtp_build_skb_outer_ip6()
1128 &pctx->peer.addr6); in gtp_build_skb_outer_ip6()
1135 switch (pctx->gtp_version) { in gtp_build_skb_outer_ip6()
1153 gtp_set_pktinfo_ipv6(pktinfo, pctx->sk, tos, pctx, rt, &fl6, dev); in gtp_build_skb_outer_ip6()
1168 struct pdp_ctx *pctx; in gtp_build_skb_ip4() local
1177 pctx = ipv4_pdp_find(gtp, iph->saddr); in gtp_build_skb_ip4()
1179 pctx = ipv4_pdp_find(gtp, iph->daddr); in gtp_build_skb_ip4()
1181 if (!pctx) { in gtp_build_skb_ip4()
1186 netdev_dbg(dev, "found PDP context %p\n", pctx); in gtp_build_skb_ip4()
1188 switch (pctx->sk->sk_family) { in gtp_build_skb_ip4()
1190 ret = gtp_build_skb_outer_ip4(skb, dev, pktinfo, pctx, in gtp_build_skb_ip4()
1194 ret = gtp_build_skb_outer_ip6(net, skb, dev, pktinfo, pctx, in gtp_build_skb_ip4()
1217 struct pdp_ctx *pctx; in gtp_build_skb_ip6() local
1227 pctx = ipv6_pdp_find(gtp, &ip6h->saddr); in gtp_build_skb_ip6()
1229 pctx = ipv6_pdp_find(gtp, &ip6h->daddr); in gtp_build_skb_ip6()
1231 if (!pctx) { in gtp_build_skb_ip6()
1236 netdev_dbg(dev, "found PDP context %p\n", pctx); in gtp_build_skb_ip6()
1240 switch (pctx->sk->sk_family) { in gtp_build_skb_ip6()
1242 ret = gtp_build_skb_outer_ip4(skb, dev, pktinfo, pctx, tos, 0); in gtp_build_skb_ip6()
1245 ret = gtp_build_skb_outer_ip6(net, skb, dev, pktinfo, pctx, tos); in gtp_build_skb_ip6()
1295 switch (pktinfo.pctx->sk->sk_family) { in gtp_dev_xmit()
1303 !net_eq(sock_net(pktinfo.pctx->sk), in gtp_dev_xmit()
1549 struct pdp_ctx *pctx; in gtp_dellink() local
1553 hlist_for_each_entry_safe(pctx, next, &gtp->tid_hash[i], hlist_tid) in gtp_dellink()
1554 pdp_context_delete(pctx); in gtp_dellink()
1765 static void gtp_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info) in gtp_pdp_fill() argument
1767 pctx->gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]); in gtp_pdp_fill()
1769 switch (pctx->gtp_version) { in gtp_pdp_fill()
1775 pctx->u.v0.tid = nla_get_u64(info->attrs[GTPA_TID]); in gtp_pdp_fill()
1776 pctx->u.v0.flow = nla_get_u16(info->attrs[GTPA_FLOW]); in gtp_pdp_fill()
1779 pctx->u.v1.i_tei = nla_get_u32(info->attrs[GTPA_I_TEI]); in gtp_pdp_fill()
1780 pctx->u.v1.o_tei = nla_get_u32(info->attrs[GTPA_O_TEI]); in gtp_pdp_fill()
1787 static void ip_pdp_peer_fill(struct pdp_ctx *pctx, struct genl_info *info) in ip_pdp_peer_fill() argument
1790 pctx->peer.addr.s_addr = in ip_pdp_peer_fill()
1793 pctx->peer.addr6 = nla_get_in6_addr(info->attrs[GTPA_PEER_ADDR6]); in ip_pdp_peer_fill()
1797 static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info) in ipv4_pdp_fill() argument
1799 ip_pdp_peer_fill(pctx, info); in ipv4_pdp_fill()
1800 pctx->ms.addr.s_addr = in ipv4_pdp_fill()
1802 gtp_pdp_fill(pctx, info); in ipv4_pdp_fill()
1805 static bool ipv6_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info) in ipv6_pdp_fill() argument
1807 ip_pdp_peer_fill(pctx, info); in ipv6_pdp_fill()
1808 pctx->ms.addr6 = nla_get_in6_addr(info->attrs[GTPA_MS_ADDR6]); in ipv6_pdp_fill()
1809 if (pctx->ms.addr6.s6_addr32[2] || in ipv6_pdp_fill()
1810 pctx->ms.addr6.s6_addr32[3]) in ipv6_pdp_fill()
1813 gtp_pdp_fill(pctx, info); in ipv6_pdp_fill()
1821 struct pdp_ctx *pctx, *pctx_tid = NULL; in gtp_pdp_add() local
1859 pctx = ipv4_pdp_find(gtp, ms_addr); in gtp_pdp_add()
1868 pctx = ipv6_pdp_find(gtp, &ms_addr6); in gtp_pdp_add()
1873 if (pctx) in gtp_pdp_add()
1892 if (pctx && pctx_tid) in gtp_pdp_add()
1894 if (!pctx) in gtp_pdp_add()
1895 pctx = pctx_tid; in gtp_pdp_add()
1897 switch (pctx->af) { in gtp_pdp_add()
1899 ipv4_pdp_fill(pctx, info); in gtp_pdp_add()
1902 if (!ipv6_pdp_fill(pctx, info)) in gtp_pdp_add()
1907 if (pctx->gtp_version == GTP_V0) in gtp_pdp_add()
1909 pctx->u.v0.tid, pctx); in gtp_pdp_add()
1910 else if (pctx->gtp_version == GTP_V1) in gtp_pdp_add()
1912 pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx); in gtp_pdp_add()
1914 return pctx; in gtp_pdp_add()
1918 pctx = kmalloc(sizeof(*pctx), GFP_ATOMIC); in gtp_pdp_add()
1919 if (pctx == NULL) in gtp_pdp_add()
1923 pctx->sk = sk; in gtp_pdp_add()
1924 pctx->dev = gtp->dev; in gtp_pdp_add()
1925 pctx->af = family; in gtp_pdp_add()
1927 switch (pctx->af) { in gtp_pdp_add()
1931 kfree(pctx); in gtp_pdp_add()
1935 ipv4_pdp_fill(pctx, info); in gtp_pdp_add()
1940 kfree(pctx); in gtp_pdp_add()
1944 if (!ipv6_pdp_fill(pctx, info)) { in gtp_pdp_add()
1946 kfree(pctx); in gtp_pdp_add()
1951 atomic_set(&pctx->tx_seq, 0); in gtp_pdp_add()
1953 switch (pctx->gtp_version) { in gtp_pdp_add()
1960 hash_tid = gtp0_hashfn(pctx->u.v0.tid) % gtp->hash_size; in gtp_pdp_add()
1963 hash_tid = gtp1u_hashfn(pctx->u.v1.i_tei) % gtp->hash_size; in gtp_pdp_add()
1967 hlist_add_head_rcu(&pctx->hlist_addr, &gtp->addr_hash[hash_ms]); in gtp_pdp_add()
1968 hlist_add_head_rcu(&pctx->hlist_tid, &gtp->tid_hash[hash_tid]); in gtp_pdp_add()
1970 switch (pctx->gtp_version) { in gtp_pdp_add()
1973 pctx->u.v0.tid, &pctx->peer.addr, in gtp_pdp_add()
1974 &pctx->ms.addr, pctx); in gtp_pdp_add()
1978 pctx->u.v1.i_tei, pctx->u.v1.o_tei, in gtp_pdp_add()
1979 &pctx->peer.addr, &pctx->ms.addr, pctx); in gtp_pdp_add()
1983 return pctx; in gtp_pdp_add()
1988 struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head); in pdp_context_free() local
1990 sock_put(pctx->sk); in pdp_context_free()
1991 kfree(pctx); in pdp_context_free()
1994 static void pdp_context_delete(struct pdp_ctx *pctx) in pdp_context_delete() argument
1996 hlist_del_rcu(&pctx->hlist_tid); in pdp_context_delete()
1997 hlist_del_rcu(&pctx->hlist_addr); in pdp_context_delete()
1998 call_rcu(&pctx->rcu_head, pdp_context_free); in pdp_context_delete()
2001 static int gtp_tunnel_notify(struct pdp_ctx *pctx, u8 cmd, gfp_t allocation);
2006 struct pdp_ctx *pctx; in gtp_genl_new_pdp() local
2053 pctx = gtp_pdp_add(gtp, sk, info); in gtp_genl_new_pdp()
2054 if (IS_ERR(pctx)) { in gtp_genl_new_pdp()
2055 err = PTR_ERR(pctx); in gtp_genl_new_pdp()
2057 gtp_tunnel_notify(pctx, GTP_CMD_NEWPDP, GFP_KERNEL); in gtp_genl_new_pdp()
2116 struct pdp_ctx *pctx; in gtp_find_pdp() local
2119 pctx = gtp_find_pdp_by_link(net, nla); in gtp_find_pdp()
2121 pctx = ERR_PTR(-EINVAL); in gtp_find_pdp()
2123 if (!pctx) in gtp_find_pdp()
2124 pctx = ERR_PTR(-ENOENT); in gtp_find_pdp()
2126 return pctx; in gtp_find_pdp()
2131 struct pdp_ctx *pctx; in gtp_genl_del_pdp() local
2139 pctx = gtp_find_pdp(sock_net(skb->sk), info->attrs); in gtp_genl_del_pdp()
2140 if (IS_ERR(pctx)) { in gtp_genl_del_pdp()
2141 err = PTR_ERR(pctx); in gtp_genl_del_pdp()
2145 if (pctx->gtp_version == GTP_V0) in gtp_genl_del_pdp()
2146 netdev_dbg(pctx->dev, "GTPv0-U: deleting tunnel id = %llx (pdp %p)\n", in gtp_genl_del_pdp()
2147 pctx->u.v0.tid, pctx); in gtp_genl_del_pdp()
2148 else if (pctx->gtp_version == GTP_V1) in gtp_genl_del_pdp()
2149 netdev_dbg(pctx->dev, "GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n", in gtp_genl_del_pdp()
2150 pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx); in gtp_genl_del_pdp()
2152 gtp_tunnel_notify(pctx, GTP_CMD_DELPDP, GFP_ATOMIC); in gtp_genl_del_pdp()
2153 pdp_context_delete(pctx); in gtp_genl_del_pdp()
2161 int flags, u32 type, struct pdp_ctx *pctx) in gtp_genl_fill_info() argument
2170 if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version) || in gtp_genl_fill_info()
2171 nla_put_u32(skb, GTPA_LINK, pctx->dev->ifindex) || in gtp_genl_fill_info()
2172 nla_put_u8(skb, GTPA_FAMILY, pctx->af)) in gtp_genl_fill_info()
2175 switch (pctx->af) { in gtp_genl_fill_info()
2177 if (nla_put_be32(skb, GTPA_MS_ADDRESS, pctx->ms.addr.s_addr)) in gtp_genl_fill_info()
2181 if (nla_put_in6_addr(skb, GTPA_MS_ADDR6, &pctx->ms.addr6)) in gtp_genl_fill_info()
2186 switch (pctx->sk->sk_family) { in gtp_genl_fill_info()
2188 if (nla_put_be32(skb, GTPA_PEER_ADDRESS, pctx->peer.addr.s_addr)) in gtp_genl_fill_info()
2192 if (nla_put_in6_addr(skb, GTPA_PEER_ADDR6, &pctx->peer.addr6)) in gtp_genl_fill_info()
2197 switch (pctx->gtp_version) { in gtp_genl_fill_info()
2199 if (nla_put_u64_64bit(skb, GTPA_TID, pctx->u.v0.tid, GTPA_PAD) || in gtp_genl_fill_info()
2200 nla_put_u16(skb, GTPA_FLOW, pctx->u.v0.flow)) in gtp_genl_fill_info()
2204 if (nla_put_u32(skb, GTPA_I_TEI, pctx->u.v1.i_tei) || in gtp_genl_fill_info()
2205 nla_put_u32(skb, GTPA_O_TEI, pctx->u.v1.o_tei)) in gtp_genl_fill_info()
2218 static int gtp_tunnel_notify(struct pdp_ctx *pctx, u8 cmd, gfp_t allocation) in gtp_tunnel_notify() argument
2227 ret = gtp_genl_fill_info(msg, 0, 0, 0, cmd, pctx); in gtp_tunnel_notify()
2233 ret = genlmsg_multicast_netns(&gtp_genl_family, dev_net(pctx->dev), msg, in gtp_tunnel_notify()
2240 struct pdp_ctx *pctx = NULL; in gtp_genl_get_pdp() local
2249 pctx = gtp_find_pdp(sock_net(skb->sk), info->attrs); in gtp_genl_get_pdp()
2250 if (IS_ERR(pctx)) { in gtp_genl_get_pdp()
2251 err = PTR_ERR(pctx); in gtp_genl_get_pdp()
2262 0, info->nlhdr->nlmsg_type, pctx); in gtp_genl_get_pdp()
2282 struct pdp_ctx *pctx; in gtp_genl_dump_pdp() local
2299 hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], in gtp_genl_dump_pdp()
2306 cb->nlh->nlmsg_type, pctx)) { in gtp_genl_dump_pdp()