actions: skbedit add support for mod-ing skb pkt_type

I'll make a formal submission sans the header when the kernel patches
makes it in. This version is for someone who wants to play around with
the net-next kernel patches i sent

Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
This commit is contained in:
Jamal Hadi Salim 2016-07-02 07:14:33 -04:00 committed by Stephen Hemminger
parent 4824bb4151
commit 1d1e0fd29b
2 changed files with 53 additions and 6 deletions

View File

@ -11,6 +11,8 @@ skbedit - SKB editing action
.IR PRIORITY " ] [" .IR PRIORITY " ] ["
.B mark .B mark
.IR MARK " ]" .IR MARK " ]"
.B ptype
.IR PTYPE " ]"
.SH DESCRIPTION .SH DESCRIPTION
The The
.B skbedit .B skbedit
@ -52,6 +54,13 @@ Change the packet's firewall mark value.
is an unsigned 32bit value in automatically detected format (i.e., prefix with is an unsigned 32bit value in automatically detected format (i.e., prefix with
.RB ' 0x ' .RB ' 0x '
for hexadecimal interpretation, etc.). for hexadecimal interpretation, etc.).
.TP
.BI ptype " PTYPE"
Override the packet's type. Useful for setting packet type to host when
needing to allow ingressing packets with the wrong MAC address but
correct IP address.
.I PTYPE
is one of: host, otherhost, broadcast, multicast
.SH SEE ALSO .SH SEE ALSO
.BR tc (8), .BR tc (8),
.BR tc-pedit (8) .BR tc-pedit (8)

View File

@ -26,14 +26,17 @@
#include "utils.h" #include "utils.h"
#include "tc_util.h" #include "tc_util.h"
#include <linux/tc_act/tc_skbedit.h> #include <linux/tc_act/tc_skbedit.h>
#include <linux/if_packet.h>
static void static void explain(void)
explain(void)
{ {
fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM]>\n" fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM] [PT]>\n"
"QM = queue_mapping QUEUE_MAPPING\n" "QM = queue_mapping QUEUE_MAPPING\n"
"PM = priority PRIORITY\n" "PM = priority PRIORITY\n"
"MM = mark MARK\n" "MM = mark MARK\n"
"PT = ptype PACKETYPE\n"
"PACKETYPE = is one of:\n"
" host, otherhost, broadcast, multicast\n"
"QUEUE_MAPPING = device transmit queue to use\n" "QUEUE_MAPPING = device transmit queue to use\n"
"PRIORITY = classID to assign to priority field\n" "PRIORITY = classID to assign to priority field\n"
"MARK = firewall mark to set\n"); "MARK = firewall mark to set\n");
@ -55,7 +58,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
int ok = 0; int ok = 0;
struct rtattr *tail; struct rtattr *tail;
unsigned int tmp; unsigned int tmp;
__u16 queue_mapping; __u16 queue_mapping, ptype;
__u32 flags = 0, priority, mark; __u32 flags = 0, priority, mark;
struct tc_skbedit sel = { 0 }; struct tc_skbedit sel = { 0 };
@ -90,6 +93,24 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
return -1; return -1;
} }
ok++; ok++;
} else if (matches(*argv, "ptype") == 0) {
NEXT_ARG();
if (matches(*argv, "host") == 0) {
ptype = PACKET_HOST;
} else if (matches(*argv, "broadcast") == 0) {
ptype = PACKET_BROADCAST;
} else if (matches(*argv, "multicast") == 0) {
ptype = PACKET_MULTICAST;
} else if (matches(*argv, "otherhost") == 0) {
ptype = PACKET_OTHERHOST;
} else {
fprintf(stderr, "Illegal ptype (%s)\n",
*argv);
return -1;
}
flags |= SKBEDIT_F_PTYPE;
ok++;
} else if (matches(*argv, "help") == 0) { } else if (matches(*argv, "help") == 0) {
usage(); usage();
} else { } else {
@ -152,6 +173,9 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
if (flags & SKBEDIT_F_MARK) if (flags & SKBEDIT_F_MARK)
addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK, addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK,
&mark, sizeof(mark)); &mark, sizeof(mark));
if (flags & SKBEDIT_F_PTYPE)
addattr_l(n, MAX_MSG, TCA_SKBEDIT_PTYPE,
&ptype, sizeof(ptype));
tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail; tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail;
*argc_p = argc; *argc_p = argc;
@ -166,7 +190,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
SPRINT_BUF(b1); SPRINT_BUF(b1);
__u32 *priority; __u32 *priority;
__u32 *mark; __u32 *mark;
__u16 *queue_mapping; __u16 *queue_mapping, *ptype;
struct tc_skbedit *p = NULL; struct tc_skbedit *p = NULL;
if (arg == NULL) if (arg == NULL)
@ -194,8 +218,22 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]); mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]);
fprintf(f, " mark %d", *mark); fprintf(f, " mark %d", *mark);
} }
if (tb[TCA_SKBEDIT_PTYPE] != NULL) {
ptype = RTA_DATA(tb[TCA_SKBEDIT_PTYPE]);
if (*ptype == PACKET_HOST)
fprintf(f, " ptype host");
else if (*ptype == PACKET_BROADCAST)
fprintf(f, " ptype broadcast");
else if (*ptype == PACKET_MULTICAST)
fprintf(f, " ptype multicast");
else if (*ptype == PACKET_OTHERHOST)
fprintf(f, " ptype otherhost");
else
fprintf(f, " ptype %d", *ptype);
}
fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt, p->bindcnt); fprintf(f, "\n\t index %d ref %d bind %d",
p->index, p->refcnt, p->bindcnt);
if (show_stats) { if (show_stats) {
if (tb[TCA_SKBEDIT_TM]) { if (tb[TCA_SKBEDIT_TM]) {