Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drop packets when the QER ULDL gate is closed #99

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/qer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
#include "dev.h"
#include "pdr.h"

// TS 29.244 8.2.7 Gate Status
// 0 OPEN, 1 CLOSED
// 2, 3 For future use. Shall not be sent.
// If received, shall be interpreted as the value "1"
#define QER_UL_GATE_CLOSE (0x1 << 2)
#define QER_DL_GATE_CLOSE (0x1 << 0)

struct qer {
struct hlist_node hlist_id;
u64 seid;
Expand Down
5 changes: 4 additions & 1 deletion src/genl/genl_qer.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "genl_qer.h"
#include "qer.h"
#include "hash.h"
#include "log.h"

#include <linux/rculist.h>
#include <net/netns/generic.h>
Expand Down Expand Up @@ -309,8 +310,10 @@ static int qer_fill(struct qer *qer, struct gtp5g_dev *gtp, struct genl_info *in
else
qer->seid = 0;

if (info->attrs[GTP5G_QER_GATE])
if (info->attrs[GTP5G_QER_GATE]) {
qer->ul_dl_gate = nla_get_u8(info->attrs[GTP5G_QER_GATE]);
GTP5G_INF(NULL, "QER Gate Status (%x)", qer->ul_dl_gate);
}

/* MBR */
if (info->attrs[GTP5G_QER_MBR] &&
Expand Down
12 changes: 11 additions & 1 deletion src/gtpu/encap.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ static int gtp5g_rx(struct pdr *pdr, struct sk_buff *skb,
{
int rt = -1;
struct far *far = rcu_dereference(pdr->far);
// struct qer *qer = rcu_dereference(pdr->qer);
struct qer __rcu *qer_with_rate = rcu_dereference(pdr->qer_with_rate);

if (!far) {
GTP5G_ERR(pdr->dev, "FAR not exists for PDR(%u)\n", pdr->id);
Expand All @@ -716,6 +716,10 @@ static int gtp5g_rx(struct pdr *pdr, struct sk_buff *skb,
rt = gtp5g_drop_skb_encap(skb, pdr->dev, pdr);
break;
case FAR_ACTION_FORW:
if (qer_with_rate->ul_dl_gate & QER_UL_GATE_CLOSE) {
GTP5G_TRC(pdr->dev, "QER UL gate is closed, drop the packet");
return PKT_DROPPED;
}
rt = gtp5g_fwd_skb_encap(skb, pdr->dev, hdrlen, pdr, far);
break;
case FAR_ACTION_BUFF:
Expand Down Expand Up @@ -991,6 +995,7 @@ int gtp5g_handle_skb_ipv4(struct sk_buff *skb, struct net_device *dev,
struct far *far;
//struct gtp5g_qer *qer;
struct iphdr *iph;
struct qer __rcu *qer_with_rate = NULL;

/* Read the IP destination address and resolve the PDR.
* Prepend PDR header with TEI/TID from PDR.
Expand All @@ -1014,6 +1019,7 @@ int gtp5g_handle_skb_ipv4(struct sk_buff *skb, struct net_device *dev,
// __func__, __LINE__, qer->id, qer->qfi);
//}

qer_with_rate = rcu_dereference(pdr->qer_with_rate);
far = rcu_dereference(pdr->far);
if (far) {
// One and only one of the DROP, FORW and BUFF flags shall be set to 1.
Expand All @@ -1023,6 +1029,10 @@ int gtp5g_handle_skb_ipv4(struct sk_buff *skb, struct net_device *dev,
case FAR_ACTION_DROP:
return gtp5g_drop_skb_ipv4(skb, dev, pdr);
case FAR_ACTION_FORW:
if (qer_with_rate->ul_dl_gate & QER_DL_GATE_CLOSE) {
GTP5G_TRC(pdr->dev, "QER DL gate is closed, drop the packet");
return PKT_DROPPED;
}
return gtp5g_fwd_skb_ipv4(skb, dev, pktinfo, pdr, far);
case FAR_ACTION_BUFF:
return gtp5g_buf_skb_ipv4(skb, dev, pdr, far);
Expand Down