On Mon, Nov 16, 2015 at 04:06:45PM +0100, Andreas Schultz wrote:
This permits a split namespace setup where the GTP transport sockets are in one namespace the gtp tunnel interface is in another namespace.
The target namespece is selected by the new GTPA_NET_NS_FD NL attributes. It fall back to the netns of the GTP-U sockets if the NL attr is not present.
Signed-off-by: Andreas Schultz aschultz@tpip.net
gtp.c | 41 +++++++++++++++++++++++++++++++++++++---- gtp_nl.h | 1 + 2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/gtp.c b/gtp.c index 7c61e61..11f8fad 100644 --- a/gtp.c +++ b/gtp.c @@ -330,6 +330,8 @@ static int gtp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) if (!gti) goto user;
- netdev_dbg(gti->dev, "encap_recv %p\n", sk);
- switch (udp_sk(sk)->encap_type) { case UDP_ENCAP_GTP0: netdev_dbg(gti->dev, "received GTP0 packet\n");
@@ -738,7 +740,7 @@ static int gtp_encap_enable(struct net_device *dev, struct gtp_instance *gti, static int gtp_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) {
- struct gtp_net *gn = net_generic(src_net, gtp_net_id);
- struct gtp_net *gn; struct net_device *real_dev; struct gtp_instance *gti; int hashsize, err, fd0, fd1;
@@ -778,6 +780,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev, if (err < 0) goto err1;
gn = net_generic(dev_net(dev), gtp_net_id); list_add_rcu(>i->list, &gn->gtp_instance_list);
netdev_dbg(dev, "registered new interface\n");
@@ -845,6 +848,19 @@ static struct rtnl_link_ops gtp_link_ops __read_mostly = { .fill_info = gtp_fill_info, };
+static struct net *gtp_genl_get_net(struct net *src_net, struct nlattr *tb[]) +{
- struct net *net;
- /* Examine the link attributes and figure out which
* network namespace we are talking about.*/- if (tb[GTPA_NET_NS_FD])
net = get_net_ns_by_fd(nla_get_u32(tb[GTPA_NET_NS_FD]));
I can see this returns ERR_PTR() so...
- else
net = get_net(src_net);- return net;
+}
static int gtp_hashtable_new(struct gtp_instance *gti, int hsize) { int i; @@ -893,6 +909,8 @@ static int gtp_encap_enable(struct net_device *dev, struct gtp_instance *gti, struct socket *sock0, *sock1u; struct sock *sk;
- netdev_dbg(dev, "enable gtp on %d, %d\n", fd_gtp0, fd_gtp1);
- sock0 = sockfd_lookup(fd_gtp0, &err); if (sock0 == NULL) { netdev_dbg(dev, "socket fd=%d not found (gtp0)\n", fd_gtp0);
@@ -918,6 +936,8 @@ static int gtp_encap_enable(struct net_device *dev, struct gtp_instance *gti, goto err2; }
- netdev_dbg(dev, "enable gtp on %p, %p\n", sock0, sock1u);
- gti->sock0 = sock0; gti->sock1u = sock1u;
@@ -1059,7 +1079,7 @@ static int ipv4_pdp_add(struct net_device *dev, struct genl_info *info)
static int gtp_genl_tunnel_new(struct sk_buff *skb, struct genl_info *info) {
- struct net *net = sock_net(skb->sk);
struct net *net; struct net_device *dev;
if (!info->attrs[GTPA_VERSION] ||
@@ -1069,6 +1089,10 @@ static int gtp_genl_tunnel_new(struct sk_buff *skb, struct genl_info *info) !info->attrs[GTPA_TID]) return -EINVAL;
- net = gtp_genl_get_net(sock_net(skb->sk), info->attrs);
- if (net == NULL)
This has to be IS_ERR().
return -EINVAL;- /* Check if there's an existing gtpX device to configure */ dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK])); if (dev == NULL)
@@ -1079,7 +1103,7 @@ static int gtp_genl_tunnel_new(struct sk_buff *skb, struct genl_info *info)
static int gtp_genl_tunnel_delete(struct sk_buff *skb, struct genl_info *info) {
- struct net *net = sock_net(skb->sk);
- struct net *net; struct gtp_instance *gti; struct net_device *dev; struct pdp_ctx *pctx;
@@ -1107,6 +1131,10 @@ static int gtp_genl_tunnel_delete(struct sk_buff *skb, struct genl_info *info) if (gtp_version == GTP_V1 && tid > UINT_MAX) return -EINVAL;
- net = gtp_genl_get_net(sock_net(skb->sk), info->attrs);
- if (net == NULL)
This one too.
return -EINVAL;- /* Check if there's an existing gtpX device to configure */ dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK])); if (dev == NULL)
@@ -1175,7 +1203,7 @@ nla_put_failure:
static int gtp_genl_tunnel_get(struct sk_buff *skb, struct genl_info *info) {
- struct net *net = sock_net(skb->sk);
- struct net *net; struct net_device *dev; struct gtp_instance *gti; struct pdp_ctx *pctx = NULL;
@@ -1196,6 +1224,10 @@ static int gtp_genl_tunnel_get(struct sk_buff *skb, struct genl_info *info) return -EINVAL; }
- net = gtp_genl_get_net(sock_net(skb->sk), info->attrs);
- if (net == NULL)
And here.
BTW, I'd appreciate if you can add netdev_dbg stuff in a separated patch.