[PATCH net-next v5 2/2] gtp: support SGSN-side tunnels

2017-03-24 Thread Jonas Bonn
The GTP-tunnel driver is explicitly GGSN-side as it searches for PDP
contexts based on the incoming packets _destination_ address.  If we
want to place ourselves on the SGSN side of the  tunnel, then we want
to be identifying PDP contexts based on _source_ address.

Let it be noted that in a "real" configuration this module would never
be used:  the SGSN normally does not see IP packets as input.  The
justification for this functionality is for PGW load-testing applications
where the input to the SGSN is locally generally IP traffic.

This patch adds a "role" argument at GTP-link creation time to specify
whether we are on the GGSN or SGSN side of the tunnel; this flag is then
used to determine which part of the IP packet to use in determining
the PDP context.

Signed-off-by: Jonas Bonn <jo...@southpole.se>
Acked-by: Pablo Neira Ayuso <pa...@netfilter.org>
Acked-by: Harald Welte <lafo...@gnumonks.org>
---
 drivers/net/gtp.c| 42 ++
 include/uapi/linux/if_link.h |  7 +++
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 1f6d911..4fea1b3 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -74,6 +74,7 @@ struct gtp_dev {
 
struct net_device   *dev;
 
+   unsigned introle;
unsigned inthash_size;
struct hlist_head   *tid_hash;
struct hlist_head   *addr_hash;
@@ -154,8 +155,8 @@ static struct pdp_ctx *ipv4_pdp_find(struct gtp_dev *gtp, 
__be32 ms_addr)
return NULL;
 }
 
-static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
- unsigned int hdrlen)
+static bool gtp_check_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
+ unsigned int hdrlen, unsigned int role)
 {
struct iphdr *iph;
 
@@ -164,27 +165,31 @@ static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, 
struct pdp_ctx *pctx,
 
iph = (struct iphdr *)(skb->data + hdrlen);
 
-   return iph->saddr == pctx->ms_addr_ip4.s_addr;
+   if (role == GTP_ROLE_SGSN)
+   return iph->daddr == pctx->ms_addr_ip4.s_addr;
+   else
+   return iph->saddr == pctx->ms_addr_ip4.s_addr;
 }
 
-/* Check if the inner IP source address in this packet is assigned to any
+/* Check if the inner IP address in this packet is assigned to any
  * existing mobile subscriber.
  */
-static bool gtp_check_src_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
-unsigned int hdrlen)
+static bool gtp_check_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
+unsigned int hdrlen, unsigned int role)
 {
switch (ntohs(skb->protocol)) {
case ETH_P_IP:
-   return gtp_check_src_ms_ipv4(skb, pctx, hdrlen);
+   return gtp_check_ms_ipv4(skb, pctx, hdrlen, role);
}
return false;
 }
 
-static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb, unsigned int 
hdrlen)
+static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb,
+   unsigned int hdrlen, unsigned int role)
 {
struct pcpu_sw_netstats *stats;
 
-   if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+   if (!gtp_check_ms(skb, pctx, hdrlen, role)) {
netdev_dbg(pctx->dev, "No PDP ctx for this MS\n");
return 1;
}
@@ -239,7 +244,7 @@ static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb)
return 1;
}
 
-   return gtp_rx(pctx, skb, hdrlen);
+   return gtp_rx(pctx, skb, hdrlen, gtp->role);
 }
 
 static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
@@ -281,7 +286,7 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb)
return 1;
}
 
-   return gtp_rx(pctx, skb, hdrlen);
+   return gtp_rx(pctx, skb, hdrlen, gtp->role);
 }
 
 static void gtp_encap_destroy(struct sock *sk)
@@ -481,7 +486,11 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct 
net_device *dev,
 * Prepend PDP header with TEI/TID from PDP ctx.
 */
iph = ip_hdr(skb);
-   pctx = ipv4_pdp_find(gtp, iph->daddr);
+   if (gtp->role == GTP_ROLE_SGSN)
+   pctx = ipv4_pdp_find(gtp, iph->saddr);
+   else
+   pctx = ipv4_pdp_find(gtp, iph->daddr);
+
if (!pctx) {
netdev_dbg(dev, "no PDP ctx found for %pI4, skip\n",
   >daddr);
@@ -685,6 +694,7 @@ static const struct nla_policy gtp_policy[IFLA_GTP_MAX + 1] 
= {
[IFLA_GTP_FD0]  = { .type = NLA_U32 },
[IFLA_GTP_FD1]  = { .type = NLA_U32 },
[IFLA_GTP_PDP_HASHSIZE] = { .type = NLA_U32 },
+   [IFLA_GTP_ROLE] = { .type = NLA_U32 },

[PATCH net-next v5 1/2] gtp: rename SGSN netlink attribute

2017-03-24 Thread Jonas Bonn
This is a mostly cosmetic rename of the SGSN netlink attribute to
the GTP link.  The justification for this is that we will be making
the module support decapsulation of "downstream" SGSN packets, in
which case the netlink parameter actually refers to the upstream GGSN
peer.  Renaming the parameter makes the relationship clearer.

The legacy name is maintained as a define in the header file in order
to not break existing code.

Signed-off-by: Jonas Bonn <jo...@southpole.se>
Acked-by: Pablo Neira Ayuso <pa...@netfilter.org>
Acked-by: Harald Welte <lafo...@gnumonks.org>
---
 drivers/net/gtp.c| 22 +++---
 include/uapi/linux/gtp.h |  3 ++-
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 3e1854f..1f6d911 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -56,7 +56,7 @@ struct pdp_ctx {
u16 af;
 
struct in_addr  ms_addr_ip4;
-   struct in_addr  sgsn_addr_ip4;
+   struct in_addr  peer_addr_ip4;
 
struct sock *sk;
struct net_device   *dev;
@@ -489,17 +489,17 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct 
net_device *dev,
}
netdev_dbg(dev, "found PDP context %p\n", pctx);
 
-   rt = ip4_route_output_gtp(, pctx->sk, pctx->sgsn_addr_ip4.s_addr);
+   rt = ip4_route_output_gtp(, pctx->sk, pctx->peer_addr_ip4.s_addr);
if (IS_ERR(rt)) {
netdev_dbg(dev, "no route to SSGN %pI4\n",
-  >sgsn_addr_ip4.s_addr);
+  >peer_addr_ip4.s_addr);
dev->stats.tx_carrier_errors++;
goto err;
}
 
if (rt->dst.dev == dev) {
netdev_dbg(dev, "circular route to SSGN %pI4\n",
-  >sgsn_addr_ip4.s_addr);
+  >peer_addr_ip4.s_addr);
dev->stats.collisions++;
goto err_rt;
}
@@ -866,8 +866,8 @@ static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct 
genl_info *info)
 {
pctx->gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
pctx->af = AF_INET;
-   pctx->sgsn_addr_ip4.s_addr =
-   nla_get_be32(info->attrs[GTPA_SGSN_ADDRESS]);
+   pctx->peer_addr_ip4.s_addr =
+   nla_get_be32(info->attrs[GTPA_PEER_ADDRESS]);
pctx->ms_addr_ip4.s_addr =
nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
 
@@ -957,13 +957,13 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct sock 
*sk,
switch (pctx->gtp_version) {
case GTP_V0:
netdev_dbg(dev, "GTPv0-U: new PDP ctx id=%llx ssgn=%pI4 ms=%pI4 
(pdp=%p)\n",
-  pctx->u.v0.tid, >sgsn_addr_ip4,
+  pctx->u.v0.tid, >peer_addr_ip4,
   >ms_addr_ip4, pctx);
break;
case GTP_V1:
netdev_dbg(dev, "GTPv1-U: new PDP ctx id=%x/%x ssgn=%pI4 
ms=%pI4 (pdp=%p)\n",
   pctx->u.v1.i_tei, pctx->u.v1.o_tei,
-  >sgsn_addr_ip4, >ms_addr_ip4, pctx);
+  >peer_addr_ip4, >ms_addr_ip4, pctx);
break;
}
 
@@ -994,7 +994,7 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct 
genl_info *info)
 
if (!info->attrs[GTPA_VERSION] ||
!info->attrs[GTPA_LINK] ||
-   !info->attrs[GTPA_SGSN_ADDRESS] ||
+   !info->attrs[GTPA_PEER_ADDRESS] ||
!info->attrs[GTPA_MS_ADDRESS])
return -EINVAL;
 
@@ -1126,7 +1126,7 @@ static int gtp_genl_fill_info(struct sk_buff *skb, u32 
snd_portid, u32 snd_seq,
goto nlmsg_failure;
 
if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version) ||
-   nla_put_be32(skb, GTPA_SGSN_ADDRESS, pctx->sgsn_addr_ip4.s_addr) ||
+   nla_put_be32(skb, GTPA_PEER_ADDRESS, pctx->peer_addr_ip4.s_addr) ||
nla_put_be32(skb, GTPA_MS_ADDRESS, pctx->ms_addr_ip4.s_addr))
goto nla_put_failure;
 
@@ -1237,7 +1237,7 @@ static struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = {
[GTPA_LINK] = { .type = NLA_U32, },
[GTPA_VERSION]  = { .type = NLA_U32, },
[GTPA_TID]  = { .type = NLA_U64, },
-   [GTPA_SGSN_ADDRESS] = { .type = NLA_U32, },
+   [GTPA_PEER_ADDRESS] = { .type = NLA_U32, },
[GTPA_MS_ADDRESS]   = { .type = NLA_U32, },
[GTPA_FLOW] = { .type = NLA_U16, },
[GTPA_NET_NS_FD]= { .type = NLA_U32, },
diff --git a/include/uapi/linux/gtp.h b/include/uapi/linux/gtp.h
index 72a04a0..57d1edb 100644
--- a/include/uapi/linux/gtp.h
+++ b/include/uapi/linux/gtp.h
@@ -19,7 +19,8 @@ 

[PATCH net-next v5 0/2] GTP SGSN-side tunnel

2017-03-24 Thread Jonas Bonn
Changes since v4:

* Respin the series on top of net-next; the conflicts were trivial,
  amounting to just code having been shifted about

Jonas Bonn (2):
  gtp: rename SGSN netlink attribute
  gtp: support SGSN-side tunnels

 drivers/net/gtp.c| 64 
 include/uapi/linux/gtp.h |  3 ++-
 include/uapi/linux/if_link.h |  7 +
 3 files changed, 50 insertions(+), 24 deletions(-)

-- 
2.9.3



Re: [PATCH net-next v3 0/2] GTP SGSN-side tunnels

2017-03-24 Thread Jonas Bonn

On 03/24/2017 11:41 AM, Pablo Neira Ayuso wrote:

On Fri, Mar 24, 2017 at 10:33:56AM +0100, Jonas Bonn wrote:

Changes since v2:

* Move #define of legacy netlink attribute into enum
* Added note to commit message about load-testing use-case
* Ack from Pablo

Thanks a lot Jonas!

David, please apply. Thanks!


David, please apply v4 instead as it has a coding-style fixup requested 
by Harald.


Thanks,

Jonas



[PATCH net-next v4 2/2] gtp: support SGSN-side tunnels

2017-03-24 Thread Jonas Bonn
The GTP-tunnel driver is explicitly GGSN-side as it searches for PDP
contexts based on the incoming packets _destination_ address.  If we
want to place ourselves on the SGSN side of the  tunnel, then we want
to be identifying PDP contexts based on _source_ address.

Let it be noted that in a "real" configuration this module would never
be used:  the SGSN normally does not see IP packets as input.  The
justification for this functionality is for PGW load-testing applications
where the input to the SGSN is locally generally IP traffic.

This patch adds a "role" argument at GTP-link creation time to specify
whether we are on the GGSN or SGSN side of the tunnel; this flag is then
used to determine which part of the IP packet to use in determining
the PDP context.

Signed-off-by: Jonas Bonn <jo...@southpole.se>
Acked-by: Pablo Neira Ayuso <pa...@netfilter.org>
Acked-by: Harald Welte <lafo...@gnumonks.org>
---
 drivers/net/gtp.c| 40 ++--
 include/uapi/linux/if_link.h |  7 +++
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 3806be6..e674cb1 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -72,6 +72,7 @@ struct gtp_dev {
struct net  *net;
struct net_device   *dev;
 
+   unsigned introle;
unsigned inthash_size;
struct hlist_head   *tid_hash;
struct hlist_head   *addr_hash;
@@ -150,8 +151,8 @@ static struct pdp_ctx *ipv4_pdp_find(struct gtp_dev *gtp, 
__be32 ms_addr)
return NULL;
 }
 
-static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
- unsigned int hdrlen)
+static bool gtp_check_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
+ unsigned int hdrlen, unsigned int role)
 {
struct iphdr *iph;
 
@@ -160,18 +161,21 @@ static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, 
struct pdp_ctx *pctx,
 
iph = (struct iphdr *)(skb->data + hdrlen);
 
-   return iph->saddr == pctx->ms_addr_ip4.s_addr;
+   if (role == GTP_ROLE_SGSN)
+   return iph->daddr == pctx->ms_addr_ip4.s_addr;
+   else
+   return iph->saddr == pctx->ms_addr_ip4.s_addr;
 }
 
-/* Check if the inner IP source address in this packet is assigned to any
+/* Check if the inner IP address in this packet is assigned to any
  * existing mobile subscriber.
  */
-static bool gtp_check_src_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
-unsigned int hdrlen)
+static bool gtp_check_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
+unsigned int hdrlen, unsigned int role)
 {
switch (ntohs(skb->protocol)) {
case ETH_P_IP:
-   return gtp_check_src_ms_ipv4(skb, pctx, hdrlen);
+   return gtp_check_ms_ipv4(skb, pctx, hdrlen, role);
}
return false;
 }
@@ -205,7 +209,7 @@ static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb,
goto out_rcu;
}
 
-   if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+   if (!gtp_check_ms(skb, pctx, hdrlen, gtp->role)) {
netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
ret = -1;
goto out_rcu;
@@ -262,7 +266,7 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb,
goto out_rcu;
}
 
-   if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+   if (!gtp_check_ms(skb, pctx, hdrlen, gtp->role)) {
netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
ret = -1;
goto out_rcu;
@@ -491,7 +495,11 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct 
net_device *dev,
 * Prepend PDP header with TEI/TID from PDP ctx.
 */
iph = ip_hdr(skb);
-   pctx = ipv4_pdp_find(gtp, iph->daddr);
+   if (gtp->role == GTP_ROLE_SGSN)
+   pctx = ipv4_pdp_find(gtp, iph->saddr);
+   else
+   pctx = ipv4_pdp_find(gtp, iph->daddr);
+
if (!pctx) {
netdev_dbg(dev, "no PDP ctx found for %pI4, skip\n",
   >daddr);
@@ -666,12 +674,23 @@ static int gtp_newlink(struct net *src_net, struct 
net_device *dev,
int hashsize, err, fd0, fd1;
struct gtp_dev *gtp;
struct gtp_net *gn;
+   unsigned int role;
+
+   if (data[IFLA_GTP_ROLE]) {
+   role = nla_get_u32(data[IFLA_GTP_ROLE]);
+   if (role > GTP_ROLE_SGSN)
+   return -EINVAL;
+   } else {
+   role = GTP_ROLE_GGSN;
+   }
 
if (!data[IFLA_GTP_FD0] || !data[IFLA_GTP_FD1])
return -EINVAL;
 
gtp = netdev_priv(dev);
 
+   gtp->role = role;

[PATCH net-next v4 1/2] gtp: rename SGSN netlink attribute

2017-03-24 Thread Jonas Bonn
This is a mostly cosmetic rename of the SGSN netlink attribute to
the GTP link.  The justification for this is that we will be making
the module support decapsulation of "downstream" SGSN packets, in
which case the netlink parameter actually refers to the upstream GGSN
peer.  Renaming the parameter makes the relationship clearer.

The legacy name is maintained as a define in the header file in order
to not break existing code.

Signed-off-by: Jonas Bonn <jo...@southpole.se>
Acked-by: Pablo Neira Ayuso <pa...@netfilter.org>
Acked-by: Harald Welte <lafo...@gnumonks.org>
---
 drivers/net/gtp.c| 22 +++---
 include/uapi/linux/gtp.h |  3 ++-
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 50349a9..3806be6 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -56,7 +56,7 @@ struct pdp_ctx {
u16 af;
 
struct in_addr  ms_addr_ip4;
-   struct in_addr  sgsn_addr_ip4;
+   struct in_addr  peer_addr_ip4;
 
atomic_ttx_seq;
struct rcu_head rcu_head;
@@ -522,17 +522,17 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct 
net_device *dev,
}
 
rt = ip4_route_output_gtp(sock_net(sk), , gtp->sock0->sk,
- pctx->sgsn_addr_ip4.s_addr);
+ pctx->peer_addr_ip4.s_addr);
if (IS_ERR(rt)) {
netdev_dbg(dev, "no route to SSGN %pI4\n",
-  >sgsn_addr_ip4.s_addr);
+  >peer_addr_ip4.s_addr);
dev->stats.tx_carrier_errors++;
goto err;
}
 
if (rt->dst.dev == dev) {
netdev_dbg(dev, "circular route to SSGN %pI4\n",
-  >sgsn_addr_ip4.s_addr);
+  >peer_addr_ip4.s_addr);
dev->stats.collisions++;
goto err_rt;
}
@@ -894,8 +894,8 @@ static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct 
genl_info *info)
 {
pctx->gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
pctx->af = AF_INET;
-   pctx->sgsn_addr_ip4.s_addr =
-   nla_get_be32(info->attrs[GTPA_SGSN_ADDRESS]);
+   pctx->peer_addr_ip4.s_addr =
+   nla_get_be32(info->attrs[GTPA_PEER_ADDRESS]);
pctx->ms_addr_ip4.s_addr =
nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
 
@@ -981,13 +981,13 @@ static int ipv4_pdp_add(struct net_device *dev, struct 
genl_info *info)
switch (pctx->gtp_version) {
case GTP_V0:
netdev_dbg(dev, "GTPv0-U: new PDP ctx id=%llx ssgn=%pI4 ms=%pI4 
(pdp=%p)\n",
-  pctx->u.v0.tid, >sgsn_addr_ip4,
+  pctx->u.v0.tid, >peer_addr_ip4,
   >ms_addr_ip4, pctx);
break;
case GTP_V1:
netdev_dbg(dev, "GTPv1-U: new PDP ctx id=%x/%x ssgn=%pI4 
ms=%pI4 (pdp=%p)\n",
   pctx->u.v1.i_tei, pctx->u.v1.o_tei,
-  >sgsn_addr_ip4, >ms_addr_ip4, pctx);
+  >peer_addr_ip4, >ms_addr_ip4, pctx);
break;
}
 
@@ -1001,7 +1001,7 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct 
genl_info *info)
 
if (!info->attrs[GTPA_VERSION] ||
!info->attrs[GTPA_LINK] ||
-   !info->attrs[GTPA_SGSN_ADDRESS] ||
+   !info->attrs[GTPA_PEER_ADDRESS] ||
!info->attrs[GTPA_MS_ADDRESS])
return -EINVAL;
 
@@ -1114,7 +1114,7 @@ static int gtp_genl_fill_info(struct sk_buff *skb, u32 
snd_portid, u32 snd_seq,
goto nlmsg_failure;
 
if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version) ||
-   nla_put_be32(skb, GTPA_SGSN_ADDRESS, pctx->sgsn_addr_ip4.s_addr) ||
+   nla_put_be32(skb, GTPA_PEER_ADDRESS, pctx->peer_addr_ip4.s_addr) ||
nla_put_be32(skb, GTPA_MS_ADDRESS, pctx->ms_addr_ip4.s_addr))
goto nla_put_failure;
 
@@ -1267,7 +1267,7 @@ static struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = {
[GTPA_LINK] = { .type = NLA_U32, },
[GTPA_VERSION]  = { .type = NLA_U32, },
[GTPA_TID]  = { .type = NLA_U64, },
-   [GTPA_SGSN_ADDRESS] = { .type = NLA_U32, },
+   [GTPA_PEER_ADDRESS] = { .type = NLA_U32, },
[GTPA_MS_ADDRESS]   = { .type = NLA_U32, },
[GTPA_FLOW] = { .type = NLA_U16, },
[GTPA_NET_NS_FD]= { .type = NLA_U32, },
diff --git a/include/uapi/linux/gtp.h b/include/uapi/linux/gtp.h
index 72a04a0..57d1edb 100644
--- a/include/uapi/linux/gtp.h
+++ b/include/uapi/linux/gtp.h
@@ -19,7 +19,8 @@ en

[PATCH net-next v4 0/2] GTP SGSN-side tunnels

2017-03-24 Thread Jonas Bonn
Changes from v3:

* Coding style fixup: remove extraneous braces on if-statement
* Ack from Harald

Jonas Bonn (2):
  gtp: rename SGSN netlink attribute
  gtp: support SGSN-side tunnels

 drivers/net/gtp.c| 62 +---
 include/uapi/linux/gtp.h |  3 ++-
 include/uapi/linux/if_link.h |  7 +
 3 files changed, 50 insertions(+), 22 deletions(-)

-- 
2.9.3



Re: [PATCH net-next v3 0/2] GTP SGSN-side tunnels

2017-03-24 Thread Jonas Bonn

Hi Harald,

On 03/24/2017 11:15 AM, Harald Welte wrote:

Hi Jonas,

looks fine to me, but I haven't tested it.  Did you manually test it
using the extended libgtpnl + tools?


I have tested it against your libgtpnl branch laforge/sgsn-role. 
Creating an interface with tools/gtp-link works fine.


We have been running the v1 patches in a production load-testing system 
for the last month.  That all works and gives good performance.  I 
haven't been able to actually run the v2 and v3 patches in that 
environment as access to it is a bit limited... that said, the changes 
from v1 to v3 are really only cosmetic and don't even touch the "parts 
that matter" with respect to encapsulation. Really the patch is pretty 
trivial... mucking about with the netlink interface is the bulk of it 
and that bit has been tested and works.




Also, in code like this:
in
+   if (gtp->role == GTP_ROLE_SGSN) {
+   pctx = ipv4_pdp_find(gtp, iph->saddr);
+   } else {

I think general Linux kernel coding style is to not have curly-brackets
around single-line blocks. See "Do not unnecessarily use braces where a
single statement will do." in line 169 of
Documentation/process/coding-style.rst

I won't mind your current style, and it is not a blocker issue to me,
but still it would be nice for general consistency.

OK, I'll fix that up just for the sake of correctness and send a v4.



Acked-by: Harald Welte 


Thanks,

Jonas



[PATCH net-next v3 1/2] gtp: rename SGSN netlink attribute

2017-03-24 Thread Jonas Bonn
This is a mostly cosmetic rename of the SGSN netlink attribute to
the GTP link.  The justification for this is that we will be making
the module support decapsulation of "downstream" SGSN packets, in
which case the netlink parameter actually refers to the upstream GGSN
peer.  Renaming the parameter makes the relationship clearer.

The legacy name is maintained as a define in the header file in order
to not break existing code.

Signed-off-by: Jonas Bonn <jo...@southpole.se>
Acked-by: Pablo Neira Ayuso <pa...@netfilter.org>
---
 drivers/net/gtp.c| 22 +++---
 include/uapi/linux/gtp.h |  3 ++-
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 50349a9..3806be6 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -56,7 +56,7 @@ struct pdp_ctx {
u16 af;
 
struct in_addr  ms_addr_ip4;
-   struct in_addr  sgsn_addr_ip4;
+   struct in_addr  peer_addr_ip4;
 
atomic_ttx_seq;
struct rcu_head rcu_head;
@@ -522,17 +522,17 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct 
net_device *dev,
}
 
rt = ip4_route_output_gtp(sock_net(sk), , gtp->sock0->sk,
- pctx->sgsn_addr_ip4.s_addr);
+ pctx->peer_addr_ip4.s_addr);
if (IS_ERR(rt)) {
netdev_dbg(dev, "no route to SSGN %pI4\n",
-  >sgsn_addr_ip4.s_addr);
+  >peer_addr_ip4.s_addr);
dev->stats.tx_carrier_errors++;
goto err;
}
 
if (rt->dst.dev == dev) {
netdev_dbg(dev, "circular route to SSGN %pI4\n",
-  >sgsn_addr_ip4.s_addr);
+  >peer_addr_ip4.s_addr);
dev->stats.collisions++;
goto err_rt;
}
@@ -894,8 +894,8 @@ static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct 
genl_info *info)
 {
pctx->gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
pctx->af = AF_INET;
-   pctx->sgsn_addr_ip4.s_addr =
-   nla_get_be32(info->attrs[GTPA_SGSN_ADDRESS]);
+   pctx->peer_addr_ip4.s_addr =
+   nla_get_be32(info->attrs[GTPA_PEER_ADDRESS]);
pctx->ms_addr_ip4.s_addr =
nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
 
@@ -981,13 +981,13 @@ static int ipv4_pdp_add(struct net_device *dev, struct 
genl_info *info)
switch (pctx->gtp_version) {
case GTP_V0:
netdev_dbg(dev, "GTPv0-U: new PDP ctx id=%llx ssgn=%pI4 ms=%pI4 
(pdp=%p)\n",
-  pctx->u.v0.tid, >sgsn_addr_ip4,
+  pctx->u.v0.tid, >peer_addr_ip4,
   >ms_addr_ip4, pctx);
break;
case GTP_V1:
netdev_dbg(dev, "GTPv1-U: new PDP ctx id=%x/%x ssgn=%pI4 
ms=%pI4 (pdp=%p)\n",
   pctx->u.v1.i_tei, pctx->u.v1.o_tei,
-  >sgsn_addr_ip4, >ms_addr_ip4, pctx);
+  >peer_addr_ip4, >ms_addr_ip4, pctx);
break;
}
 
@@ -1001,7 +1001,7 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct 
genl_info *info)
 
if (!info->attrs[GTPA_VERSION] ||
!info->attrs[GTPA_LINK] ||
-   !info->attrs[GTPA_SGSN_ADDRESS] ||
+   !info->attrs[GTPA_PEER_ADDRESS] ||
!info->attrs[GTPA_MS_ADDRESS])
return -EINVAL;
 
@@ -1114,7 +1114,7 @@ static int gtp_genl_fill_info(struct sk_buff *skb, u32 
snd_portid, u32 snd_seq,
goto nlmsg_failure;
 
if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version) ||
-   nla_put_be32(skb, GTPA_SGSN_ADDRESS, pctx->sgsn_addr_ip4.s_addr) ||
+   nla_put_be32(skb, GTPA_PEER_ADDRESS, pctx->peer_addr_ip4.s_addr) ||
nla_put_be32(skb, GTPA_MS_ADDRESS, pctx->ms_addr_ip4.s_addr))
goto nla_put_failure;
 
@@ -1267,7 +1267,7 @@ static struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = {
[GTPA_LINK] = { .type = NLA_U32, },
[GTPA_VERSION]  = { .type = NLA_U32, },
[GTPA_TID]  = { .type = NLA_U64, },
-   [GTPA_SGSN_ADDRESS] = { .type = NLA_U32, },
+   [GTPA_PEER_ADDRESS] = { .type = NLA_U32, },
[GTPA_MS_ADDRESS]   = { .type = NLA_U32, },
[GTPA_FLOW] = { .type = NLA_U16, },
[GTPA_NET_NS_FD]= { .type = NLA_U32, },
diff --git a/include/uapi/linux/gtp.h b/include/uapi/linux/gtp.h
index 72a04a0..57d1edb 100644
--- a/include/uapi/linux/gtp.h
+++ b/include/uapi/linux/gtp.h
@@ -19,7 +19,8 @@ enum gtp_attrs {
GTPA_LINK,
GT

[PATCH net-next v3 2/2] gtp: support SGSN-side tunnels

2017-03-24 Thread Jonas Bonn
The GTP-tunnel driver is explicitly GGSN-side as it searches for PDP
contexts based on the incoming packets _destination_ address.  If we
want to place ourselves on the SGSN side of the  tunnel, then we want
to be identifying PDP contexts based on _source_ address.

Let it be noted that in a "real" configuration this module would never
be used:  the SGSN normally does not see IP packets as input.  The
justification for this functionality is for PGW load-testing applications
where the input to the SGSN is locally generally IP traffic.

This patch adds a "role" argument at GTP-link creation time to specify
whether we are on the GGSN or SGSN side of the tunnel; this flag is then
used to determine which part of the IP packet to use in determining
the PDP context.

Signed-off-by: Jonas Bonn <jo...@southpole.se>
Acked-by: Pablo Neira Ayuso <pa...@netfilter.org>
---
 drivers/net/gtp.c| 41 +++--
 include/uapi/linux/if_link.h |  7 +++
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 3806be6..b54d1a3 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -72,6 +72,7 @@ struct gtp_dev {
struct net  *net;
struct net_device   *dev;
 
+   unsigned introle;
unsigned inthash_size;
struct hlist_head   *tid_hash;
struct hlist_head   *addr_hash;
@@ -150,8 +151,8 @@ static struct pdp_ctx *ipv4_pdp_find(struct gtp_dev *gtp, 
__be32 ms_addr)
return NULL;
 }
 
-static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
- unsigned int hdrlen)
+static bool gtp_check_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
+ unsigned int hdrlen, unsigned int role)
 {
struct iphdr *iph;
 
@@ -160,18 +161,22 @@ static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, 
struct pdp_ctx *pctx,
 
iph = (struct iphdr *)(skb->data + hdrlen);
 
-   return iph->saddr == pctx->ms_addr_ip4.s_addr;
+   if (role == GTP_ROLE_SGSN) {
+   return iph->daddr == pctx->ms_addr_ip4.s_addr;
+   } else {
+   return iph->saddr == pctx->ms_addr_ip4.s_addr;
+   }
 }
 
-/* Check if the inner IP source address in this packet is assigned to any
+/* Check if the inner IP address in this packet is assigned to any
  * existing mobile subscriber.
  */
-static bool gtp_check_src_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
-unsigned int hdrlen)
+static bool gtp_check_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
+unsigned int hdrlen, unsigned int role)
 {
switch (ntohs(skb->protocol)) {
case ETH_P_IP:
-   return gtp_check_src_ms_ipv4(skb, pctx, hdrlen);
+   return gtp_check_ms_ipv4(skb, pctx, hdrlen, role);
}
return false;
 }
@@ -205,7 +210,7 @@ static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb,
goto out_rcu;
}
 
-   if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+   if (!gtp_check_ms(skb, pctx, hdrlen, gtp->role)) {
netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
ret = -1;
goto out_rcu;
@@ -262,7 +267,7 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb,
goto out_rcu;
}
 
-   if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+   if (!gtp_check_ms(skb, pctx, hdrlen, gtp->role)) {
netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
ret = -1;
goto out_rcu;
@@ -491,7 +496,11 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct 
net_device *dev,
 * Prepend PDP header with TEI/TID from PDP ctx.
 */
iph = ip_hdr(skb);
-   pctx = ipv4_pdp_find(gtp, iph->daddr);
+   if (gtp->role == GTP_ROLE_SGSN) {
+   pctx = ipv4_pdp_find(gtp, iph->saddr);
+   } else {
+   pctx = ipv4_pdp_find(gtp, iph->daddr);
+   }
if (!pctx) {
netdev_dbg(dev, "no PDP ctx found for %pI4, skip\n",
   >daddr);
@@ -666,12 +675,23 @@ static int gtp_newlink(struct net *src_net, struct 
net_device *dev,
int hashsize, err, fd0, fd1;
struct gtp_dev *gtp;
struct gtp_net *gn;
+   unsigned int role;
+
+   if (data[IFLA_GTP_ROLE]) {
+   role = nla_get_u32(data[IFLA_GTP_ROLE]);
+   if (role > GTP_ROLE_SGSN)
+   return -EINVAL;
+   } else {
+   role = GTP_ROLE_GGSN;
+   }
 
if (!data[IFLA_GTP_FD0] || !data[IFLA_GTP_FD1])
return -EINVAL;
 
gtp = netdev_priv(dev);
 
+   gtp->role = role;
+
fd0 = nl

[PATCH net-next v3 0/2] GTP SGSN-side tunnels

2017-03-24 Thread Jonas Bonn
Changes since v2:

* Move #define of legacy netlink attribute into enum
* Added note to commit message about load-testing use-case
* Ack from Pablo

Jonas Bonn (2):
  gtp: rename SGSN netlink attribute
  gtp: support SGSN-side tunnels

 drivers/net/gtp.c| 63 +---
 include/uapi/linux/gtp.h |  3 ++-
 include/uapi/linux/if_link.h |  7 +
 3 files changed, 51 insertions(+), 22 deletions(-)

-- 
2.9.3



Re: [PATCH 1/1] gtp: support SGSN-side tunnels

2017-03-21 Thread Jonas Bonn

Hi Harald,

On 03/15/2017 05:39 PM, Harald Welte wrote:

Hi Jonas,

are you working on the review feedback that was provided back in early
February?  I think there were some comments like
* remove unrelated cosmetic change in comment
* change from FLAGS to a dedicated MODE netlink attribute
* add libgtpnl code and some usage information or even sample scripts

I would definitely like to see this move forward, particularly in order
to test the GGSN-side code.


Sorry for the delay in this.

I've sent, just now, revised patches to the kernel module.

I was going to send some libgtpnl patches but I noticed, when gathering 
these up, that you have already made most of the necessary changes on a 
new branch.  What you've got there is almost identical to what I've got.


Since you used the terminology "role" instead of "mode" in your libgtpnl 
branch, I made the corresponding change in the kernel module, too, so it 
now calls this role instead of mode.


Regards,
Jonas






Regards,
Harald





[PATCH v2 2/2] gtp: support SGSN-side tunnels

2017-03-21 Thread Jonas Bonn
The GTP-tunnel driver is explicitly GGSN-side as it searches for PDP
contexts based on the incoming packets _destination_ address.  If we
want to write an SGSN, then we want to be idenityfing PDP contexts
based on _source_ address.

This patch adds a "role" argument at GTP-link creation time to specify
whether we are on the GGSN or SGSN side of the tunnel; this flag is then
used to determine which part of the IP packet to use in determining
the PDP context.

Signed-off-by: Jonas Bonn <jo...@southpole.se>
---
 drivers/net/gtp.c| 41 +++--
 include/uapi/linux/if_link.h |  7 +++
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 3806be6..b54d1a3 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -72,6 +72,7 @@ struct gtp_dev {
struct net  *net;
struct net_device   *dev;
 
+   unsigned introle;
unsigned inthash_size;
struct hlist_head   *tid_hash;
struct hlist_head   *addr_hash;
@@ -150,8 +151,8 @@ static struct pdp_ctx *ipv4_pdp_find(struct gtp_dev *gtp, 
__be32 ms_addr)
return NULL;
 }
 
-static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
- unsigned int hdrlen)
+static bool gtp_check_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
+ unsigned int hdrlen, unsigned int role)
 {
struct iphdr *iph;
 
@@ -160,18 +161,22 @@ static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, 
struct pdp_ctx *pctx,
 
iph = (struct iphdr *)(skb->data + hdrlen);
 
-   return iph->saddr == pctx->ms_addr_ip4.s_addr;
+   if (role == GTP_ROLE_SGSN) {
+   return iph->daddr == pctx->ms_addr_ip4.s_addr;
+   } else {
+   return iph->saddr == pctx->ms_addr_ip4.s_addr;
+   }
 }
 
-/* Check if the inner IP source address in this packet is assigned to any
+/* Check if the inner IP address in this packet is assigned to any
  * existing mobile subscriber.
  */
-static bool gtp_check_src_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
-unsigned int hdrlen)
+static bool gtp_check_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
+unsigned int hdrlen, unsigned int role)
 {
switch (ntohs(skb->protocol)) {
case ETH_P_IP:
-   return gtp_check_src_ms_ipv4(skb, pctx, hdrlen);
+   return gtp_check_ms_ipv4(skb, pctx, hdrlen, role);
}
return false;
 }
@@ -205,7 +210,7 @@ static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb,
goto out_rcu;
}
 
-   if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+   if (!gtp_check_ms(skb, pctx, hdrlen, gtp->role)) {
netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
ret = -1;
goto out_rcu;
@@ -262,7 +267,7 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb,
goto out_rcu;
}
 
-   if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+   if (!gtp_check_ms(skb, pctx, hdrlen, gtp->role)) {
netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
ret = -1;
goto out_rcu;
@@ -491,7 +496,11 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct 
net_device *dev,
 * Prepend PDP header with TEI/TID from PDP ctx.
 */
iph = ip_hdr(skb);
-   pctx = ipv4_pdp_find(gtp, iph->daddr);
+   if (gtp->role == GTP_ROLE_SGSN) {
+   pctx = ipv4_pdp_find(gtp, iph->saddr);
+   } else {
+   pctx = ipv4_pdp_find(gtp, iph->daddr);
+   }
if (!pctx) {
netdev_dbg(dev, "no PDP ctx found for %pI4, skip\n",
   >daddr);
@@ -666,12 +675,23 @@ static int gtp_newlink(struct net *src_net, struct 
net_device *dev,
int hashsize, err, fd0, fd1;
struct gtp_dev *gtp;
struct gtp_net *gn;
+   unsigned int role;
+
+   if (data[IFLA_GTP_ROLE]) {
+   role = nla_get_u32(data[IFLA_GTP_ROLE]);
+   if (role > GTP_ROLE_SGSN)
+   return -EINVAL;
+   } else {
+   role = GTP_ROLE_GGSN;
+   }
 
if (!data[IFLA_GTP_FD0] || !data[IFLA_GTP_FD1])
return -EINVAL;
 
gtp = netdev_priv(dev);
 
+   gtp->role = role;
+
fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
 
@@ -723,6 +743,7 @@ static const struct nla_policy gtp_policy[IFLA_GTP_MAX + 1] 
= {
[IFLA_GTP_FD0]  = { .type = NLA_U32 },
[IFLA_GTP_FD1]  = { .type = NLA_U32 },
[IFLA_GTP_PDP_HASHSIZE] = { .type = NLA_U32 },
+   [IFLA_GTP_

[PATCH v2 1/2] gtp: rename SGSN netlink attribute

2017-03-21 Thread Jonas Bonn
This is a mostly cosmetic rename of the SGSN netlink attribute to
the GTP link.  The justification for this is that we will be making
the module support decapsulation of "downstream" SGSN packets, in
which case the netlink parameter actually refers to the upstream GGSN
peer.  Renaming the parameter makes the relationship clearer.

The legacy name is maintained as a define in the header file in order
to not break existing code.

Signed-off-by: Jonas Bonn <jo...@southpole.se>
---
 drivers/net/gtp.c| 22 +++---
 include/uapi/linux/gtp.h |  3 ++-
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 50349a9..3806be6 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -56,7 +56,7 @@ struct pdp_ctx {
u16 af;
 
struct in_addr  ms_addr_ip4;
-   struct in_addr  sgsn_addr_ip4;
+   struct in_addr  peer_addr_ip4;
 
atomic_ttx_seq;
struct rcu_head rcu_head;
@@ -522,17 +522,17 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct 
net_device *dev,
}
 
rt = ip4_route_output_gtp(sock_net(sk), , gtp->sock0->sk,
- pctx->sgsn_addr_ip4.s_addr);
+ pctx->peer_addr_ip4.s_addr);
if (IS_ERR(rt)) {
netdev_dbg(dev, "no route to SSGN %pI4\n",
-  >sgsn_addr_ip4.s_addr);
+  >peer_addr_ip4.s_addr);
dev->stats.tx_carrier_errors++;
goto err;
}
 
if (rt->dst.dev == dev) {
netdev_dbg(dev, "circular route to SSGN %pI4\n",
-  >sgsn_addr_ip4.s_addr);
+  >peer_addr_ip4.s_addr);
dev->stats.collisions++;
goto err_rt;
}
@@ -894,8 +894,8 @@ static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct 
genl_info *info)
 {
pctx->gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
pctx->af = AF_INET;
-   pctx->sgsn_addr_ip4.s_addr =
-   nla_get_be32(info->attrs[GTPA_SGSN_ADDRESS]);
+   pctx->peer_addr_ip4.s_addr =
+   nla_get_be32(info->attrs[GTPA_PEER_ADDRESS]);
pctx->ms_addr_ip4.s_addr =
nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
 
@@ -981,13 +981,13 @@ static int ipv4_pdp_add(struct net_device *dev, struct 
genl_info *info)
switch (pctx->gtp_version) {
case GTP_V0:
netdev_dbg(dev, "GTPv0-U: new PDP ctx id=%llx ssgn=%pI4 ms=%pI4 
(pdp=%p)\n",
-  pctx->u.v0.tid, >sgsn_addr_ip4,
+  pctx->u.v0.tid, >peer_addr_ip4,
   >ms_addr_ip4, pctx);
break;
case GTP_V1:
netdev_dbg(dev, "GTPv1-U: new PDP ctx id=%x/%x ssgn=%pI4 
ms=%pI4 (pdp=%p)\n",
   pctx->u.v1.i_tei, pctx->u.v1.o_tei,
-  >sgsn_addr_ip4, >ms_addr_ip4, pctx);
+  >peer_addr_ip4, >ms_addr_ip4, pctx);
break;
}
 
@@ -1001,7 +1001,7 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct 
genl_info *info)
 
if (!info->attrs[GTPA_VERSION] ||
!info->attrs[GTPA_LINK] ||
-   !info->attrs[GTPA_SGSN_ADDRESS] ||
+   !info->attrs[GTPA_PEER_ADDRESS] ||
!info->attrs[GTPA_MS_ADDRESS])
return -EINVAL;
 
@@ -1114,7 +1114,7 @@ static int gtp_genl_fill_info(struct sk_buff *skb, u32 
snd_portid, u32 snd_seq,
goto nlmsg_failure;
 
if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version) ||
-   nla_put_be32(skb, GTPA_SGSN_ADDRESS, pctx->sgsn_addr_ip4.s_addr) ||
+   nla_put_be32(skb, GTPA_PEER_ADDRESS, pctx->peer_addr_ip4.s_addr) ||
nla_put_be32(skb, GTPA_MS_ADDRESS, pctx->ms_addr_ip4.s_addr))
goto nla_put_failure;
 
@@ -1267,7 +1267,7 @@ static struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = {
[GTPA_LINK] = { .type = NLA_U32, },
[GTPA_VERSION]  = { .type = NLA_U32, },
[GTPA_TID]  = { .type = NLA_U64, },
-   [GTPA_SGSN_ADDRESS] = { .type = NLA_U32, },
+   [GTPA_PEER_ADDRESS] = { .type = NLA_U32, },
[GTPA_MS_ADDRESS]   = { .type = NLA_U32, },
[GTPA_FLOW] = { .type = NLA_U16, },
[GTPA_NET_NS_FD]= { .type = NLA_U32, },
diff --git a/include/uapi/linux/gtp.h b/include/uapi/linux/gtp.h
index 72a04a0..c51ebb0 100644
--- a/include/uapi/linux/gtp.h
+++ b/include/uapi/linux/gtp.h
@@ -19,7 +19,7 @@ enum gtp_attrs {
GTPA_LINK,
GTPA_VERSION,
GTPA_TID,   /* for GTPv0 only */
-

Re: [PATCH v2 1/2] gtp: rename SGSN netlink attribute

2017-03-21 Thread Jonas Bonn

On 03/21/2017 04:07 PM, Pablo Neira Ayuso wrote:

On Tue, Mar 21, 2017 at 04:04:29PM +0100, Jonas Bonn wrote:

diff --git a/include/uapi/linux/gtp.h b/include/uapi/linux/gtp.h
index 72a04a0..c51ebb0 100644
--- a/include/uapi/linux/gtp.h
+++ b/include/uapi/linux/gtp.h
@@ -19,7 +19,7 @@ enum gtp_attrs {
GTPA_LINK,
GTPA_VERSION,
GTPA_TID,   /* for GTPv0 only */
-   GTPA_SGSN_ADDRESS,
+   GTPA_PEER_ADDRESS,  /* Remote GSN peer, either SGSN or GGSN */

We need here:

#define GTPA_SGSN_ADDRESS GTPA_PEER_ADDRESS

for backward compatibility. Anything that is exposed through uapi
cannot be changed.


Yes... look a couple of lines further down...


GTPA_MS_ADDRESS,
GTPA_FLOW,
GTPA_NET_NS_FD,
@@ -29,5 +29,6 @@ enum gtp_attrs {
__GTPA_MAX,
  };
  #define GTPA_MAX (__GTPA_MAX + 1)
+#define GTPA_SGSN_ADDRESS GTPA_PEER_ADDRESS /* maintain legacy attr name */


... there it is! :)

/Jonas
  
  #endif /* _UAPI_LINUX_GTP_H_ */

--
2.9.3





Re: [PATCH 1/1] gtp: support SGSN-side tunnels

2017-02-06 Thread Jonas Bonn

Hi Pablo,

On 02/06/2017 12:08 PM, Pablo Neira Ayuso wrote:

Hi Jonas,

On Fri, Feb 03, 2017 at 10:12:31AM +0100, Jonas Bonn wrote:

The GTP-tunnel driver is explicitly GGSN-side as it searches for PDP
contexts based on the incoming packets _destination_ address.  If we
want to write an SGSN, then we want to be idenityfing PDP contexts
based on _source_ address.

This patch adds a "flags" argument at GTP-link creation time to specify
whether we are on the GGSN or SGSN side of the tunnel; this flag is then
used to determine which part of the IP packet to use in determining
the PDP context.

So far the implementation that I saw in osmocom relies on userspace code
to tunnel data from ME to the SSGN/SGW running on the base station.

The data we get from GGSN -> SGSN needs to be places into a SN-PDU (via
SNDCP) when sending it to the BTS, right? So I wonder how this can be
useful given that we would need to see real IP packets coming to the
SSGN that we tunnel into GTP.


Fair enough.  The use-case I am looking at involves PGW load-testing 
where the simulated load is generated locally on the SGSN so it _is_ 
seeing IP packets and the SNDCP is left out altogether.  Perhaps this is 
too pathological to warrant messing with the upstream driver... I don't 
know: the symmetry does not cost much even if it's of limited use.


Couldn't the SNDCP theoretically be a separate node and push IP packets 
to the SGSN, thus making this useful?  Perhaps it's a stretch...


/Jonas



[PATCH 1/1] gtp: support SGSN-side tunnels

2017-02-03 Thread Jonas Bonn
The GTP-tunnel driver is explicitly GGSN-side as it searches for PDP
contexts based on the incoming packets _destination_ address.  If we
want to write an SGSN, then we want to be idenityfing PDP contexts
based on _source_ address.

This patch adds a "flags" argument at GTP-link creation time to specify
whether we are on the GGSN or SGSN side of the tunnel; this flag is then
used to determine which part of the IP packet to use in determining
the PDP context.

Signed-off-by: Jonas Bonn <jo...@southpole.se>
---

 drivers/net/gtp.c| 43 ---
 include/uapi/linux/gtp.h |  2 +-
 include/uapi/linux/if_link.h |  5 +
 3 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 50349a9..1bbac69 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -72,6 +72,7 @@ struct gtp_dev {
struct net  *net;
struct net_device   *dev;
 
+   unsigned intflags;
unsigned inthash_size;
struct hlist_head   *tid_hash;
struct hlist_head   *addr_hash;
@@ -150,8 +151,8 @@ static struct pdp_ctx *ipv4_pdp_find(struct gtp_dev *gtp, 
__be32 ms_addr)
return NULL;
 }
 
-static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
- unsigned int hdrlen)
+static bool gtp_check_ms_ipv4(struct sk_buff *skb, struct pdp_ctx *pctx,
+ unsigned int hdrlen, unsigned int flags)
 {
struct iphdr *iph;
 
@@ -160,18 +161,22 @@ static bool gtp_check_src_ms_ipv4(struct sk_buff *skb, 
struct pdp_ctx *pctx,
 
iph = (struct iphdr *)(skb->data + hdrlen);
 
-   return iph->saddr == pctx->ms_addr_ip4.s_addr;
+   if (flags & GTP_FLAGS_SGSN) {
+   return iph->daddr == pctx->ms_addr_ip4.s_addr;
+   } else {
+   return iph->saddr == pctx->ms_addr_ip4.s_addr;
+   }
 }
 
-/* Check if the inner IP source address in this packet is assigned to any
+/* Check if the inner IP address in this packet is assigned to any
  * existing mobile subscriber.
  */
-static bool gtp_check_src_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
-unsigned int hdrlen)
+static bool gtp_check_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
+unsigned int hdrlen, unsigned int flags)
 {
switch (ntohs(skb->protocol)) {
case ETH_P_IP:
-   return gtp_check_src_ms_ipv4(skb, pctx, hdrlen);
+   return gtp_check_ms_ipv4(skb, pctx, hdrlen, flags);
}
return false;
 }
@@ -205,7 +210,7 @@ static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb,
goto out_rcu;
}
 
-   if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+   if (!gtp_check_ms(skb, pctx, hdrlen, gtp->flags)) {
netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
ret = -1;
goto out_rcu;
@@ -248,7 +253,7 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb,
if (gtp1->flags & GTP1_F_MASK)
hdrlen += 4;
 
-   /* Make sure the header is larger enough, including extensions. */
+   /* Make sure the header is large enough, including extensions. */
if (!pskb_may_pull(skb, hdrlen))
return -1;
 
@@ -262,7 +267,7 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct 
sk_buff *skb,
goto out_rcu;
}
 
-   if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+   if (!gtp_check_ms(skb, pctx, hdrlen, gtp->flags)) {
netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
ret = -1;
goto out_rcu;
@@ -491,7 +496,11 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct 
net_device *dev,
 * Prepend PDP header with TEI/TID from PDP ctx.
 */
iph = ip_hdr(skb);
-   pctx = ipv4_pdp_find(gtp, iph->daddr);
+   if (gtp->flags & GTP_FLAGS_SGSN) {
+   pctx = ipv4_pdp_find(gtp, iph->saddr);
+   } else {
+   pctx = ipv4_pdp_find(gtp, iph->daddr);
+   }
if (!pctx) {
netdev_dbg(dev, "no PDP ctx found for %pI4, skip\n",
   >daddr);
@@ -666,12 +675,23 @@ static int gtp_newlink(struct net *src_net, struct 
net_device *dev,
int hashsize, err, fd0, fd1;
struct gtp_dev *gtp;
struct gtp_net *gn;
+   unsigned int flags;
+
+   if (data[IFLA_GTP_FLAGS]) {
+   flags = nla_get_u32(data[IFLA_GTP_FLAGS]);
+   if (flags & ~GTP_FLAGS_MASK)
+   return -EINVAL;
+   } else {
+   flags = 0;
+   }
 
if (!data[IFLA_GTP_FD0] || !data[IFLA_GTP_FD1])
return -EINVAL;
 
  

[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/sk98lin/skge.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 20890e4..eedcbeb 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -5166,7 +5166,7 @@ err_out:
 #define skge_resume NULL
 #endif
 
-static struct pci_device_id skge_pci_tbl[] = {
+static PCI_DEVICE_TABLE(skge_pci_tbl) = {
 #ifdef SK98LIN_ALL_DEVICES
{ PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/starfire.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index c49214f..a67bac5 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -337,7 +337,7 @@ enum chipset {
CH_6915 = 0,
 };
 
-static struct pci_device_id starfire_pci_tbl[] = {
+static PCI_DEVICE_TABLE(starfire_pci_tbl) = {
{ 0x9004, 0x6915, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_6915 },
{ 0, }
 };
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/skfp/skfddi.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 7cf9b9f..2a8386b 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -150,7 +150,7 @@ extern void mac_drv_rx_mode(struct s_smc *smc, int mode);
 extern void mac_drv_clear_rx_queue(struct s_smc *smc);
 extern void enable_tx_irq(struct s_smc *smc, u_short queue);
 
-static struct pci_device_id skfddi_pci_tbl[] = {
+static PCI_DEVICE_TABLE(skfddi_pci_tbl) = {
{ PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP, PCI_ANY_ID, PCI_ANY_ID, },
{ } /* Terminating entry */
 };
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/wan/dscc4.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index c6f26e2..16d3a4c 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -2048,7 +2048,7 @@ static int __init dscc4_setup(char *str)
 __setup(dscc4.setup=, dscc4_setup);
 #endif
 
-static struct pci_device_id dscc4_pci_tbl[] = {
+static PCI_DEVICE_TABLE(dscc4_pci_tbl) = {
{ PCI_VENDOR_ID_SIEMENS, PCI_DEVICE_ID_SIEMENS_DSCC4,
PCI_ANY_ID, PCI_ANY_ID, },
{ 0,}
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/niu.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index e98ce1e..ab8148a 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -62,7 +62,7 @@ static void writeq(u64 val, void __iomem *reg)
 }
 #endif
 
-static struct pci_device_id niu_pci_tbl[] = {
+static PCI_DEVICE_TABLE(niu_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_SUN, 0xabcd)},
{}
 };
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/wan/lmc/lmc_main.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 6635ece..e85cfe7 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -82,7 +82,7 @@ static int lmc_first_load = 0;
 
 static int LMC_PKT_BUF_SZ = 1542;
 
-static struct pci_device_id lmc_pci_tbl[] = {
+static PCI_DEVICE_TABLE(lmc_pci_tbl) = {
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
  PCI_VENDOR_ID_LMC, PCI_ANY_ID },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/hamachi.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index b53f6b6..d8056e9 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1987,7 +1987,7 @@ static void __devexit hamachi_remove_one (struct pci_dev 
*pdev)
}
 }
 
-static struct pci_device_id hamachi_pci_tbl[] = {
+static PCI_DEVICE_TABLE(hamachi_pci_tbl) = {
{ 0x1318, 0x0911, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, }
 };
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/amd8111e.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 85f7276..a4ad2fb 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -113,7 +113,7 @@ MODULE_PARM_DESC(coalesce, Enable or Disable interrupt 
coalescing, 1: Enable, 0
 module_param_array(dynamic_ipg, bool, NULL, 0);
 MODULE_PARM_DESC(dynamic_ipg, Enable or Disable dynamic IPG, 1: Enable, 0: 
Disable);
 
-static struct pci_device_id amd8111e_pci_tbl[] = {
+static PCI_DEVICE_TABLE(amd8111e_pci_tbl) = {
 
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD8111E_7462,
 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/arcnet/com20020-pci.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/arcnet/com20020-pci.c 
b/drivers/net/arcnet/com20020-pci.c
index b8c0fa6..87ee0db 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -141,7 +141,7 @@ static void __devexit com20020pci_remove(struct pci_dev 
*pdev)
free_netdev(dev);
 }
 
-static struct pci_device_id com20020pci_id_table[] = {
+static PCI_DEVICE_TABLE(com20020pci_id_table) = {
{ 0x1571, 0xa001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0x1571, 0xa002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0x1571, 0xa003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


pci_device_id cleanups

2008-02-20 Thread Jonas Bonn

The PCI_DEVICE_TABLE patch I sent earlier doesn't necessarily make much sense 
by itself... here is a set of patches that apply this macro, in turn moving a 
lot of this data into __devinitconst which is discardable in certain 
situations.  Hopefully the benefit of this approach is a bit clearer now.

 drivers/net/3c59x.c   |2 +-
 drivers/net/amd8111e.c|2 +-
 drivers/net/arcnet/com20020-pci.c |2 +-
 drivers/net/defxx.c   |2 +-
 drivers/net/hamachi.c |2 +-
 drivers/net/niu.c |2 +-
 drivers/net/pasemi_mac.c  |2 +-
 drivers/net/sk98lin/skge.c|2 +-
 drivers/net/skfp/skfddi.c |2 +-
 drivers/net/starfire.c|2 +-
 drivers/net/sunhme.c  |2 +-
 drivers/net/tlan.c|2 +-
 drivers/net/wan/dscc4.c   |2 +-
 drivers/net/wan/lmc/lmc_main.c|2 +-
 include/linux/pci.h   |9 +
 15 files changed, 23 insertions(+), 14 deletions(-)


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/tlan.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 3af5b92..bea59c6 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -253,7 +253,7 @@ static struct board {
{ Compaq NetFlex-3/E, TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card 
*/
 };
 
-static struct pci_device_id tlan_pci_tbl[] = {
+static PCI_DEVICE_TABLE(tlan_pci_tbl) = {
{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/defxx.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index ddc30c4..84a3ce5 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -3630,7 +3630,7 @@ static int __devinit dfx_pci_register(struct pci_dev *,
  const struct pci_device_id *);
 static void __devexit dfx_pci_unregister(struct pci_dev *);
 
-static struct pci_device_id dfx_pci_table[] = {
+static PCI_DEVICE_TABLE(dfx_pci_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI) },
{ }
 };
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/sunhme.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index b4e7f30..beb0d27 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -3247,7 +3247,7 @@ static void __devexit happy_meal_pci_remove(struct 
pci_dev *pdev)
dev_set_drvdata(pdev-dev, NULL);
 }
 
-static struct pci_device_id happymeal_pci_ids[] = {
+static PCI_DEVICE_TABLE(happymeal_pci_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) },
{ } /* Terminating entry */
 };
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/pasemi_mac.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 2e39e02..069fa7c 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -1648,7 +1648,7 @@ static void __devexit pasemi_mac_remove(struct pci_dev 
*pdev)
free_netdev(netdev);
 }
 
-static struct pci_device_id pasemi_mac_pci_tbl[] = {
+static PCI_DEVICE_TABLE(pasemi_mac_pci_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) },
{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) },
{ },
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Add PCI_DEVICE_TABLE macro

2008-02-20 Thread Jonas Bonn
The definitions of struct pci_device_id arrays should generally follow
the same pattern across the entire kernel.  This macro defines this
array as const and puts it into the __devinitconst section.

Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 include/linux/pci.h |9 +
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/include/linux/pci.h b/include/linux/pci.h
index 87195b6..c7a91b1 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -389,6 +389,15 @@ struct pci_driver {
 #defineto_pci_driver(drv) container_of(drv, struct pci_driver, driver)
 
 /**
+ * PCI_DEVICE_TABLE - macro used to describe a pci device table
+ * @_table: device table name
+ *
+ * This macro is used to create a struct pci_device_id array (a device table) 
+ * in a generic manner.
+ */
+#define PCI_DEVICE_TABLE(_table) const struct pci_device_id _table[] 
__devinitconst
+
+/**
  * PCI_DEVICE - macro used to describe a specific pci device
  * @vend: the 16 bit PCI Vendor ID
  * @dev: the 16 bit PCI Device ID
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [net] use PCI_DEVICE_TABLE: makes struct pci_device_id array const and adds section attribute __devinitconst

2008-02-20 Thread Jonas Bonn
Signed-off-by: Jonas Bonn [EMAIL PROTECTED]
---
 drivers/net/3c59x.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 6f8e7d4..d2045d4 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -372,7 +372,7 @@ static struct vortex_chip_info {
 };
 
 
-static struct pci_device_id vortex_pci_tbl[] = {
+static PCI_DEVICE_TABLE(vortex_pci_tbl) = {
{ 0x10B7, 0x5900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C590 },
{ 0x10B7, 0x5920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C592 },
{ 0x10B7, 0x5970, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C597 },
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: pci_device_id cleanups

2008-02-20 Thread Jonas Bonn

Sam Ravnborg wrote:

On Wed, Feb 20, 2008 at 01:53:36PM +0100, Jonas Bonn wrote:

The PCI_DEVICE_TABLE patch I sent earlier doesn't necessarily make
much sense by itself... here is a set of patches that apply
this macro, in turn moving a lot of this data into __devinitconst
which is discardable in certain situations.
Hopefully the benefit of this approach is a bit clearer now.

[shorter lines please..]


Sorry...



Can you please confirm that this does not break powerpc (64 bit)
as they have troubles with the constification..


I do not have access to any PowerPC machine... Olof Johansson built the 
tree I posted earlier on PowerPC; there's nothing really new here except 
the wrapping of the definition in a macro.


But of course, it would great if someone could confirm this...



Sam



--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: PowerPC toolchain for x86 [Was: pci_device_id cleanups]

2008-02-20 Thread Jonas Bonn



Sam Ravnborg wrote:

On Wed, Feb 20, 2008 at 02:27:19PM +0100, Jonas Bonn wrote:

Sam Ravnborg wrote:

On Wed, Feb 20, 2008 at 01:53:36PM +0100, Jonas Bonn wrote:

The PCI_DEVICE_TABLE patch I sent earlier doesn't necessarily make
much sense by itself... here is a set of patches that apply
this macro, in turn moving a lot of this data into __devinitconst
which is discardable in certain situations.
Hopefully the benefit of this approach is a bit clearer now.

[shorter lines please..]

Sorry...


Can you please confirm that this does not break powerpc (64 bit)
as they have troubles with the constification..
I do not have access to any PowerPC machine... Olof Johansson built the 
tree I posted earlier on PowerPC; there's nothing really new here except 
the wrapping of the definition in a macro.

And you added const and a specific section.


No... once the macro is expanded the code is exactly the same as that 
which built cleanly on powerpc previously (which Olof, built, I mean)... 
nothing new here.



Exactly what could break on PowerPC.

To do the build break check is easy.
Google for crosstool and build your own powerpc toolchain.



Thanks... I'll throw together a cross compiler and see what I can do.

/Jonas


Andrew has something precompiled somewhere but I lost the link.


Sam



--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [SIS190] Constify data marked as __devinitdata

2008-01-30 Thread Jonas Bonn
This fixes build error as gcc complains about a section type conflict
due to the const __devinitdata in sis190_get_mac_addr_from_apc().
---
 drivers/net/sis190.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index b570402..e48e4ad 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -326,7 +326,7 @@ static const struct {
{ SiS 191 PCI Gigabit Ethernet adapter },
 };
 
-static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
+static const struct pci_device_id sis190_pci_tbl[] __devinitdata = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
{ 0, },
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [SIS190] Use _devinitconst for const data

2008-01-30 Thread Jonas Bonn
This fixes build error as gcc complains about a section type conflict
due to the mixing of const and non-const data in same section.
---
 drivers/net/sis190.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index b570402..f84c02e 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -326,7 +326,7 @@ static const struct {
{ SiS 191 PCI Gigabit Ethernet adapter },
 };
 
-static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
+static struct pci_device_id sis190_pci_tbl[] __devinitconst = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
{ 0, },
@@ -1556,7 +1556,7 @@ static int __devinit 
sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
 static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
  struct net_device *dev)
 {
-   static const u16 __devinitdata ids[] = { 0x0965, 0x0966, 0x0968 };
+   static u16 __devinitconst ids[] = { 0x0965, 0x0966, 0x0968 };
struct sis190_private *tp = netdev_priv(dev);
struct pci_dev *isa_bridge;
u8 reg, tmp8;
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [SIS190] Constify data marked as __devinitdata

2008-01-30 Thread Jonas Bonn


instead? Because AFAIK, const *and* __sectionmarker does not mix.



You're right... it's documented in linux/init.h that const and 
__sectionmarker do not mix.  The compile error is due to the use of 
const and __section marker in the function sis190_get_mac_addr_from_apc().


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [SIS190] Use __devinitconst for const devinit data

2008-01-30 Thread Jonas Bonn
Mixing const and __section was previously not allowed.  New __devinitconst tag
allows this.

This fixes a gcc section type mismatch build error.
---
 drivers/net/sis190.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index b570402..d3126a9 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -326,7 +326,7 @@ static const struct {
{ SiS 191 PCI Gigabit Ethernet adapter },
 };
 
-static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
+static const struct pci_device_id sis190_pci_tbl[] __devinitconst = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
{ 0, },
@@ -1556,7 +1556,7 @@ static int __devinit 
sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
 static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
  struct net_device *dev)
 {
-   static const u16 __devinitdata ids[] = { 0x0965, 0x0966, 0x0968 };
+   static const u16 __devinitconst ids[] = { 0x0965, 0x0966, 0x0968 };
struct sis190_private *tp = netdev_priv(dev);
struct pci_dev *isa_bridge;
u8 reg, tmp8;
-- 
1.5.3.8


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html