mirror of
https://github.com/FRRouting/frr.git
synced 2025-05-01 05:57:15 +02:00
zebra: Handle nhg_hash_entry encaps/more debugging
Add code for handling nexthop group hash entry encaps and sending them to the kernel. Add some more debugging information for the encaps and groups in general. Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
This commit is contained in:
parent
b7537db639
commit
8d03bc501b
|
@ -50,6 +50,7 @@
|
||||||
#include "vty.h"
|
#include "vty.h"
|
||||||
#include "mpls.h"
|
#include "mpls.h"
|
||||||
#include "vxlan.h"
|
#include "vxlan.h"
|
||||||
|
#include "printfrr.h"
|
||||||
|
|
||||||
#include "zebra/zapi_msg.h"
|
#include "zebra/zapi_msg.h"
|
||||||
#include "zebra/zebra_ns.h"
|
#include "zebra/zebra_ns.h"
|
||||||
|
@ -1895,19 +1896,20 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in)
|
||||||
return suc;
|
return suc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Char length to debug ID with */
|
||||||
* _netlink_nexthop_build_group() - Build a nexthop_grp struct for a nlmsg
|
#define ID_LENGTH 10
|
||||||
*
|
|
||||||
* @n: Netlink message header struct
|
|
||||||
* @req_size: Size allocated for this message
|
|
||||||
* @z_grp: Array of nh_grp structs
|
|
||||||
* @count: How many depencies there are
|
|
||||||
*/
|
|
||||||
static void _netlink_nexthop_build_group(struct nlmsghdr *n, size_t req_size,
|
static void _netlink_nexthop_build_group(struct nlmsghdr *n, size_t req_size,
|
||||||
|
uint32_t id,
|
||||||
const struct nh_grp *z_grp,
|
const struct nh_grp *z_grp,
|
||||||
const uint8_t count)
|
const uint8_t count)
|
||||||
{
|
{
|
||||||
struct nexthop_grp grp[count];
|
struct nexthop_grp grp[count];
|
||||||
|
/* Need space for max group size, "/", and null term */
|
||||||
|
char buf[(MULTIPATH_NUM * (ID_LENGTH + 1)) + 1];
|
||||||
|
char buf1[ID_LENGTH + 2];
|
||||||
|
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
memset(grp, 0, sizeof(grp));
|
memset(grp, 0, sizeof(grp));
|
||||||
|
|
||||||
|
@ -1915,9 +1917,23 @@ static void _netlink_nexthop_build_group(struct nlmsghdr *n, size_t req_size,
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
grp[i].id = z_grp[i].id;
|
grp[i].id = z_grp[i].id;
|
||||||
grp[i].weight = z_grp[i].weight;
|
grp[i].weight = z_grp[i].weight;
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_KERNEL) {
|
||||||
|
if (i == 0)
|
||||||
|
snprintf(buf, sizeof(buf1), "group %u",
|
||||||
|
grp[i].id);
|
||||||
|
else {
|
||||||
|
snprintf(buf1, sizeof(buf1), "/%u",
|
||||||
|
grp[i].id);
|
||||||
|
strlcat(buf, buf1, sizeof(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
addattr_l(n, req_size, NHA_GROUP, grp, count * sizeof(*grp));
|
addattr_l(n, req_size, NHA_GROUP, grp, count * sizeof(*grp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
|
zlog_debug("%s: ID (%u): %s", __func__, id, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1935,11 +1951,18 @@ static int netlink_nexthop(int cmd, struct zebra_dplane_ctx *ctx)
|
||||||
char buf[NL_PKT_BUF_SIZE];
|
char buf[NL_PKT_BUF_SIZE];
|
||||||
} req;
|
} req;
|
||||||
|
|
||||||
|
mpls_lse_t out_lse[MPLS_MAX_LABELS];
|
||||||
|
char label_buf[256];
|
||||||
|
int num_labels = 0;
|
||||||
|
size_t req_size = sizeof(req);
|
||||||
|
|
||||||
/* Nothing to do if the kernel doesn't support nexthop objects */
|
/* Nothing to do if the kernel doesn't support nexthop objects */
|
||||||
if (!supports_nh)
|
if (!supports_nh)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
label_buf[0] = '\0';
|
||||||
|
|
||||||
|
memset(&req, 0, req_size);
|
||||||
|
|
||||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg));
|
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg));
|
||||||
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
|
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
|
||||||
|
@ -1962,12 +1985,12 @@ static int netlink_nexthop(int cmd, struct zebra_dplane_ctx *ctx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
addattr32(&req.n, sizeof(req), NHA_ID, id);
|
addattr32(&req.n, req_size, NHA_ID, id);
|
||||||
|
|
||||||
if (cmd == RTM_NEWNEXTHOP) {
|
if (cmd == RTM_NEWNEXTHOP) {
|
||||||
if (dplane_ctx_get_nhe_nh_grp_count(ctx))
|
if (dplane_ctx_get_nhe_nh_grp_count(ctx))
|
||||||
_netlink_nexthop_build_group(
|
_netlink_nexthop_build_group(
|
||||||
&req.n, sizeof(req),
|
&req.n, req_size, id,
|
||||||
dplane_ctx_get_nhe_nh_grp(ctx),
|
dplane_ctx_get_nhe_nh_grp(ctx),
|
||||||
dplane_ctx_get_nhe_nh_grp_count(ctx));
|
dplane_ctx_get_nhe_nh_grp_count(ctx));
|
||||||
else {
|
else {
|
||||||
|
@ -1983,20 +2006,20 @@ static int netlink_nexthop(int cmd, struct zebra_dplane_ctx *ctx)
|
||||||
switch (nh->type) {
|
switch (nh->type) {
|
||||||
case NEXTHOP_TYPE_IPV4:
|
case NEXTHOP_TYPE_IPV4:
|
||||||
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
addattr_l(&req.n, sizeof(req), NHA_GATEWAY,
|
addattr_l(&req.n, req_size, NHA_GATEWAY,
|
||||||
&nh->gate.ipv4, IPV4_MAX_BYTELEN);
|
&nh->gate.ipv4, IPV4_MAX_BYTELEN);
|
||||||
break;
|
break;
|
||||||
case NEXTHOP_TYPE_IPV6:
|
case NEXTHOP_TYPE_IPV6:
|
||||||
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||||
addattr_l(&req.n, sizeof(req), NHA_GATEWAY,
|
addattr_l(&req.n, req_size, NHA_GATEWAY,
|
||||||
&nh->gate.ipv6, IPV6_MAX_BYTELEN);
|
&nh->gate.ipv6, IPV6_MAX_BYTELEN);
|
||||||
break;
|
break;
|
||||||
case NEXTHOP_TYPE_BLACKHOLE:
|
case NEXTHOP_TYPE_BLACKHOLE:
|
||||||
// TODO: Handle this, Can't have OIF/Encap with
|
addattr_l(&req.n, req_size, NHA_BLACKHOLE, NULL,
|
||||||
// it
|
0);
|
||||||
addattr_l(&req.n, sizeof(req), NHA_BLACKHOLE,
|
/* Blackhole shouldn't have anymore attributes
|
||||||
NULL, 0);
|
*/
|
||||||
break;
|
goto nexthop_done;
|
||||||
case NEXTHOP_TYPE_IFINDEX:
|
case NEXTHOP_TYPE_IFINDEX:
|
||||||
/* Don't need anymore info for this */
|
/* Don't need anymore info for this */
|
||||||
break;
|
break;
|
||||||
|
@ -2009,8 +2032,53 @@ static int netlink_nexthop(int cmd, struct zebra_dplane_ctx *ctx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
addattr32(&req.n, sizeof(req), NHA_OIF, nh->ifindex);
|
addattr32(&req.n, req_size, NHA_OIF, nh->ifindex);
|
||||||
// TODO: Handle Encap
|
|
||||||
|
num_labels =
|
||||||
|
build_label_stack(nh->nh_label, out_lse,
|
||||||
|
label_buf, sizeof(label_buf));
|
||||||
|
|
||||||
|
if (num_labels) {
|
||||||
|
/* Set the BoS bit */
|
||||||
|
out_lse[num_labels - 1] |=
|
||||||
|
htonl(1 << MPLS_LS_S_SHIFT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: MPLS unsupported for now in kernel.
|
||||||
|
*/
|
||||||
|
if (req.nhm.nh_family == AF_MPLS)
|
||||||
|
goto nexthop_done;
|
||||||
|
#if 0
|
||||||
|
addattr_l(&req.n, req_size, NHA_NEWDST,
|
||||||
|
&out_lse,
|
||||||
|
num_labels
|
||||||
|
* sizeof(mpls_lse_t));
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
struct rtattr *nest;
|
||||||
|
uint16_t encap = LWTUNNEL_ENCAP_MPLS;
|
||||||
|
|
||||||
|
addattr_l(&req.n, req_size,
|
||||||
|
NHA_ENCAP_TYPE, &encap,
|
||||||
|
sizeof(uint16_t));
|
||||||
|
nest = addattr_nest(&req.n, req_size,
|
||||||
|
NHA_ENCAP);
|
||||||
|
addattr_l(&req.n, req_size,
|
||||||
|
MPLS_IPTUNNEL_DST, &out_lse,
|
||||||
|
num_labels
|
||||||
|
* sizeof(mpls_lse_t));
|
||||||
|
addattr_nest_end(&req.n, nest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nexthop_done:
|
||||||
|
if (IS_ZEBRA_DEBUG_KERNEL) {
|
||||||
|
char buf[NEXTHOP_STRLEN];
|
||||||
|
|
||||||
|
snprintfrr(buf, sizeof(buf), "%pNHv", nh);
|
||||||
|
zlog_debug("%s: ID (%u): %s (%u) %s ", __func__,
|
||||||
|
id, buf, nh->vrf_id, label_buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
req.nhm.nh_protocol = zebra2proto(dplane_ctx_get_nhe_type(ctx));
|
req.nhm.nh_protocol = zebra2proto(dplane_ctx_get_nhe_type(ctx));
|
||||||
|
|
Loading…
Reference in a new issue