mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-29 23:09:34 +00:00
zebra: Add 2 things to fpm_listener
1) Add ability to hex-dump the received packet for debugging 2) Receive encap type and vxlan vni and display them. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
parent
0c9ce7a862
commit
084aba4ec0
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/if_link.h>
|
||||||
|
|
||||||
#include "rt_netlink.h"
|
#include "rt_netlink.h"
|
||||||
#include "fpm/fpm.h"
|
#include "fpm/fpm.h"
|
||||||
@ -42,6 +43,7 @@ struct glob {
|
|||||||
int server_sock;
|
int server_sock;
|
||||||
int sock;
|
int sock;
|
||||||
bool reflect;
|
bool reflect;
|
||||||
|
bool dump_hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct glob glob_space;
|
struct glob glob_space;
|
||||||
@ -292,6 +294,8 @@ netlink_prot_to_s(unsigned char prot)
|
|||||||
struct netlink_nh {
|
struct netlink_nh {
|
||||||
struct rtattr *gateway;
|
struct rtattr *gateway;
|
||||||
int if_index;
|
int if_index;
|
||||||
|
uint16_t encap_type;
|
||||||
|
uint32_t vxlan_vni;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct netlink_msg_ctx {
|
struct netlink_msg_ctx {
|
||||||
@ -341,7 +345,7 @@ static inline void netlink_msg_ctx_set_err(struct netlink_msg_ctx *ctx,
|
|||||||
* parse_rtattrs_
|
* parse_rtattrs_
|
||||||
*/
|
*/
|
||||||
static int parse_rtattrs_(struct rtattr *rta, size_t len, struct rtattr **rtas,
|
static int parse_rtattrs_(struct rtattr *rta, size_t len, struct rtattr **rtas,
|
||||||
int num_rtas, const char **err_msg)
|
uint16_t num_rtas, const char **err_msg)
|
||||||
{
|
{
|
||||||
memset(rtas, 0, num_rtas * sizeof(rtas[0]));
|
memset(rtas, 0, num_rtas * sizeof(rtas[0]));
|
||||||
|
|
||||||
@ -387,7 +391,8 @@ static int parse_rtattrs(struct netlink_msg_ctx *ctx, struct rtattr *rta,
|
|||||||
* netlink_msg_ctx_add_nh
|
* netlink_msg_ctx_add_nh
|
||||||
*/
|
*/
|
||||||
static int netlink_msg_ctx_add_nh(struct netlink_msg_ctx *ctx, int if_index,
|
static int netlink_msg_ctx_add_nh(struct netlink_msg_ctx *ctx, int if_index,
|
||||||
struct rtattr *gateway)
|
struct rtattr *gateway, uint16_t encap_type,
|
||||||
|
uint32_t vxlan_vni)
|
||||||
{
|
{
|
||||||
struct netlink_nh *nh;
|
struct netlink_nh *nh;
|
||||||
|
|
||||||
@ -400,6 +405,9 @@ static int netlink_msg_ctx_add_nh(struct netlink_msg_ctx *ctx, int if_index,
|
|||||||
|
|
||||||
nh->gateway = gateway;
|
nh->gateway = gateway;
|
||||||
nh->if_index = if_index;
|
nh->if_index = if_index;
|
||||||
|
|
||||||
|
nh->encap_type = encap_type;
|
||||||
|
nh->vxlan_vni = vxlan_vni;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,6 +420,7 @@ static int parse_multipath_attr(struct netlink_msg_ctx *ctx,
|
|||||||
size_t len;
|
size_t len;
|
||||||
struct rtnexthop *rtnh;
|
struct rtnexthop *rtnh;
|
||||||
struct rtattr *rtattrs[RTA_MAX + 1];
|
struct rtattr *rtattrs[RTA_MAX + 1];
|
||||||
|
struct rtattr *tb[RTA_MAX + 1];
|
||||||
struct rtattr *gateway;
|
struct rtattr *gateway;
|
||||||
const char *err_msg;
|
const char *err_msg;
|
||||||
|
|
||||||
@ -420,6 +429,8 @@ static int parse_multipath_attr(struct netlink_msg_ctx *ctx,
|
|||||||
|
|
||||||
for (; len > 0;
|
for (; len > 0;
|
||||||
len -= NLMSG_ALIGN(rtnh->rtnh_len), rtnh = RTNH_NEXT(rtnh)) {
|
len -= NLMSG_ALIGN(rtnh->rtnh_len), rtnh = RTNH_NEXT(rtnh)) {
|
||||||
|
uint32_t vxlan_vni;
|
||||||
|
uint16_t encap_type;
|
||||||
|
|
||||||
if (!RTNH_OK(rtnh, len)) {
|
if (!RTNH_OK(rtnh, len)) {
|
||||||
netlink_msg_ctx_set_err(ctx, "Malformed nh");
|
netlink_msg_ctx_set_err(ctx, "Malformed nh");
|
||||||
@ -443,7 +454,27 @@ static int parse_multipath_attr(struct netlink_msg_ctx *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gateway = rtattrs[RTA_GATEWAY];
|
gateway = rtattrs[RTA_GATEWAY];
|
||||||
netlink_msg_ctx_add_nh(ctx, rtnh->rtnh_ifindex, gateway);
|
memset(tb, 0, sizeof(tb));
|
||||||
|
if (rtattrs[RTA_ENCAP]) {
|
||||||
|
parse_rtattrs_(RTA_DATA(rtattrs[RTA_ENCAP]),
|
||||||
|
rtattrs[RTA_ENCAP]->rta_len -
|
||||||
|
sizeof(struct rtattr),
|
||||||
|
tb, ARRAY_SIZE(tb), &err_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtattrs[RTA_ENCAP_TYPE])
|
||||||
|
encap_type =
|
||||||
|
*(uint16_t *)RTA_DATA(rtattrs[RTA_ENCAP_TYPE]);
|
||||||
|
else
|
||||||
|
encap_type = 0;
|
||||||
|
|
||||||
|
if (tb[0])
|
||||||
|
vxlan_vni = *(uint32_t *)RTA_DATA(tb[0]);
|
||||||
|
else
|
||||||
|
vxlan_vni = 0;
|
||||||
|
|
||||||
|
netlink_msg_ctx_add_nh(ctx, rtnh->rtnh_ifindex, gateway,
|
||||||
|
encap_type, vxlan_vni);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -485,11 +516,33 @@ static int parse_route_msg(struct netlink_msg_ctx *ctx)
|
|||||||
gateway = rtattrs[RTA_GATEWAY];
|
gateway = rtattrs[RTA_GATEWAY];
|
||||||
oif = rtattrs[RTA_OIF];
|
oif = rtattrs[RTA_OIF];
|
||||||
if (gateway || oif) {
|
if (gateway || oif) {
|
||||||
|
struct rtattr *tb[RTA_MAX + 1] = { 0 };
|
||||||
|
uint16_t encap_type = 0;
|
||||||
|
uint32_t vxlan_vni = 0;
|
||||||
|
|
||||||
if_index = 0;
|
if_index = 0;
|
||||||
if (oif)
|
if (oif)
|
||||||
if_index = *((int *)RTA_DATA(oif));
|
if_index = *((int *)RTA_DATA(oif));
|
||||||
|
|
||||||
netlink_msg_ctx_add_nh(ctx, if_index, gateway);
|
|
||||||
|
if (rtattrs[RTA_ENCAP]) {
|
||||||
|
const char *err_msg;
|
||||||
|
|
||||||
|
parse_rtattrs_(RTA_DATA(rtattrs[RTA_ENCAP]),
|
||||||
|
rtattrs[RTA_ENCAP]->rta_len -
|
||||||
|
sizeof(struct rtattr),
|
||||||
|
tb, ARRAY_SIZE(tb), &err_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtattrs[RTA_ENCAP_TYPE])
|
||||||
|
encap_type =
|
||||||
|
*(uint16_t *)RTA_DATA(rtattrs[RTA_ENCAP_TYPE]);
|
||||||
|
|
||||||
|
if (tb[0])
|
||||||
|
vxlan_vni = *(uint32_t *)RTA_DATA(tb[0]);
|
||||||
|
|
||||||
|
netlink_msg_ctx_add_nh(ctx, if_index, gateway, encap_type,
|
||||||
|
vxlan_vni);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtattr = rtattrs[RTA_MULTIPATH];
|
rtattr = rtattrs[RTA_MULTIPATH];
|
||||||
@ -557,6 +610,11 @@ static int netlink_msg_ctx_snprint(struct netlink_msg_ctx *ctx, char *buf,
|
|||||||
cur += snprintf(cur, end - cur, " via interface %d",
|
cur += snprintf(cur, end - cur, " via interface %d",
|
||||||
nh->if_index);
|
nh->if_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nh->encap_type)
|
||||||
|
cur += snprintf(cur, end - cur,
|
||||||
|
", Encap Type: %u Vxlan vni %u",
|
||||||
|
nh->encap_type, nh->vxlan_vni);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cur - buf;
|
return cur - buf;
|
||||||
@ -573,6 +631,51 @@ static void print_netlink_msg_ctx(struct netlink_msg_ctx *ctx)
|
|||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fpm_listener_hexdump(const void *mem, size_t len)
|
||||||
|
{
|
||||||
|
char line[64];
|
||||||
|
const uint8_t *src = mem;
|
||||||
|
const uint8_t *end = src + len;
|
||||||
|
|
||||||
|
if (!glob->dump_hex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
printf("%016lx: (zero length / no data)\n", (long)src);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src < end) {
|
||||||
|
struct fbuf fb = {
|
||||||
|
.buf = line,
|
||||||
|
.pos = line,
|
||||||
|
.len = sizeof(line),
|
||||||
|
};
|
||||||
|
const uint8_t *lineend = src + 8;
|
||||||
|
uint32_t line_bytes = 0;
|
||||||
|
|
||||||
|
printf("%016lx: ", (long)src);
|
||||||
|
|
||||||
|
while (src < lineend && src < end) {
|
||||||
|
printf("%02x ", *src++);
|
||||||
|
line_bytes++;
|
||||||
|
}
|
||||||
|
if (line_bytes < 8)
|
||||||
|
printf("%*s", (8 - line_bytes) * 3, "");
|
||||||
|
|
||||||
|
src -= line_bytes;
|
||||||
|
while (src < lineend && src < end && fb.pos < fb.buf + fb.len) {
|
||||||
|
uint8_t byte = *src++;
|
||||||
|
|
||||||
|
if (isprint(byte))
|
||||||
|
*fb.pos++ = byte;
|
||||||
|
else
|
||||||
|
*fb.pos++ = '.';
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* parse_netlink_msg
|
* parse_netlink_msg
|
||||||
*/
|
*/
|
||||||
@ -582,6 +685,7 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm)
|
|||||||
struct nlmsghdr *hdr;
|
struct nlmsghdr *hdr;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
|
fpm_listener_hexdump(buf, buf_len);
|
||||||
ctx = &ctx_space;
|
ctx = &ctx_space;
|
||||||
|
|
||||||
hdr = (struct nlmsghdr *)buf;
|
hdr = (struct nlmsghdr *)buf;
|
||||||
@ -667,7 +771,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
memset(glob, 0, sizeof(*glob));
|
memset(glob, 0, sizeof(*glob));
|
||||||
|
|
||||||
while ((r = getopt(argc, argv, "rd")) != -1) {
|
while ((r = getopt(argc, argv, "rdv")) != -1) {
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case 'r':
|
case 'r':
|
||||||
glob->reflect = true;
|
glob->reflect = true;
|
||||||
@ -675,6 +779,9 @@ int main(int argc, char **argv)
|
|||||||
case 'd':
|
case 'd':
|
||||||
fork_daemon = true;
|
fork_daemon = true;
|
||||||
break;
|
break;
|
||||||
|
case 'v':
|
||||||
|
glob->dump_hex = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user