diff options
author | Victor Nogueira <victor@mojatatu.com> | 2024-01-23 18:38:11 -0300 |
---|---|---|
committer | David Ahern <dsahern@kernel.org> | 2024-01-25 18:15:50 +0000 |
commit | 139a74134c52a7f96cc7b16a53988097dd2d4175 (patch) | |
tree | 8819908e2037ae49a67e9fb52e9ad9e91f3da0a2 /tc | |
parent | fbf0acb941507a47e6fbec3eec39500b73c32f53 (diff) |
m_mirred: Allow mirred to block
So far the mirred action has dealt with syntax that handles
mirror/redirection for netdev. A matching packet is redirected or mirrored
to a target netdev.
In this patch we enable mirred to mirror to a tc block as well.
IOW, the new syntax looks as follows:
... mirred <ingress | egress> <mirror | redirect> [index INDEX] < <blockid BLOCKID> | <dev <devname>> >
Examples of mirroring or redirecting to a tc block:
$ tc filter add block 22 protocol ip pref 25 \
flower dst_ip 192.168.0.0/16 action mirred egress mirror blockid 22
$ tc filter add block 22 protocol ip pref 25 \
flower dst_ip 10.10.10.10/32 action mirred egress redirect blockid 22
Co-developed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Co-developed-by: Pedro Tammela <pctammela@mojatatu.com>
Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
Diffstat (limited to 'tc')
-rw-r--r-- | tc/m_mirred.c | 61 |
1 files changed, 49 insertions, 12 deletions
diff --git a/tc/m_mirred.c b/tc/m_mirred.c index e5653e67..60bd9045 100644 --- a/tc/m_mirred.c +++ b/tc/m_mirred.c @@ -24,12 +24,16 @@ static void explain(void) { fprintf(stderr, - "Usage: mirred <DIRECTION> <ACTION> [index INDEX] <dev DEVICENAME>\n" + "Usage: mirred <DIRECTION> <ACTION> [index INDEX] <TARGET>\n" "where:\n" "\tDIRECTION := <ingress | egress>\n" "\tACTION := <mirror | redirect>\n" "\tINDEX is the specific policy instance id\n" - "\tDEVICENAME is the devicename\n"); + "\tTARGET := <BLOCK | DEVICE>\n" + "\tDEVICE := dev DEVICENAME\n" + "\tDEVICENAME is the devicename\n" + "\tBLOCK := blockid BLOCKID\n" + "\tBLOCKID := 32-bit unsigned block ID\n"); } static void @@ -94,6 +98,7 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p, struct tc_mirred p = {}; struct rtattr *tail; char d[IFNAMSIZ] = {}; + __u32 blockid = 0; while (argc > 0) { @@ -162,15 +167,37 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p, TCA_INGRESS_REDIR; p.action = TC_ACT_STOLEN; ok++; - } else if ((redir || mirror) && - matches(*argv, "dev") == 0) { - NEXT_ARG(); - if (strlen(d)) - duparg("dev", *argv); - - strncpy(d, *argv, sizeof(d)-1); - argc--; - argv++; + } else if ((redir || mirror)) { + if (strcmp(*argv, "blockid") == 0) { + if (strlen(d)) { + fprintf(stderr, + "blockid and device are mutually exclusive.\n"); + return -1; + } + NEXT_ARG(); + if (get_u32(&blockid, *argv, 0) || + !blockid) { + fprintf(stderr, + "invalid block ID"); + return -1; + } + argc--; + argv++; + } + if (argc && matches(*argv, "dev") == 0) { + if (blockid) { + fprintf(stderr, + "blockid and device are mutually exclusive.\n"); + return -1; + } + NEXT_ARG(); + if (strlen(d)) + duparg("dev", *argv); + + strncpy(d, *argv, sizeof(d)-1); + argc--; + argv++; + } break; @@ -220,6 +247,8 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p, tail = addattr_nest(n, MAX_MSG, tca_id); addattr_l(n, MAX_MSG, TCA_MIRRED_PARMS, &p, sizeof(p)); + if (blockid) + addattr32(n, MAX_MSG, TCA_MIRRED_BLOCKID, blockid); addattr_nest_end(n, tail); *argc_p = argc; @@ -299,7 +328,15 @@ print_mirred(struct action_util *au, FILE *f, struct rtattr *arg) mirred_action(p->eaction)); print_string(PRINT_JSON, "direction", NULL, mirred_direction(p->eaction)); - print_string(PRINT_ANY, "to_dev", " to device %s)", dev); + if (tb[TCA_MIRRED_BLOCKID]) { + const __u32 *blockid = RTA_DATA(tb[TCA_MIRRED_BLOCKID]); + + print_uint(PRINT_ANY, "to_blockid", " to blockid %u)", + *blockid); + } else { + print_string(PRINT_ANY, "to_dev", " to device %s)", dev); + } + print_action_control(f, " ", p->action, ""); print_nl(); |