mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-08-13 10:56:55 +00:00

Gcc-10 complains about referencing a zero size array.
This occurs because the array of keys is actually in the following
structure which is part of the overall selector.
The original code was safe, but better to just use the key
array directly.
Fixes: 2d9a8dc439
("tc: p_ip6: Support pedit of IPv6 dsfield")
Cc: petrm@mellanox.com
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
105 lines
2.2 KiB
C
105 lines
2.2 KiB
C
/*
|
|
* p_ip6.c packet editor: IPV6 header
|
|
*
|
|
* This program is free software; you can distribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*
|
|
* Authors: Amir Vadai <amir@vadai.me>
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <string.h>
|
|
#include "utils.h"
|
|
#include "tc_util.h"
|
|
#include "m_pedit.h"
|
|
|
|
static int
|
|
parse_ip6(int *argc_p, char ***argv_p,
|
|
struct m_pedit_sel *sel, struct m_pedit_key *tkey)
|
|
{
|
|
int res = -1;
|
|
int argc = *argc_p;
|
|
char **argv = *argv_p;
|
|
|
|
if (argc < 2)
|
|
return -1;
|
|
|
|
if (!sel->extended)
|
|
return -1;
|
|
|
|
tkey->htype = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6;
|
|
|
|
if (strcmp(*argv, "src") == 0) {
|
|
NEXT_ARG();
|
|
tkey->off = 8;
|
|
res = parse_cmd(&argc, &argv, 16, TIPV6, RU32, sel, tkey);
|
|
goto done;
|
|
}
|
|
if (strcmp(*argv, "dst") == 0) {
|
|
NEXT_ARG();
|
|
tkey->off = 24;
|
|
res = parse_cmd(&argc, &argv, 16, TIPV6, RU32, sel, tkey);
|
|
goto done;
|
|
}
|
|
if (strcmp(*argv, "flow_lbl") == 0) {
|
|
NEXT_ARG();
|
|
tkey->off = 0;
|
|
res = parse_cmd(&argc, &argv, 4, TU32, 0x0007ffff, sel, tkey);
|
|
goto done;
|
|
}
|
|
if (strcmp(*argv, "payload_len") == 0) {
|
|
NEXT_ARG();
|
|
tkey->off = 4;
|
|
res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
|
|
goto done;
|
|
}
|
|
if (strcmp(*argv, "nexthdr") == 0) {
|
|
NEXT_ARG();
|
|
tkey->off = 6;
|
|
res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
|
|
goto done;
|
|
}
|
|
if (strcmp(*argv, "hoplimit") == 0) {
|
|
NEXT_ARG();
|
|
tkey->off = 7;
|
|
res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
|
|
goto done;
|
|
}
|
|
if (strcmp(*argv, "traffic_class") == 0) {
|
|
NEXT_ARG();
|
|
tkey->off = 1;
|
|
res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
|
|
|
|
/* Shift the field by 4 bits on success. */
|
|
if (!res) {
|
|
int nkeys = sel->sel.nkeys;
|
|
struct tc_pedit_key *key = &sel->keys[nkeys - 1];
|
|
|
|
key->mask = htonl(ntohl(key->mask) << 4 | 0xf);
|
|
key->val = htonl(ntohl(key->val) << 4);
|
|
}
|
|
goto done;
|
|
}
|
|
|
|
return -1;
|
|
|
|
done:
|
|
*argc_p = argc;
|
|
*argv_p = argv;
|
|
return res;
|
|
}
|
|
|
|
struct m_pedit_util p_pedit_ip6 = {
|
|
.id = "ip6",
|
|
.parse_peopt = parse_ip6,
|
|
};
|