osmith has submitted this change. ( https://gerrit.osmocom.org/c/libgtpnl/+/35988?usp=email )
Change subject: gtp: add flags to gtp_tunnel object ......................................................................
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(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved pespin: Looks good to me, but someone else must approve
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++])); }