Lines Matching refs:pctx

106 static void pdp_context_delete(struct pdp_ctx *pctx);
173 static bool gtp_check_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx, in gtp_check_ms_ipv4() argument
184 return iph->daddr == pctx->ms_addr_ip4.s_addr; in gtp_check_ms_ipv4()
186 return iph->saddr == pctx->ms_addr_ip4.s_addr; in gtp_check_ms_ipv4()
192 static bool gtp_check_ms(struct sk_buff *skb, struct pdp_ctx *pctx, in gtp_check_ms() argument
197 return gtp_check_ms_ipv4(skb, pctx, hdrlen, role); in gtp_check_ms()
202 static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb, in gtp_rx() argument
205 if (!gtp_check_ms(skb, pctx, hdrlen, role)) { in gtp_rx()
206 netdev_dbg(pctx->dev, "No PDP ctx for this MS\n"); in gtp_rx()
212 !net_eq(sock_net(pctx->sk), dev_net(pctx->dev)))) { in gtp_rx()
213 pctx->dev->stats.rx_length_errors++; in gtp_rx()
217 netdev_dbg(pctx->dev, "forwarding packet from GGSN to uplink\n"); in gtp_rx()
226 skb->dev = pctx->dev; in gtp_rx()
228 dev_sw_netstats_rx_add(pctx->dev, skb->len); in gtp_rx()
234 pctx->dev->stats.rx_dropped++; in gtp_rx()
412 struct pdp_ctx *pctx; in gtp0_udp_encap_recv() local
435 pctx = gtp0_pdp_find(gtp, be64_to_cpu(gtp0->tid)); in gtp0_udp_encap_recv()
436 if (!pctx) { in gtp0_udp_encap_recv()
441 return gtp_rx(pctx, skb, hdrlen, gtp->role); in gtp0_udp_encap_recv()
574 struct pdp_ctx *pctx; in gtp1u_udp_encap_recv() local
612 pctx = gtp1_pdp_find(gtp, ntohl(gtp1->tid)); in gtp1u_udp_encap_recv()
613 if (!pctx) { in gtp1u_udp_encap_recv()
618 return gtp_rx(pctx, skb, hdrlen, gtp->role); in gtp1u_udp_encap_recv()
732 static inline void gtp0_push_header(struct sk_buff *skb, struct pdp_ctx *pctx) in gtp0_push_header() argument
742 gtp0->seq = htons((atomic_inc_return(&pctx->tx_seq) - 1) % 0xffff); in gtp0_push_header()
743 gtp0->flow = htons(pctx->u.v0.flow); in gtp0_push_header()
746 gtp0->tid = cpu_to_be64(pctx->u.v0.tid); in gtp0_push_header()
749 static inline void gtp1_push_header(struct sk_buff *skb, struct pdp_ctx *pctx) in gtp1_push_header() argument
765 gtp1->tid = htonl(pctx->u.v1.o_tei); in gtp1_push_header()
777 struct pdp_ctx *pctx; member
784 switch (pktinfo->pctx->gtp_version) { in gtp_push_header()
787 gtp0_push_header(skb, pktinfo->pctx); in gtp_push_header()
791 gtp1_push_header(skb, pktinfo->pctx); in gtp_push_header()
798 struct pdp_ctx *pctx, struct rtable *rt, in gtp_set_pktinfo_ipv4() argument
804 pktinfo->pctx = pctx; in gtp_set_pktinfo_ipv4()
814 struct pdp_ctx *pctx; in gtp_build_skb_ip4() local
826 pctx = ipv4_pdp_find(gtp, iph->saddr); in gtp_build_skb_ip4()
828 pctx = ipv4_pdp_find(gtp, iph->daddr); in gtp_build_skb_ip4()
830 if (!pctx) { in gtp_build_skb_ip4()
835 netdev_dbg(dev, "found PDP context %p\n", pctx); in gtp_build_skb_ip4()
837 rt = ip4_route_output_gtp(&fl4, pctx->sk, pctx->peer_addr_ip4.s_addr, in gtp_build_skb_ip4()
838 inet_sk(pctx->sk)->inet_saddr); in gtp_build_skb_ip4()
841 &pctx->peer_addr_ip4.s_addr); in gtp_build_skb_ip4()
848 &pctx->peer_addr_ip4.s_addr); in gtp_build_skb_ip4()
858 switch (pctx->gtp_version) { in gtp_build_skb_ip4()
880 gtp_set_pktinfo_ipv4(pktinfo, pctx->sk, iph, pctx, rt, &fl4, dev); in gtp_build_skb_ip4()
927 !net_eq(sock_net(pktinfo.pctx->sk), in gtp_dev_xmit()
1110 struct pdp_ctx *pctx; in gtp_dellink() local
1114 hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid) in gtp_dellink()
1115 pdp_context_delete(pctx); in gtp_dellink()
1307 static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info) in ipv4_pdp_fill() argument
1309 pctx->gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]); in ipv4_pdp_fill()
1310 pctx->af = AF_INET; in ipv4_pdp_fill()
1311 pctx->peer_addr_ip4.s_addr = in ipv4_pdp_fill()
1313 pctx->ms_addr_ip4.s_addr = in ipv4_pdp_fill()
1316 switch (pctx->gtp_version) { in ipv4_pdp_fill()
1322 pctx->u.v0.tid = nla_get_u64(info->attrs[GTPA_TID]); in ipv4_pdp_fill()
1323 pctx->u.v0.flow = nla_get_u16(info->attrs[GTPA_FLOW]); in ipv4_pdp_fill()
1326 pctx->u.v1.i_tei = nla_get_u32(info->attrs[GTPA_I_TEI]); in ipv4_pdp_fill()
1327 pctx->u.v1.o_tei = nla_get_u32(info->attrs[GTPA_O_TEI]); in ipv4_pdp_fill()
1337 struct pdp_ctx *pctx, *pctx_tid = NULL; in gtp_pdp_add() local
1348 pctx = ipv4_pdp_find(gtp, ms_addr); in gtp_pdp_add()
1349 if (pctx) in gtp_pdp_add()
1366 if (pctx && pctx_tid) in gtp_pdp_add()
1368 if (!pctx) in gtp_pdp_add()
1369 pctx = pctx_tid; in gtp_pdp_add()
1371 ipv4_pdp_fill(pctx, info); in gtp_pdp_add()
1373 if (pctx->gtp_version == GTP_V0) in gtp_pdp_add()
1375 pctx->u.v0.tid, pctx); in gtp_pdp_add()
1376 else if (pctx->gtp_version == GTP_V1) in gtp_pdp_add()
1378 pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx); in gtp_pdp_add()
1380 return pctx; in gtp_pdp_add()
1384 pctx = kmalloc(sizeof(*pctx), GFP_ATOMIC); in gtp_pdp_add()
1385 if (pctx == NULL) in gtp_pdp_add()
1389 pctx->sk = sk; in gtp_pdp_add()
1390 pctx->dev = gtp->dev; in gtp_pdp_add()
1391 ipv4_pdp_fill(pctx, info); in gtp_pdp_add()
1392 atomic_set(&pctx->tx_seq, 0); in gtp_pdp_add()
1394 switch (pctx->gtp_version) { in gtp_pdp_add()
1401 hash_tid = gtp0_hashfn(pctx->u.v0.tid) % gtp->hash_size; in gtp_pdp_add()
1404 hash_tid = gtp1u_hashfn(pctx->u.v1.i_tei) % gtp->hash_size; in gtp_pdp_add()
1408 hlist_add_head_rcu(&pctx->hlist_addr, &gtp->addr_hash[hash_ms]); in gtp_pdp_add()
1409 hlist_add_head_rcu(&pctx->hlist_tid, &gtp->tid_hash[hash_tid]); in gtp_pdp_add()
1411 switch (pctx->gtp_version) { in gtp_pdp_add()
1414 pctx->u.v0.tid, &pctx->peer_addr_ip4, in gtp_pdp_add()
1415 &pctx->ms_addr_ip4, pctx); in gtp_pdp_add()
1419 pctx->u.v1.i_tei, pctx->u.v1.o_tei, in gtp_pdp_add()
1420 &pctx->peer_addr_ip4, &pctx->ms_addr_ip4, pctx); in gtp_pdp_add()
1424 return pctx; in gtp_pdp_add()
1429 struct pdp_ctx *pctx = container_of(head, struct pdp_ctx, rcu_head); in pdp_context_free() local
1431 sock_put(pctx->sk); in pdp_context_free()
1432 kfree(pctx); in pdp_context_free()
1435 static void pdp_context_delete(struct pdp_ctx *pctx) in pdp_context_delete() argument
1437 hlist_del_rcu(&pctx->hlist_tid); in pdp_context_delete()
1438 hlist_del_rcu(&pctx->hlist_addr); in pdp_context_delete()
1439 call_rcu(&pctx->rcu_head, pdp_context_free); in pdp_context_delete()
1442 static int gtp_tunnel_notify(struct pdp_ctx *pctx, u8 cmd, gfp_t allocation);
1447 struct pdp_ctx *pctx; in gtp_genl_new_pdp() local
1496 pctx = gtp_pdp_add(gtp, sk, info); in gtp_genl_new_pdp()
1497 if (IS_ERR(pctx)) { in gtp_genl_new_pdp()
1498 err = PTR_ERR(pctx); in gtp_genl_new_pdp()
1500 gtp_tunnel_notify(pctx, GTP_CMD_NEWPDP, GFP_KERNEL); in gtp_genl_new_pdp()
1536 struct pdp_ctx *pctx; in gtp_find_pdp() local
1539 pctx = gtp_find_pdp_by_link(net, nla); in gtp_find_pdp()
1541 pctx = ERR_PTR(-EINVAL); in gtp_find_pdp()
1543 if (!pctx) in gtp_find_pdp()
1544 pctx = ERR_PTR(-ENOENT); in gtp_find_pdp()
1546 return pctx; in gtp_find_pdp()
1551 struct pdp_ctx *pctx; in gtp_genl_del_pdp() local
1559 pctx = gtp_find_pdp(sock_net(skb->sk), info->attrs); in gtp_genl_del_pdp()
1560 if (IS_ERR(pctx)) { in gtp_genl_del_pdp()
1561 err = PTR_ERR(pctx); in gtp_genl_del_pdp()
1565 if (pctx->gtp_version == GTP_V0) in gtp_genl_del_pdp()
1566 netdev_dbg(pctx->dev, "GTPv0-U: deleting tunnel id = %llx (pdp %p)\n", in gtp_genl_del_pdp()
1567 pctx->u.v0.tid, pctx); in gtp_genl_del_pdp()
1568 else if (pctx->gtp_version == GTP_V1) in gtp_genl_del_pdp()
1569 netdev_dbg(pctx->dev, "GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n", in gtp_genl_del_pdp()
1570 pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx); in gtp_genl_del_pdp()
1572 gtp_tunnel_notify(pctx, GTP_CMD_DELPDP, GFP_ATOMIC); in gtp_genl_del_pdp()
1573 pdp_context_delete(pctx); in gtp_genl_del_pdp()
1581 int flags, u32 type, struct pdp_ctx *pctx) in gtp_genl_fill_info() argument
1590 if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version) || in gtp_genl_fill_info()
1591 nla_put_u32(skb, GTPA_LINK, pctx->dev->ifindex) || in gtp_genl_fill_info()
1592 nla_put_be32(skb, GTPA_PEER_ADDRESS, pctx->peer_addr_ip4.s_addr) || in gtp_genl_fill_info()
1593 nla_put_be32(skb, GTPA_MS_ADDRESS, pctx->ms_addr_ip4.s_addr)) in gtp_genl_fill_info()
1596 switch (pctx->gtp_version) { in gtp_genl_fill_info()
1598 if (nla_put_u64_64bit(skb, GTPA_TID, pctx->u.v0.tid, GTPA_PAD) || in gtp_genl_fill_info()
1599 nla_put_u16(skb, GTPA_FLOW, pctx->u.v0.flow)) in gtp_genl_fill_info()
1603 if (nla_put_u32(skb, GTPA_I_TEI, pctx->u.v1.i_tei) || in gtp_genl_fill_info()
1604 nla_put_u32(skb, GTPA_O_TEI, pctx->u.v1.o_tei)) in gtp_genl_fill_info()
1617 static int gtp_tunnel_notify(struct pdp_ctx *pctx, u8 cmd, gfp_t allocation) in gtp_tunnel_notify() argument
1626 ret = gtp_genl_fill_info(msg, 0, 0, 0, cmd, pctx); in gtp_tunnel_notify()
1632 ret = genlmsg_multicast_netns(&gtp_genl_family, dev_net(pctx->dev), msg, in gtp_tunnel_notify()
1639 struct pdp_ctx *pctx = NULL; in gtp_genl_get_pdp() local
1648 pctx = gtp_find_pdp(sock_net(skb->sk), info->attrs); in gtp_genl_get_pdp()
1649 if (IS_ERR(pctx)) { in gtp_genl_get_pdp()
1650 err = PTR_ERR(pctx); in gtp_genl_get_pdp()
1661 0, info->nlhdr->nlmsg_type, pctx); in gtp_genl_get_pdp()
1681 struct pdp_ctx *pctx; in gtp_genl_dump_pdp() local
1698 hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], in gtp_genl_dump_pdp()
1705 cb->nlh->nlmsg_type, pctx)) { in gtp_genl_dump_pdp()