--- a/tc/Makefile 2019-04-08 12:48:15.425854828 +0530 +++ b/tc/Makefile 2019-04-08 13:03:17.204741000 +0530 @@ -54,6 +54,7 @@ TCMODULES += m_bpf.o TCMODULES += m_sample.o TCMODULES += m_ct.o TCMODULES += m_gate.o +TCMODULES += m_nssmirred.o TCMODULES += p_ip.o TCMODULES += p_ip6.o TCMODULES += p_icmp.o --- /dev/null 1970-01-01 05:30:00.000000000 +0530 +++ b/tc/m_nssmirred.c 2019-06-19 14:25:51.369793000 +0530 @@ -0,0 +1,183 @@ +/* + ************************************************************************** + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" +#include "tc_util.h" +#include "tc_common.h" +#include + +/* + * explain() + * API to print the explaination of nssmirred action statement's + * elements. + */ +static void explain(void) +{ + fprintf(stderr, "Usage: nssmirred redirect \n"); + fprintf(stderr, "where: \n"); + fprintf(stderr, "\tTO_DEVICENAME is the devicename to redirect to\n"); + fprintf(stderr, "\tFROM_DEVICENAME is the devicename to redirect from\n"); +} + +/* + * usage() + * API to show the usage of the nssmirred action. + */ +static void usage(void) +{ + explain(); + exit(-1); +} + +/* + * parse_nss_mirred() + * Parse and validate the nssmirred action statement. + */ +static int parse_nss_mirred(struct action_util *a, int *argc_p, char ***argv_p, + int tca_id, struct nlmsghdr *n) +{ + int idx, argc = *argc_p; + char **argv = *argv_p; + struct tc_nss_mirred p; + struct rtattr *tail; + + if (argc < 0) { + fprintf(stderr, "nssmirred bad argument count %d. Try option \"help\"\n", argc); + goto error; + } + + if (matches(*argv, "nssmirred")) { + fprintf(stderr, "nssmirred bad argument %s. Try option \"help\"\n", *argv); + goto error; + } + + NEXT_ARG(); + if (!matches(*argv, "help")) { + usage(); + } + + if (matches(*argv, "redirect")) { + fprintf(stderr, "nssmirred bad argument %s. Try option \"help\"\n", *argv); + goto error; + } + + NEXT_ARG(); + if (matches(*argv, "dev")) { + fprintf(stderr, "nssmirred: bad value %s. Try option \"help\"\n", *argv); + goto error; + } + + NEXT_ARG(); + memset(&p, 0, sizeof(struct tc_nss_mirred)); + if ((idx = ll_name_to_index(*argv)) == 0) { + fprintf(stderr, "Cannot find to device \"%s\"\n", *argv); + goto error; + } + + p.to_ifindex = idx; + NEXT_ARG(); + if (matches(*argv, "fromdev")) { + fprintf(stderr, "nssmirred: bad value %s. Try option \"help\"\n", *argv); + goto error; + } + + NEXT_ARG(); + if ((idx = ll_name_to_index(*argv)) == 0) { + fprintf(stderr, "Cannot find from device \"%s\"\n", *argv); + goto error; + } + + p.from_ifindex = idx; + p.action = TC_ACT_STOLEN; + tail = NLMSG_TAIL(n); + addattr_l(n, MAX_MSG, tca_id, NULL, 0); + addattr_l(n, MAX_MSG, TCA_NSS_MIRRED_PARMS, &p, sizeof (p)); + tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; + argc--; + argv++; + *argc_p = argc; + *argv_p = argv; + return 0; + +error: + return -1; +} + +/* + * print_nss_mirred() + * Print information related to nssmirred action. + */ +static int print_nss_mirred(struct action_util *au, FILE * f, struct rtattr *arg) +{ + struct tc_nss_mirred *p; + struct rtattr *tb[TCA_NSS_MIRRED_MAX + 1]; + const char *from_dev, *to_dev; + + if (arg == NULL) { + return -1; + } + + parse_rtattr_nested(tb, TCA_NSS_MIRRED_MAX, arg); + + if (tb[TCA_NSS_MIRRED_PARMS] == NULL) { + fprintf(f, "[NULL nssmirred parameters]"); + goto error; + } + + p = RTA_DATA(tb[TCA_NSS_MIRRED_PARMS]); + if ((from_dev = ll_index_to_name(p->from_ifindex)) == 0) { + fprintf(stderr, "Invalid interface (index: %d)\n", p->from_ifindex); + goto error; + } + + if ((to_dev = ll_index_to_name(p->to_ifindex)) == 0) { + fprintf(stderr, "Invalid interface (index: %d)\n", p->to_ifindex); + goto error; + } + + fprintf(f, "nssmirred (%s to device %s) stolen\n", from_dev, to_dev); + fprintf(f, "\tindex %d ref %d bind %d\n",p->index,p->refcnt,p->bindcnt); + + if (show_stats) { + if (tb[TCA_NSS_MIRRED_TM]) { + struct tcf_t *tm = RTA_DATA(tb[TCA_NSS_MIRRED_TM]); + print_tm(f,tm); + } + } + return 0; + +error: + return -1; +} + +/* + * nssmirred_action_util + * nssmirred action utility structure. + */ +struct action_util nssmirred_action_util = { + .id = "nssmirred", + .parse_aopt = parse_nss_mirred, + .print_aopt = print_nss_mirred, +}; --- /dev/null 1970-01-01 05:30:00.000000000 +0530 +++ a/include/linux/tc_act/tc_nssmirred.h 2019-06-19 14:25:40.787768000 +0530 @@ -0,0 +1,44 @@ +/* + ************************************************************************** + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __LINUX_TC_NSS_MIR_H +#define __LINUX_TC_NSS_MIR_H + +#include +#include + +/* + * tc_nss_mirred + * Structure for nssmirred action. + */ +struct tc_nss_mirred { + tc_gen; + __u32 from_ifindex; /* ifindex of the port to be redirected from */ + __u32 to_ifindex; /* ifindex of the port to be redirected to */ +}; + +/* + * Types of nssmirred action parameters. + */ +enum { + TCA_NSS_MIRRED_UNSPEC, + TCA_NSS_MIRRED_TM, + TCA_NSS_MIRRED_PARMS, + __TCA_NSS_MIRRED_MAX +}; +#define TCA_NSS_MIRRED_MAX (__TCA_NSS_MIRRED_MAX - 1) + +#endif /* __LINUX_TC_NSS_MIR_H */