1 /*
2 * Copyright (c) 2018-2021 Eugene Syromyatnikov <evgsyr@gmail.com>
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7
8 #include "defs.h"
9 #include "netlink_route.h"
10 #include "nlattr.h"
11 #include "print_fields.h"
12
13 #include "netlink.h"
14 #include <linux/mroute.h>
15 #include <linux/mroute6.h>
16 #include <linux/rtnetlink.h>
17
18 #include "xlat/rtnl_ip6mra_creport_attr.h"
19 #include "xlat/rtnl_ip6mra_msg_types.h"
20 #include "xlat/rtnl_ipmra_creport_attr.h"
21 #include "xlat/rtnl_ipmra_msg_types.h"
22 #include "xlat/rtnl_family.h"
23
24 static bool
25 decode_nla_ipmra_msg_type(struct tcb *const tcp,
26 const kernel_ulong_t addr,
27 const unsigned int len,
28 const void *const opaque_data)
29 {
30 const struct decode_nla_xlat_opts opts = {
31 .xlat = rtnl_ipmra_msg_types,
32 .dflt = "IGMPMSG_???",
33 .size = 1,
34 };
35
36 return decode_nla_xval(tcp, addr, len, &opts);
37 }
38
39 static const nla_decoder_t rtnl_creport_ipmra_decoders[] = {
40 [IPMRA_CREPORT_UNSPEC] = NULL,
41 [IPMRA_CREPORT_MSGTYPE] = decode_nla_ipmra_msg_type,
42 [IPMRA_CREPORT_VIF_ID] = decode_nla_u32,
43 [IPMRA_CREPORT_SRC_ADDR] = decode_nla_in_addr,
44 [IPMRA_CREPORT_DST_ADDR] = decode_nla_in_addr,
45 [IPMRA_CREPORT_PKT] = NULL, /* raw packet data */
46 [IPMRA_CREPORT_TABLE] = decode_nla_u32,
47 };
48
49 static bool
50 decode_nla_ip6mra_msg_type(struct tcb *const tcp,
51 const kernel_ulong_t addr,
52 const unsigned int len,
53 const void *const opaque_data)
54 {
55 const struct decode_nla_xlat_opts opts = {
56 .xlat = rtnl_ip6mra_msg_types,
57 .dflt = "MRT6MSG_???",
58 .size = 1,
59 };
60
61 return decode_nla_xval(tcp, addr, len, &opts);
62 }
63
64 static const nla_decoder_t rtnl_creport_ip6mra_decoders[] = {
65 [IP6MRA_CREPORT_UNSPEC] = NULL,
66 [IP6MRA_CREPORT_MSGTYPE] = decode_nla_ip6mra_msg_type,
67 [IP6MRA_CREPORT_MIF_ID] = decode_nla_u32,
68 [IP6MRA_CREPORT_SRC_ADDR] = decode_nla_in6_addr,
69 [IP6MRA_CREPORT_DST_ADDR] = decode_nla_in6_addr,
70 [IP6MRA_CREPORT_PKT] = NULL, /* raw packet data */
71 };
72
73 DECL_NETLINK_ROUTE_DECODER(decode_cachereport)
74 {
75 static const struct af_spec_decoder_desc cachereport_descs[] = {
76 { RTNL_FAMILY_IPMR,
77 rtnl_ipmra_creport_attr, "IPMRA_CREPORT_???",
78 ARRSZ_PAIR(rtnl_creport_ipmra_decoders) },
79 { RTNL_FAMILY_IP6MR,
80 rtnl_ip6mra_creport_attr, "IP6MRA_CREPORT_???",
81 ARRSZ_PAIR(rtnl_creport_ip6mra_decoders) },
82 };
83
84 struct rtgenmsg rtgenmsg = { .rtgen_family = family };
85
86 tprint_struct_begin();
87 tprints_field_name("rtgen_family");
88 printxvals_ex(rtgenmsg.rtgen_family, "RTNL_FAMILY_???",
89 XLAT_STYLE_DEFAULT, rtnl_family, addrfams, NULL);
90 tprint_struct_end();
91
92 const size_t offset = NLMSG_ALIGN(sizeof(rtgenmsg));
93
94 if (len > offset) {
95 tprint_array_next();
96 decode_nla_af_spec(tcp, addr + offset, len - offset,
97 rtgenmsg.rtgen_family,
98 ARRSZ_PAIR(cachereport_descs));
99 }
100 }