Add support for IOAM encap modes
This patch adds support for the three IOAM encap modes that were introduced: inline, encap and auto. Signed-off-by: Justin Iurman <justin.iurman@uliege.be> Signed-off-by: David Ahern <dsahern@kernel.org>
This commit is contained in:
parent
b840c620fe
commit
8fb522cde3
|
|
@ -210,16 +210,54 @@ static void print_encap_rpl(FILE *fp, struct rtattr *encap)
|
|||
print_rpl_srh(fp, srh);
|
||||
}
|
||||
|
||||
static const char *ioam6_mode_types[IOAM6_IPTUNNEL_MODE_MAX + 1] = {
|
||||
[IOAM6_IPTUNNEL_MODE_INLINE] = "inline",
|
||||
[IOAM6_IPTUNNEL_MODE_ENCAP] = "encap",
|
||||
[IOAM6_IPTUNNEL_MODE_AUTO] = "auto",
|
||||
};
|
||||
|
||||
static const char *format_ioam6mode_type(int mode)
|
||||
{
|
||||
if (mode < IOAM6_IPTUNNEL_MODE_MIN ||
|
||||
mode > IOAM6_IPTUNNEL_MODE_MAX ||
|
||||
!ioam6_mode_types[mode])
|
||||
return "<unknown>";
|
||||
|
||||
return ioam6_mode_types[mode];
|
||||
}
|
||||
|
||||
static __u8 read_ioam6mode_type(const char *mode)
|
||||
{
|
||||
__u8 i;
|
||||
|
||||
for (i = IOAM6_IPTUNNEL_MODE_MIN; i <= IOAM6_IPTUNNEL_MODE_MAX; i++) {
|
||||
if (ioam6_mode_types[i] && !strcmp(mode, ioam6_mode_types[i]))
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_encap_ioam6(FILE *fp, struct rtattr *encap)
|
||||
{
|
||||
struct rtattr *tb[IOAM6_IPTUNNEL_MAX + 1];
|
||||
struct ioam6_trace_hdr *trace;
|
||||
__u8 mode;
|
||||
|
||||
parse_rtattr_nested(tb, IOAM6_IPTUNNEL_MAX, encap);
|
||||
|
||||
if (!tb[IOAM6_IPTUNNEL_TRACE])
|
||||
if (!tb[IOAM6_IPTUNNEL_MODE] || !tb[IOAM6_IPTUNNEL_TRACE])
|
||||
return;
|
||||
|
||||
mode = rta_getattr_u8(tb[IOAM6_IPTUNNEL_MODE]);
|
||||
if (!tb[IOAM6_IPTUNNEL_DST] && mode != IOAM6_IPTUNNEL_MODE_INLINE)
|
||||
return;
|
||||
|
||||
print_string(PRINT_ANY, "mode", "mode %s ", format_ioam6mode_type(mode));
|
||||
|
||||
if (mode != IOAM6_IPTUNNEL_MODE_INLINE)
|
||||
print_string(PRINT_ANY, "tundst", "tundst %s ",
|
||||
rt_addr_n2a_rta(AF_INET6, tb[IOAM6_IPTUNNEL_DST]));
|
||||
|
||||
trace = RTA_DATA(tb[IOAM6_IPTUNNEL_TRACE]);
|
||||
|
||||
print_null(PRINT_ANY, "trace", "trace ", NULL);
|
||||
|
|
@ -884,23 +922,48 @@ out:
|
|||
static int parse_encap_ioam6(struct rtattr *rta, size_t len, int *argcp,
|
||||
char ***argvp)
|
||||
{
|
||||
int ns_found = 0, argc = *argcp;
|
||||
__u16 trace_ns, trace_size = 0;
|
||||
struct ioam6_trace_hdr *trace;
|
||||
char **argv = *argvp;
|
||||
int argc = *argcp;
|
||||
int ns_found = 0;
|
||||
__u16 size = 0;
|
||||
__u32 type = 0;
|
||||
__u16 ns;
|
||||
__u32 trace_type = 0;
|
||||
inet_prefix addr;
|
||||
__u8 mode;
|
||||
|
||||
trace = calloc(1, sizeof(*trace));
|
||||
if (!trace)
|
||||
return -1;
|
||||
if (strcmp(*argv, "mode") != 0) {
|
||||
mode = IOAM6_IPTUNNEL_MODE_INLINE;
|
||||
} else {
|
||||
NEXT_ARG();
|
||||
|
||||
if (strcmp(*argv, "trace"))
|
||||
mode = read_ioam6mode_type(*argv);
|
||||
if (!mode)
|
||||
invarg("Invalid mode", *argv);
|
||||
|
||||
NEXT_ARG();
|
||||
}
|
||||
|
||||
if (strcmp(*argv, "tundst") != 0) {
|
||||
if (mode != IOAM6_IPTUNNEL_MODE_INLINE)
|
||||
missarg("tundst");
|
||||
} else {
|
||||
if (mode == IOAM6_IPTUNNEL_MODE_INLINE)
|
||||
invarg("Inline mode does not need tundst", *argv);
|
||||
|
||||
NEXT_ARG();
|
||||
|
||||
get_addr(&addr, *argv, AF_INET6);
|
||||
if (addr.family != AF_INET6 || addr.bytelen != 16)
|
||||
invarg("Invalid IPv6 address for tundst", *argv);
|
||||
|
||||
NEXT_ARG();
|
||||
}
|
||||
|
||||
if (strcmp(*argv, "trace") != 0)
|
||||
missarg("trace");
|
||||
|
||||
NEXT_ARG();
|
||||
if (strcmp(*argv, "prealloc"))
|
||||
|
||||
if (strcmp(*argv, "prealloc") != 0)
|
||||
missarg("prealloc");
|
||||
|
||||
while (NEXT_ARG_OK()) {
|
||||
|
|
@ -909,63 +972,58 @@ static int parse_encap_ioam6(struct rtattr *rta, size_t len, int *argcp,
|
|||
if (strcmp(*argv, "type") == 0) {
|
||||
NEXT_ARG();
|
||||
|
||||
if (type)
|
||||
if (trace_type)
|
||||
duparg2("type", *argv);
|
||||
|
||||
if (get_u32(&type, *argv, 0) || !type)
|
||||
invarg("Invalid type", *argv);
|
||||
|
||||
trace->type_be32 = htonl(type << 8);
|
||||
|
||||
if (get_u32(&trace_type, *argv, 0) || !trace_type)
|
||||
invarg("Invalid trace type", *argv);
|
||||
} else if (strcmp(*argv, "ns") == 0) {
|
||||
NEXT_ARG();
|
||||
|
||||
if (ns_found++)
|
||||
duparg2("ns", *argv);
|
||||
|
||||
if (!type)
|
||||
missarg("type");
|
||||
|
||||
if (get_u16(&ns, *argv, 0))
|
||||
if (get_u16(&trace_ns, *argv, 0))
|
||||
invarg("Invalid namespace ID", *argv);
|
||||
|
||||
trace->namespace_id = htons(ns);
|
||||
|
||||
} else if (strcmp(*argv, "size") == 0) {
|
||||
NEXT_ARG();
|
||||
|
||||
if (size)
|
||||
if (trace_size)
|
||||
duparg2("size", *argv);
|
||||
|
||||
if (!type)
|
||||
missarg("type");
|
||||
if (!ns_found)
|
||||
missarg("ns");
|
||||
if (get_u16(&trace_size, *argv, 0) || !trace_size)
|
||||
invarg("Invalid trace size", *argv);
|
||||
|
||||
if (get_u16(&size, *argv, 0) || !size)
|
||||
invarg("Invalid size", *argv);
|
||||
|
||||
if (size % 4)
|
||||
invarg("Size must be a 4-octet multiple", *argv);
|
||||
if (size > IOAM6_TRACE_DATA_SIZE_MAX)
|
||||
invarg("Size too big", *argv);
|
||||
|
||||
trace->remlen = (__u8)(size / 4);
|
||||
if (trace_size % 4)
|
||||
invarg("Trace size must be a 4-octet multiple",
|
||||
*argv);
|
||||
|
||||
if (trace_size > IOAM6_TRACE_DATA_SIZE_MAX)
|
||||
invarg("Trace size is too big", *argv);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!type)
|
||||
if (!trace_type)
|
||||
missarg("type");
|
||||
if (!ns_found)
|
||||
missarg("ns");
|
||||
if (!size)
|
||||
if (!trace_size)
|
||||
missarg("size");
|
||||
|
||||
if (rta_addattr_l(rta, len, IOAM6_IPTUNNEL_TRACE, trace,
|
||||
sizeof(*trace))) {
|
||||
trace = calloc(1, sizeof(*trace));
|
||||
if (!trace)
|
||||
return -1;
|
||||
|
||||
trace->type_be32 = htonl(trace_type << 8);
|
||||
trace->namespace_id = htons(trace_ns);
|
||||
trace->remlen = (__u8)(trace_size / 4);
|
||||
|
||||
if (rta_addattr8(rta, len, IOAM6_IPTUNNEL_MODE, mode) ||
|
||||
(mode != IOAM6_IPTUNNEL_MODE_INLINE &&
|
||||
rta_addattr_l(rta, len, IOAM6_IPTUNNEL_DST, &addr.data, addr.bytelen)) ||
|
||||
rta_addattr_l(rta, len, IOAM6_IPTUNNEL_TRACE, trace, sizeof(*trace))) {
|
||||
free(trace);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue