Commit a51c328d authored by Po Liu's avatar Po Liu Committed by David S. Miller
Browse files

net: qos: introduce a gate control flow action



Introduce a ingress frame gate control flow action.
Tc gate action does the work like this:
Assume there is a gate allow specified ingress frames can be passed at
specific time slot, and be dropped at specific time slot. Tc filter
chooses the ingress frames, and tc gate action would specify what slot
does these frames can be passed to device and what time slot would be
dropped.
Tc gate action would provide an entry list to tell how much time gate
keep open and how much time gate keep state close. Gate action also
assign a start time to tell when the entry list start. Then driver would
repeat the gate entry list cyclically.
For the software simulation, gate action requires the user assign a time
clock type.

Below is the setting example in user space. Tc filter a stream source ip
address is 192.168.0.20 and gate action own two time slots. One is last
200ms gate open let frame pass another is last 100ms gate close let
frames dropped. When the ingress frames have reach total frames over
8000000 bytes, the excessive frames will be dropped in that 200000000ns
time slot.

> tc qdisc add dev eth0 ingress

> tc filter add dev eth0 parent ffff: protocol ip \
	   flower src_ip 192.168.0.20 \
	   action gate index 2 clockid CLOCK_TAI \
	   sched-entry open 200000000 -1 8000000 \
	   sched-entry close 100000000 -1 -1

> tc chain del dev eth0 ingress chain 0

"sched-entry" follow the name taprio style. Gate state is
"open"/"close". Follow with period nanosecond. Then next item is internal
priority value means which ingress queue should put. "-1" means
wildcard. The last value optional specifies the maximum number of
MSDU octets that are permitted to pass the gate during the specified
time interval.
Base-time is not set will be 0 as default, as result start time would
be ((N + 1) * cycletime) which is the minimal of future time.

Below example shows filtering a stream with destination mac address is
10:00:80:00:00:00 and ip type is ICMP, follow the action gate. The gate
action would run with one close time slot which means always keep close.
The time cycle is total 200000000ns. The base-time would calculate by:

 1357000000000 + (N + 1) * cycletime

When the total value is the future time, it will be the start time.
The cycletime here would be 200000000ns for this case.

> tc filter add dev eth0 parent ffff:  protocol ip \
	   flower skip_hw ip_proto icmp dst_mac 10:00:80:00:00:00 \
	   action gate index 12 base-time 1357000000000 \
	   sched-entry close 200000000 -1 -1 \
	   clockid CLOCK_TAI

Signed-off-by: default avatarPo Liu <Po.Liu@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eb236c29
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright 2020 NXP */

#ifndef __NET_TC_GATE_H
#define __NET_TC_GATE_H

#include <net/act_api.h>
#include <linux/tc_act/tc_gate.h>

struct tcfg_gate_entry {
	int			index;
	u8			gate_state;
	u32			interval;
	s32			ipv;
	s32			maxoctets;
	struct list_head	list;
};

struct tcf_gate_params {
	s32			tcfg_priority;
	u64			tcfg_basetime;
	u64			tcfg_cycletime;
	u64			tcfg_cycletime_ext;
	u32			tcfg_flags;
	s32			tcfg_clockid;
	size_t			num_entries;
	struct list_head	entries;
};

#define GATE_ACT_GATE_OPEN	BIT(0)
#define GATE_ACT_PENDING	BIT(1)

struct tcf_gate {
	struct tc_action	common;
	struct tcf_gate_params	param;
	u8			current_gate_status;
	ktime_t			current_close_time;
	u32			current_entry_octets;
	s32			current_max_octets;
	struct tcfg_gate_entry	*next_entry;
	struct hrtimer		hitimer;
	enum tk_offsets		tk_offset;
};

#define to_gate(a) ((struct tcf_gate *)a)

#endif
+1 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ enum tca_id {
	TCA_ID_CTINFO,
	TCA_ID_MPLS,
	TCA_ID_CT,
	TCA_ID_GATE,
	/* other actions go here */
	__TCA_ID_MAX = 255
};
+47 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/* Copyright 2020 NXP */

#ifndef __LINUX_TC_GATE_H
#define __LINUX_TC_GATE_H

#include <linux/pkt_cls.h>

struct tc_gate {
	tc_gen;
};

enum {
	TCA_GATE_ENTRY_UNSPEC,
	TCA_GATE_ENTRY_INDEX,
	TCA_GATE_ENTRY_GATE,
	TCA_GATE_ENTRY_INTERVAL,
	TCA_GATE_ENTRY_IPV,
	TCA_GATE_ENTRY_MAX_OCTETS,
	__TCA_GATE_ENTRY_MAX,
};
#define TCA_GATE_ENTRY_MAX (__TCA_GATE_ENTRY_MAX - 1)

enum {
	TCA_GATE_ONE_ENTRY_UNSPEC,
	TCA_GATE_ONE_ENTRY,
	__TCA_GATE_ONE_ENTRY_MAX,
};
#define TCA_GATE_ONE_ENTRY_MAX (__TCA_GATE_ONE_ENTRY_MAX - 1)

enum {
	TCA_GATE_UNSPEC,
	TCA_GATE_TM,
	TCA_GATE_PARMS,
	TCA_GATE_PAD,
	TCA_GATE_PRIORITY,
	TCA_GATE_ENTRY_LIST,
	TCA_GATE_BASE_TIME,
	TCA_GATE_CYCLE_TIME,
	TCA_GATE_CYCLE_TIME_EXT,
	TCA_GATE_FLAGS,
	TCA_GATE_CLOCKID,
	__TCA_GATE_MAX,
};
#define TCA_GATE_MAX (__TCA_GATE_MAX - 1)

#endif
+12 −0
Original line number Diff line number Diff line
@@ -981,6 +981,18 @@ config NET_ACT_CT
	  To compile this code as a module, choose M here: the
	  module will be called act_ct.

config NET_ACT_GATE
	tristate "Frame gate entry list control tc action"
	depends on NET_CLS_ACT
	help
	  Say Y here to allow to control the ingress flow to be passed at
	  specific time slot and be dropped at other specific time slot by
	  the gate entry list.

	  If unsure, say N.
	  To compile this code as a module, choose M here: the
	  module will be called act_gate.

config NET_IFE_SKBMARK
	tristate "Support to encoding decoding skb mark on IFE action"
	depends on NET_ACT_IFE
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ obj-$(CONFIG_NET_IFE_SKBPRIO) += act_meta_skbprio.o
obj-$(CONFIG_NET_IFE_SKBTCINDEX)	+= act_meta_skbtcindex.o
obj-$(CONFIG_NET_ACT_TUNNEL_KEY)+= act_tunnel_key.o
obj-$(CONFIG_NET_ACT_CT)	+= act_ct.o
obj-$(CONFIG_NET_ACT_GATE)	+= act_gate.o
obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o
obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o
obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o
Loading