Add u32 extension to match on ether source/destination
Use existing u32 mechanism to match based on Ethernet header. No need for protocol that already exists.
This commit is contained in:
parent
b9ab720e33
commit
b4d41f41b6
70
tc/f_u32.c
70
tc/f_u32.c
|
|
@ -405,6 +405,48 @@ static int parse_ip6_addr(int *argc_p, char ***argv_p,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_ether_addr(int *argc_p, char ***argv_p,
|
||||||
|
struct tc_u32_sel *sel, int off)
|
||||||
|
{
|
||||||
|
int res = -1;
|
||||||
|
int argc = *argc_p;
|
||||||
|
char **argv = *argv_p;
|
||||||
|
__u8 addr[6];
|
||||||
|
int offmask = 0;
|
||||||
|
__u32 key;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argc < 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sscanf(*argv, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||||
|
addr + 0, addr + 1, addr + 2,
|
||||||
|
addr + 3, addr + 4, addr + 5) != 6) {
|
||||||
|
fprintf(stderr, "parse_ether_addr: improperly formed address '%s'\n",
|
||||||
|
*argv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
argc--; argv++;
|
||||||
|
if (argc > 0 && strcmp(argv[0], "at") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (parse_at(&argc, &argv, &off, &offmask))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i += 2) {
|
||||||
|
key = *(__u16 *) (addr + i);
|
||||||
|
|
||||||
|
res = pack_key16(sel, key, 0xFFFF, off + i, offmask);
|
||||||
|
if (res < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*argc_p = argc;
|
||||||
|
*argv_p = argv;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
|
static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
@ -509,6 +551,31 @@ static int parse_ip6(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_ether(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
|
||||||
|
{
|
||||||
|
int res = -1;
|
||||||
|
int argc = *argc_p;
|
||||||
|
char **argv = *argv_p;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (strcmp(*argv, "src") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
res = parse_ether_addr(&argc, &argv, sel, -8);
|
||||||
|
} else if (strcmp(*argv, "dst") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
res = parse_ether_addr(&argc, &argv, sel, -14);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Unknown match: ether %s\n", *argv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*argc_p = argc;
|
||||||
|
*argv_p = argv;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
#define parse_tcp parse_udp
|
#define parse_tcp parse_udp
|
||||||
static int parse_udp(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
|
static int parse_udp(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
|
||||||
{
|
{
|
||||||
|
|
@ -629,6 +696,9 @@ static int parse_selector(int *argc_p, char ***argv_p,
|
||||||
} else if (matches(*argv, "mark") == 0) {
|
} else if (matches(*argv, "mark") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
res = parse_mark(&argc, &argv, n);
|
res = parse_mark(&argc, &argv, n);
|
||||||
|
} else if (matches(*argv, "ether") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
res = parse_ether(&argc, &argv, sel);
|
||||||
} else
|
} else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue