* [iproute2 PATCH] tc: flower: Classify packets based port ranges
@ 2018-10-12 13:54 Amritha Nambiar
2018-10-18 12:21 ` Jiri Pirko
0 siblings, 1 reply; 3+ messages in thread
From: Amritha Nambiar @ 2018-10-12 13:54 UTC (permalink / raw)
To: stephen, netdev
Cc: jakub.kicinski, amritha.nambiar, sridhar.samudrala, jhs,
xiyou.wangcong, jiri
Added support for filtering based on port ranges.
Example:
1. Match on a port range:
-------------------------
$ tc filter add dev enp4s0 protocol ip parent ffff:\
prio 1 flower ip_proto tcp dst_port range 20-30 skip_hw\
action drop
$ tc -s filter show dev enp4s0 parent ffff:
filter protocol ip pref 1 flower chain 0
filter protocol ip pref 1 flower chain 0 handle 0x1
eth_type ipv4
ip_proto tcp
dst_port_min 20
dst_port_max 30
skip_hw
not_in_hw
action order 1: gact action drop
random type none pass val 0
index 1 ref 1 bind 1 installed 181 sec used 5 sec
Action statistics:
Sent 460 bytes 10 pkt (dropped 10, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
2. Match on IP address and port range:
--------------------------------------
$ tc filter add dev enp4s0 protocol ip parent ffff:\
prio 1 flower dst_ip 192.168.1.1 ip_proto tcp dst_port range 100-200\
skip_hw action drop
$ tc -s filter show dev enp4s0 parent ffff:
filter protocol ip pref 1 flower chain 0 handle 0x2
eth_type ipv4
ip_proto tcp
dst_ip 192.168.1.1
dst_port_min 100
dst_port_max 200
skip_hw
not_in_hw
action order 1: gact action drop
random type none pass val 0
index 2 ref 1 bind 1 installed 28 sec used 6 sec
Action statistics:
Sent 460 bytes 10 pkt (dropped 10, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
---
include/uapi/linux/pkt_cls.h | 5 +
tc/f_flower.c | 145 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 140 insertions(+), 10 deletions(-)
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index be382fb..3d9727f 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -405,6 +405,11 @@ enum {
TCA_FLOWER_KEY_UDP_SRC, /* be16 */
TCA_FLOWER_KEY_UDP_DST, /* be16 */
+ TCA_FLOWER_KEY_PORT_SRC_MIN, /* be16 */
+ TCA_FLOWER_KEY_PORT_SRC_MAX, /* be16 */
+ TCA_FLOWER_KEY_PORT_DST_MIN, /* be16 */
+ TCA_FLOWER_KEY_PORT_DST_MAX, /* be16 */
+
TCA_FLOWER_FLAGS,
TCA_FLOWER_KEY_VLAN_ID, /* be16 */
TCA_FLOWER_KEY_VLAN_PRIO, /* u8 */
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 59e5f57..1a7bc80 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -33,6 +33,11 @@ enum flower_endpoint {
FLOWER_ENDPOINT_DST
};
+struct range_type {
+ __be16 min_port_type;
+ __be16 max_port_type;
+};
+
enum flower_icmp_field {
FLOWER_ICMP_FIELD_TYPE,
FLOWER_ICMP_FIELD_CODE
@@ -493,6 +498,64 @@ static int flower_parse_port(char *str, __u8 ip_proto,
return 0;
}
+static int flower_port_range_attr_type(__u8 ip_proto, enum flower_endpoint type,
+ struct range_type *range)
+{
+ if (ip_proto == IPPROTO_TCP || ip_proto == IPPROTO_UDP ||
+ ip_proto == IPPROTO_SCTP) {
+ if (type == FLOWER_ENDPOINT_SRC) {
+ range->min_port_type = TCA_FLOWER_KEY_PORT_SRC_MIN;
+ range->max_port_type = TCA_FLOWER_KEY_PORT_SRC_MAX;
+ } else {
+ range->min_port_type = TCA_FLOWER_KEY_PORT_DST_MIN;
+ range->max_port_type = TCA_FLOWER_KEY_PORT_DST_MAX;
+ }
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int flower_parse_port_range(__be16 *min, __be16 *max, __u8 ip_proto,
+ enum flower_endpoint endpoint,
+ struct nlmsghdr *n)
+{
+ struct range_type range;
+
+ flower_port_range_attr_type(ip_proto, endpoint, &range);
+ addattr16(n, MAX_MSG, range.min_port_type, *min);
+ addattr16(n, MAX_MSG, range.max_port_type, *max);
+
+ return 0;
+}
+
+static int get_range(__be16 *min, __be16 *max, char *argv)
+{
+ char *r;
+
+ r = strchr(argv, '-');
+ if (r) {
+ *r = '\0';
+ if (get_be16(min, argv, 10)) {
+ fprintf(stderr, "invalid min range\n");
+ return -1;
+ }
+ if (get_be16(max, r + 1, 10)) {
+ fprintf(stderr, "invalid max range\n");
+ return -1;
+ }
+ if (htons(*max) <= htons(*min)) {
+ fprintf(stderr, "max value should be greater than min value\n");
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "Illegal range format\n");
+ return -1;
+ }
+ return 0;
+}
+
#define TCP_FLAGS_MAX_MASK 0xfff
static int flower_parse_tcp_flags(char *str, int flags_type, int mask_type,
@@ -887,20 +950,54 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
return -1;
}
} else if (matches(*argv, "dst_port") == 0) {
+ __be16 min, max;
+
NEXT_ARG();
- ret = flower_parse_port(*argv, ip_proto,
- FLOWER_ENDPOINT_DST, n);
- if (ret < 0) {
- fprintf(stderr, "Illegal \"dst_port\"\n");
- return -1;
+ if (matches(*argv, "range") == 0) {
+ NEXT_ARG();
+ ret = get_range(&min, &max, *argv);
+ if (ret < 0)
+ return -1;
+ ret = flower_parse_port_range(&min, &max,
+ ip_proto,
+ FLOWER_ENDPOINT_DST,
+ n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"dst_port range\"\n");
+ return -1;
+ }
+ } else {
+ ret = flower_parse_port(*argv, ip_proto,
+ FLOWER_ENDPOINT_DST, n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"dst_port\"\n");
+ return -1;
+ }
}
} else if (matches(*argv, "src_port") == 0) {
+ __be16 min, max;
+
NEXT_ARG();
- ret = flower_parse_port(*argv, ip_proto,
- FLOWER_ENDPOINT_SRC, n);
- if (ret < 0) {
- fprintf(stderr, "Illegal \"src_port\"\n");
- return -1;
+ if (matches(*argv, "range") == 0) {
+ NEXT_ARG();
+ ret = get_range(&min, &max, *argv);
+ if (ret < 0)
+ return -1;
+ ret = flower_parse_port_range(&min, &max,
+ ip_proto,
+ FLOWER_ENDPOINT_SRC,
+ n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"src_port range\"\n");
+ return -1;
+ }
+ } else {
+ ret = flower_parse_port(*argv, ip_proto,
+ FLOWER_ENDPOINT_SRC, n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"src_port\"\n");
+ return -1;
+ }
}
} else if (matches(*argv, "tcp_flags") == 0) {
NEXT_ARG();
@@ -1309,6 +1406,17 @@ static void flower_print_port(char *name, struct rtattr *attr)
print_hu(PRINT_ANY, name, namefrm, rta_getattr_be16(attr));
}
+static void flower_print_port_range(char *name, struct rtattr *attr)
+{
+ SPRINT_BUF(namefrm);
+
+ if (!attr)
+ return;
+
+ sprintf(namefrm, "\n %s %%u", name);
+ print_uint(PRINT_ANY, name, namefrm, rta_getattr_be16(attr));
+}
+
static void flower_print_tcp_flags(const char *name, struct rtattr *flags_attr,
struct rtattr *mask_attr)
{
@@ -1398,6 +1506,7 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
struct rtattr *opt, __u32 handle)
{
struct rtattr *tb[TCA_FLOWER_MAX + 1];
+ struct range_type range;
int nl_type, nl_mask_type;
__be16 eth_type = 0;
__u8 ip_proto = 0xff;
@@ -1516,6 +1625,22 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
if (nl_type >= 0)
flower_print_port("src_port", tb[nl_type]);
+ if (flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_DST, &range)
+ == 0) {
+ flower_print_port_range("dst_port_min",
+ tb[range.min_port_type]);
+ flower_print_port_range("dst_port_max",
+ tb[range.max_port_type]);
+ }
+
+ if (flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_SRC, &range)
+ == 0) {
+ flower_print_port_range("src_port_min",
+ tb[range.min_port_type]);
+ flower_print_port_range("src_port_max",
+ tb[range.max_port_type]);
+ }
+
flower_print_tcp_flags("tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS],
tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]);
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [iproute2 PATCH] tc: flower: Classify packets based port ranges
2018-10-12 13:54 [iproute2 PATCH] tc: flower: Classify packets based port ranges Amritha Nambiar
@ 2018-10-18 12:21 ` Jiri Pirko
2018-10-18 18:25 ` Nambiar, Amritha
0 siblings, 1 reply; 3+ messages in thread
From: Jiri Pirko @ 2018-10-18 12:21 UTC (permalink / raw)
To: Amritha Nambiar
Cc: stephen, netdev, jakub.kicinski, sridhar.samudrala, jhs,
xiyou.wangcong
Fri, Oct 12, 2018 at 03:54:42PM CEST, amritha.nambiar@intel.com wrote:
[...]
>@@ -1516,6 +1625,22 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
> if (nl_type >= 0)
> flower_print_port("src_port", tb[nl_type]);
>
>+ if (flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_DST, &range)
>+ == 0) {
>+ flower_print_port_range("dst_port_min",
>+ tb[range.min_port_type]);
>+ flower_print_port_range("dst_port_max",
>+ tb[range.max_port_type]);
The input and output of iproute2 utils, tc included should be in sync.
So you need to print "range x-y" here.
>+ }
>+
>+ if (flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_SRC, &range)
>+ == 0) {
>+ flower_print_port_range("src_port_min",
>+ tb[range.min_port_type]);
>+ flower_print_port_range("src_port_max",
>+ tb[range.max_port_type]);
>+ }
>+
> flower_print_tcp_flags("tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS],
> tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]);
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [iproute2 PATCH] tc: flower: Classify packets based port ranges
2018-10-18 12:21 ` Jiri Pirko
@ 2018-10-18 18:25 ` Nambiar, Amritha
0 siblings, 0 replies; 3+ messages in thread
From: Nambiar, Amritha @ 2018-10-18 18:25 UTC (permalink / raw)
To: Jiri Pirko
Cc: stephen, netdev, jakub.kicinski, sridhar.samudrala, jhs,
xiyou.wangcong
On 10/18/2018 5:21 AM, Jiri Pirko wrote:
> Fri, Oct 12, 2018 at 03:54:42PM CEST, amritha.nambiar@intel.com wrote:
>
> [...]
>
>> @@ -1516,6 +1625,22 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
>> if (nl_type >= 0)
>> flower_print_port("src_port", tb[nl_type]);
>>
>> + if (flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_DST, &range)
>> + == 0) {
>> + flower_print_port_range("dst_port_min",
>> + tb[range.min_port_type]);
>> + flower_print_port_range("dst_port_max",
>> + tb[range.max_port_type]);
>
> The input and output of iproute2 utils, tc included should be in sync.
> So you need to print "range x-y" here.
>
Agree, will fix in v2. Thanks!
>
>> + }
>> +
>> + if (flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_SRC, &range)
>> + == 0) {
>> + flower_print_port_range("src_port_min",
>> + tb[range.min_port_type]);
>> + flower_print_port_range("src_port_max",
>> + tb[range.max_port_type]);
>> + }
>> +
>> flower_print_tcp_flags("tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS],
>> tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]);
>>
>>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-10-19 2:27 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-12 13:54 [iproute2 PATCH] tc: flower: Classify packets based port ranges Amritha Nambiar
2018-10-18 12:21 ` Jiri Pirko
2018-10-18 18:25 ` Nambiar, Amritha
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox