From patchwork Mon Nov 16 15:06:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Schultz X-Patchwork-Id: 545060 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.osmocom.org (tmp.osmocom.org [144.76.43.76]) by ozlabs.org (Postfix) with ESMTP id 7161614144D for ; Tue, 17 Nov 2015 02:07:22 +1100 (AEDT) Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by lists.osmocom.org (Postfix) with ESMTP id 21C7A9C87; Mon, 16 Nov 2015 15:07:21 +0000 (UTC) X-Original-To: openbsc@lists.osmocom.org Delivered-To: openbsc@lists.osmocom.org Received: from mail.tpip.net (mail.tpip.net [92.43.49.48]) by lists.osmocom.org (Postfix) with ESMTP id 802119C0F for ; Mon, 16 Nov 2015 15:07:13 +0000 (UTC) Received: from office.tpip.net (office.tpip.net [92.43.51.2]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.tpip.net (Postfix) with ESMTPS id A4C454F4E5; Mon, 16 Nov 2015 15:07:09 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by office.tpip.net (Postfix) with ESMTP id DC4D4A2C9A; Mon, 16 Nov 2015 16:07:10 +0100 (CET) Received: from office.tpip.net ([127.0.0.1]) by localhost (office.tpip.net [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id XN0SBNN3gs1p; Mon, 16 Nov 2015 16:07:10 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by office.tpip.net (Postfix) with ESMTP id 869BBA2C9E; Mon, 16 Nov 2015 16:07:10 +0100 (CET) X-Virus-Scanned: amavisd-new at tpip.net Received: from office.tpip.net ([127.0.0.1]) by localhost (office.tpip.net [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id oJ0MLirwSOn6; Mon, 16 Nov 2015 16:07:10 +0100 (CET) Received: from alice.tpip.org (unknown [192.168.13.53]) by office.tpip.net (Postfix) with ESMTPSA id 3056EA2CA7; Mon, 16 Nov 2015 16:07:10 +0100 (CET) From: Andreas Schultz To: openbsc@lists.osmocom.org Subject: [PATCH 16/16] gtp: add support for replacing PDP contexts Date: Mon, 16 Nov 2015 16:06:57 +0100 Message-Id: <1447686417-3979-17-git-send-email-aschultz@tpip.net> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1447686417-3979-1-git-send-email-aschultz@tpip.net> References: <1447686417-3979-1-git-send-email-aschultz@tpip.net> X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Development of the OpenBSC GSM base station controller List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pablo Neira Ayuso Errors-To: openbsc-bounces@lists.osmocom.org Sender: "OpenBSC" Signed-off-by: Andreas Schultz --- gtp.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/gtp.c b/gtp.c index 4b233f7..2b8738d 100644 --- a/gtp.c +++ b/gtp.c @@ -1080,24 +1080,44 @@ static int ipv4_pdp_add(struct net_device *dev, struct genl_info *info) } if (found) { + struct pdp_ctx *repl_pctx; + if (info->nlhdr->nlmsg_flags & NLM_F_EXCL) return -EEXIST; - if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE) - return -EOPNOTSUPP; - ipv4_pdp_fill(pctx, info); + repl_pctx = kmemdup(pctx, sizeof(struct pdp_ctx), GFP_KERNEL); + if (repl_pctx == NULL) + return -ENOMEM; + + ipv4_pdp_fill(repl_pctx, info); + + /* only the SGSN can be changed */ + if (pctx->af != repl_pctx->af || + pctx->gtp_version != repl_pctx->gtp_version || + memcpy(&pctx->u, &repl_pctx->u, sizeof(pctx->u) != 0)) { + kfree(repl_pctx); + return -EINVAL; + } + + hlist_replace_rcu(&pctx->hlist_addr, &repl_pctx->hlist_addr); + hlist_replace_rcu(&pctx->hlist_tid, &repl_pctx->hlist_tid); - if (pctx->gtp_version == GTP_V0) + kfree_rcu(pctx, rcu_head); + + if (repl_pctx->gtp_version == GTP_V0) netdev_dbg(dev, "GTPv0-U: update tunnel id = %llx (pdp %p)\n", - pctx->u.v0.tid, pctx); - else if (pctx->gtp_version == GTP_V1) + repl_pctx->u.v0.tid, repl_pctx); + else if (repl_pctx->gtp_version == GTP_V1) netdev_dbg(dev, "GTPv1-U: update tunnel id = %x/%x (pdp %p)\n", - pctx->u.v1.i_tid, pctx->u.v1.o_tid, pctx); + repl_pctx->u.v1.i_tid, repl_pctx->u.v1.o_tid, repl_pctx); return 0; } + if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE) + return -ENXIO; + pctx = kmalloc(sizeof(struct pdp_ctx), GFP_KERNEL); if (pctx == NULL) return -ENOMEM;