osmith submitted this change.

View Change


Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved pespin: Looks good to me, but someone else must approve
gtp: add flags to gtp_tunnel object

Flags tells us what fields have been set in this object.

This is required by

./gtp-tunnel del

otherwise, build helper function adds the MS/UE address and kernel reports
ENOENT, and tunnel identifier is ignored.

Update gtp-tunnel tool to set flowid to zero in the GTP version 0 case,
otherwise kernel reports EINVAL since now this flag is not ever set.

Change-Id: I66677ab2d4de2c459ed9987c465fce6f059d6d93
---
M src/gtp-genl.c
M src/gtp.c
M src/internal.h
M tools/gtp-tunnel.c
4 files changed, 93 insertions(+), 32 deletions(-)

diff --git a/src/gtp-genl.c b/src/gtp-genl.c
index 447e1ea..3b7c3ef 100644
--- a/src/gtp-genl.c
+++ b/src/gtp-genl.c
@@ -44,42 +44,55 @@

static void gtp_build_payload(struct nlmsghdr *nlh, struct gtp_tunnel *t)
{
- mnl_attr_put_u8(nlh, GTPA_FAMILY, t->ms_addr.family);
- mnl_attr_put_u32(nlh, GTPA_VERSION, t->gtp_version);
- if (t->ifns >= 0)
+ if (t->flags & GTP_TUN_FAMILY)
+ mnl_attr_put_u8(nlh, GTPA_FAMILY, t->ms_addr.family);
+ if (t->flags & GTP_TUN_VERSION)
+ mnl_attr_put_u32(nlh, GTPA_VERSION, t->gtp_version);
+ if (t->flags & GTP_TUN_IFNS)
mnl_attr_put_u32(nlh, GTPA_NET_NS_FD, t->ifns);
- mnl_attr_put_u32(nlh, GTPA_LINK, t->ifidx);
+ if (t->flags & GTP_TUN_IFIDX)
+ mnl_attr_put_u32(nlh, GTPA_LINK, t->ifidx);

- switch (t->ms_addr.family) {
- case AF_INET:
- mnl_attr_put_u32(nlh, GTPA_MS_ADDRESS, t->ms_addr.ip4.s_addr);
- break;
- case AF_INET6:
- mnl_attr_put(nlh, GTPA_MS_ADDR6, sizeof(t->ms_addr.ip6), &t->ms_addr.ip6);
- break;
- default:
- /* No addr is set when deleting a tunnel */
- break;
+ if (t->flags & GTP_TUN_MS_ADDR) {
+ switch (t->ms_addr.family) {
+ case AF_INET:
+ mnl_attr_put_u32(nlh, GTPA_MS_ADDRESS, t->ms_addr.ip4.s_addr);
+ break;
+ case AF_INET6:
+ mnl_attr_put(nlh, GTPA_MS_ADDR6, sizeof(t->ms_addr.ip6), &t->ms_addr.ip6);
+ break;
+ default:
+ /* No addr is set when deleting a tunnel */
+ break;
+ }
}

- switch (t->sgsn_addr.family) {
- case AF_INET:
- mnl_attr_put_u32(nlh, GTPA_PEER_ADDRESS, t->sgsn_addr.ip4.s_addr);
- break;
- case AF_INET6:
- mnl_attr_put(nlh, GTPA_PEER_ADDR6, sizeof(t->sgsn_addr.ip6), &t->sgsn_addr.ip6);
- break;
- default:
- /* No addr is set when deleting a tunnel */
- break;
+ if (t->flags & GTP_TUN_SGSN_ADDR) {
+ switch (t->sgsn_addr.family) {
+ case AF_INET:
+ mnl_attr_put_u32(nlh, GTPA_PEER_ADDRESS, t->sgsn_addr.ip4.s_addr);
+ break;
+ case AF_INET6:
+ mnl_attr_put(nlh, GTPA_PEER_ADDR6, sizeof(t->sgsn_addr.ip6), &t->sgsn_addr.ip6);
+ break;
+ default:
+ /* No addr is set when deleting a tunnel */
+ break;
+ }
}

- if (t->gtp_version == GTP_V0) {
- mnl_attr_put_u64(nlh, GTPA_TID, t->u.v0.tid);
- mnl_attr_put_u16(nlh, GTPA_FLOW, t->u.v0.flowid);
- } else if (t->gtp_version == GTP_V1) {
- mnl_attr_put_u32(nlh, GTPA_I_TEI, t->u.v1.i_tei);
- mnl_attr_put_u32(nlh, GTPA_O_TEI, t->u.v1.o_tei);
+ if (t->flags & GTP_TUN_VERSION) {
+ if (t->gtp_version == GTP_V0) {
+ if (t->flags & GTP_TUN_V0_TID)
+ mnl_attr_put_u64(nlh, GTPA_TID, t->u.v0.tid);
+ if (t->flags & GTP_TUN_V0_FLOWID)
+ mnl_attr_put_u16(nlh, GTPA_FLOW, t->u.v0.flowid);
+ } else if (t->gtp_version == GTP_V1) {
+ if (t->flags & GTP_TUN_V1_I_TEI)
+ mnl_attr_put_u32(nlh, GTPA_I_TEI, t->u.v1.i_tei);
+ if (t->flags & GTP_TUN_V1_O_TEI)
+ mnl_attr_put_u32(nlh, GTPA_O_TEI, t->u.v1.o_tei);
+ }
}
}

diff --git a/src/gtp.c b/src/gtp.c
index 0c378c4..af216f7 100644
--- a/src/gtp.c
+++ b/src/gtp.c
@@ -49,18 +49,21 @@
void gtp_tunnel_set_ifns(struct gtp_tunnel *t, int ifns)
{
t->ifns = ifns;
+ t->flags |= GTP_TUN_IFNS;
}
EXPORT_SYMBOL(gtp_tunnel_set_ifns);

void gtp_tunnel_set_ifidx(struct gtp_tunnel *t, uint32_t ifidx)
{
t->ifidx = ifidx;
+ t->flags |= GTP_TUN_IFIDX;
}
EXPORT_SYMBOL(gtp_tunnel_set_ifidx);

void gtp_tunnel_set_family(struct gtp_tunnel *t, uint16_t family)
{
t->ms_addr.family = family;
+ t->flags |= GTP_TUN_FAMILY;
}
EXPORT_SYMBOL(gtp_tunnel_set_family);

@@ -68,6 +71,7 @@
{
t->ms_addr.family = AF_INET;
t->ms_addr.ip4 = *ms_addr;
+ t->flags |= GTP_TUN_FAMILY | GTP_TUN_MS_ADDR;
}
EXPORT_SYMBOL(gtp_tunnel_set_ms_ip4);

@@ -75,6 +79,7 @@
{
t->sgsn_addr.family = AF_INET;
t->sgsn_addr.ip4 = *sgsn_addr;
+ t->flags |= GTP_TUN_SGSN_ADDR;
}
EXPORT_SYMBOL(gtp_tunnel_set_sgsn_ip4);

@@ -82,6 +87,7 @@
{
t->ms_addr.family = AF_INET6;
t->ms_addr.ip6 = *ms_addr;
+ t->flags |= GTP_TUN_FAMILY | GTP_TUN_MS_ADDR;
}
EXPORT_SYMBOL(gtp_tunnel_set_ms_ip6);

@@ -89,36 +95,42 @@
{
t->sgsn_addr.family = AF_INET6;
t->sgsn_addr.ip6 = *sgsn_addr;
+ t->flags |= GTP_TUN_SGSN_ADDR;
}
EXPORT_SYMBOL(gtp_tunnel_set_sgsn_ip6);

void gtp_tunnel_set_version(struct gtp_tunnel *t, uint32_t version)
{
t->gtp_version = version;
+ t->flags |= GTP_TUN_VERSION;
}
EXPORT_SYMBOL(gtp_tunnel_set_version);

void gtp_tunnel_set_tid(struct gtp_tunnel *t, uint64_t tid)
{
t->u.v0.tid = tid;
+ t->flags |= GTP_TUN_V0_TID;
}
EXPORT_SYMBOL(gtp_tunnel_set_tid);

void gtp_tunnel_set_flowid(struct gtp_tunnel *t, uint16_t flowid)
{
t->u.v0.flowid = flowid;
+ t->flags |= GTP_TUN_V0_FLOWID;
}
EXPORT_SYMBOL(gtp_tunnel_set_flowid);

void gtp_tunnel_set_i_tei(struct gtp_tunnel *t, uint32_t i_tei)
{
t->u.v1.i_tei = i_tei;
+ t->flags |= GTP_TUN_V1_I_TEI;
}
EXPORT_SYMBOL(gtp_tunnel_set_i_tei);

void gtp_tunnel_set_o_tei(struct gtp_tunnel *t, uint32_t o_tei)
{
t->u.v1.o_tei = o_tei;
+ t->flags |= GTP_TUN_V1_O_TEI;
}
EXPORT_SYMBOL(gtp_tunnel_set_o_tei);

diff --git a/src/internal.h b/src/internal.h
index ce8a683..1433621 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -20,6 +20,19 @@
};
};

+enum {
+ GTP_TUN_IFNS = (1 << 0),
+ GTP_TUN_IFIDX = (1 << 1),
+ GTP_TUN_FAMILY = (1 << 2),
+ GTP_TUN_MS_ADDR = (1 << 3),
+ GTP_TUN_SGSN_ADDR = (1 << 4),
+ GTP_TUN_VERSION = (1 << 5),
+ GTP_TUN_V0_TID = (1 << 6),
+ GTP_TUN_V0_FLOWID = (1 << 7),
+ GTP_TUN_V1_I_TEI = (1 << 8),
+ GTP_TUN_V1_O_TEI = (1 << 9),
+};
+
struct gtp_tunnel {
int ifns;
uint32_t ifidx;
@@ -36,6 +49,7 @@
uint32_t o_tei;
} v1;
} u;
+ uint32_t flags;
};

#endif
diff --git a/tools/gtp-tunnel.c b/tools/gtp-tunnel.c
index 1b8a7a0..8c8f95f 100644
--- a/tools/gtp-tunnel.c
+++ b/tools/gtp-tunnel.c
@@ -109,9 +109,10 @@

optidx++;

- if (gtp_version == GTP_V0)
+ if (gtp_version == GTP_V0) {
gtp_tunnel_set_tid(t, atoi(argv[optidx++]));
- else if (gtp_version == GTP_V1) {
+ gtp_tunnel_set_flowid(t, 0);
+ } else if (gtp_version == GTP_V1) {
gtp_tunnel_set_i_tei(t, atoi(argv[optidx++]));
gtp_tunnel_set_o_tei(t, atoi(argv[optidx++]));
}

To view, visit change 35988. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: libgtpnl
Gerrit-Branch: master
Gerrit-Change-Id: I66677ab2d4de2c459ed9987c465fce6f059d6d93
Gerrit-Change-Number: 35988
Gerrit-PatchSet: 2
Gerrit-Owner: osmith <osmith@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: osmith <osmith@sysmocom.de>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>
Gerrit-MessageType: merged