mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 13:33:15 +00:00
Merge pull request #1766 from donaldsharp/label_label_label
zebra: implement recursive MPLS labels
This commit is contained in:
commit
ac71b27a7c
@ -840,6 +840,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
|
|||||||
{
|
{
|
||||||
struct mpls_label_stack *nh_label;
|
struct mpls_label_stack *nh_label;
|
||||||
mpls_lse_t out_lse[MPLS_MAX_LABELS];
|
mpls_lse_t out_lse[MPLS_MAX_LABELS];
|
||||||
|
int num_labels = 0;
|
||||||
char label_buf[256];
|
char label_buf[256];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -849,56 +850,54 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
|
|||||||
* you fix this assumption
|
* you fix this assumption
|
||||||
*/
|
*/
|
||||||
label_buf[0] = '\0';
|
label_buf[0] = '\0';
|
||||||
/* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP
|
|
||||||
* (in the case of LER)
|
|
||||||
*/
|
|
||||||
nh_label = nexthop->nh_label;
|
|
||||||
if (rtmsg->rtm_family == AF_MPLS) {
|
|
||||||
assert(nh_label);
|
|
||||||
assert(nh_label->num_labels == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nh_label && nh_label->num_labels) {
|
assert(nexthop);
|
||||||
int i, num_labels = 0;
|
for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
|
||||||
u_int32_t bos;
|
|
||||||
char label_buf1[20];
|
char label_buf1[20];
|
||||||
|
|
||||||
for (i = 0; i < nh_label->num_labels; i++) {
|
nh_label = nh->nh_label;
|
||||||
if (nh_label->label[i] != MPLS_LABEL_IMPLICIT_NULL) {
|
if (!nh_label || !nh_label->num_labels)
|
||||||
bos = ((i == (nh_label->num_labels - 1)) ? 1
|
continue;
|
||||||
: 0);
|
|
||||||
out_lse[i] = mpls_lse_encode(nh_label->label[i],
|
|
||||||
0, 0, bos);
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL) {
|
|
||||||
if (!num_labels)
|
|
||||||
sprintf(label_buf, "label %u",
|
|
||||||
nh_label->label[i]);
|
|
||||||
else {
|
|
||||||
sprintf(label_buf1, "/%u",
|
|
||||||
nh_label->label[i]);
|
|
||||||
strlcat(label_buf, label_buf1,
|
|
||||||
sizeof(label_buf));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num_labels++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num_labels) {
|
|
||||||
if (rtmsg->rtm_family == AF_MPLS)
|
|
||||||
addattr_l(nlmsg, req_size, RTA_NEWDST, &out_lse,
|
|
||||||
num_labels * sizeof(mpls_lse_t));
|
|
||||||
else {
|
|
||||||
struct rtattr *nest;
|
|
||||||
u_int16_t encap = LWTUNNEL_ENCAP_MPLS;
|
|
||||||
|
|
||||||
addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE,
|
for (int i = 0; i < nh_label->num_labels; i++) {
|
||||||
&encap, sizeof(u_int16_t));
|
if (nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL)
|
||||||
nest = addattr_nest(nlmsg, req_size, RTA_ENCAP);
|
continue;
|
||||||
addattr_l(nlmsg, req_size, MPLS_IPTUNNEL_DST,
|
|
||||||
&out_lse,
|
if (IS_ZEBRA_DEBUG_KERNEL) {
|
||||||
num_labels * sizeof(mpls_lse_t));
|
if (!num_labels)
|
||||||
addattr_nest_end(nlmsg, nest);
|
sprintf(label_buf, "label %u",
|
||||||
|
nh_label->label[i]);
|
||||||
|
else {
|
||||||
|
sprintf(label_buf1, "/%u",
|
||||||
|
nh_label->label[i]);
|
||||||
|
strlcat(label_buf, label_buf1,
|
||||||
|
sizeof(label_buf));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out_lse[num_labels] =
|
||||||
|
mpls_lse_encode(nh_label->label[i], 0, 0, 0);
|
||||||
|
num_labels++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_labels) {
|
||||||
|
/* Set the BoS bit */
|
||||||
|
out_lse[num_labels - 1] |= htonl(1 << MPLS_LS_S_SHIFT);
|
||||||
|
|
||||||
|
if (rtmsg->rtm_family == AF_MPLS)
|
||||||
|
addattr_l(nlmsg, req_size, RTA_NEWDST, &out_lse,
|
||||||
|
num_labels * sizeof(mpls_lse_t));
|
||||||
|
else {
|
||||||
|
struct rtattr *nest;
|
||||||
|
u_int16_t encap = LWTUNNEL_ENCAP_MPLS;
|
||||||
|
|
||||||
|
addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, &encap,
|
||||||
|
sizeof(u_int16_t));
|
||||||
|
nest = addattr_nest(nlmsg, req_size, RTA_ENCAP);
|
||||||
|
addattr_l(nlmsg, req_size, MPLS_IPTUNNEL_DST, &out_lse,
|
||||||
|
num_labels * sizeof(mpls_lse_t));
|
||||||
|
addattr_nest_end(nlmsg, nest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1045,6 +1044,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
|
|||||||
{
|
{
|
||||||
struct mpls_label_stack *nh_label;
|
struct mpls_label_stack *nh_label;
|
||||||
mpls_lse_t out_lse[MPLS_MAX_LABELS];
|
mpls_lse_t out_lse[MPLS_MAX_LABELS];
|
||||||
|
int num_labels = 0;
|
||||||
char label_buf[256];
|
char label_buf[256];
|
||||||
|
|
||||||
rtnh->rtnh_len = sizeof(*rtnh);
|
rtnh->rtnh_len = sizeof(*rtnh);
|
||||||
@ -1059,63 +1059,60 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
|
|||||||
* you fix this assumption
|
* you fix this assumption
|
||||||
*/
|
*/
|
||||||
label_buf[0] = '\0';
|
label_buf[0] = '\0';
|
||||||
/* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP
|
|
||||||
* (in the case of LER)
|
|
||||||
*/
|
|
||||||
nh_label = nexthop->nh_label;
|
|
||||||
if (rtmsg->rtm_family == AF_MPLS) {
|
|
||||||
assert(nh_label);
|
|
||||||
assert(nh_label->num_labels == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nh_label && nh_label->num_labels) {
|
assert(nexthop);
|
||||||
int i, num_labels = 0;
|
for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
|
||||||
u_int32_t bos;
|
|
||||||
char label_buf1[20];
|
char label_buf1[20];
|
||||||
|
|
||||||
for (i = 0; i < nh_label->num_labels; i++) {
|
nh_label = nh->nh_label;
|
||||||
if (nh_label->label[i] != MPLS_LABEL_IMPLICIT_NULL) {
|
if (!nh_label || !nh_label->num_labels)
|
||||||
bos = ((i == (nh_label->num_labels - 1)) ? 1
|
continue;
|
||||||
: 0);
|
|
||||||
out_lse[i] = mpls_lse_encode(nh_label->label[i],
|
|
||||||
0, 0, bos);
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL) {
|
|
||||||
if (!num_labels)
|
|
||||||
sprintf(label_buf, "label %u",
|
|
||||||
nh_label->label[i]);
|
|
||||||
else {
|
|
||||||
sprintf(label_buf1, "/%u",
|
|
||||||
nh_label->label[i]);
|
|
||||||
strlcat(label_buf, label_buf1,
|
|
||||||
sizeof(label_buf));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num_labels++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num_labels) {
|
|
||||||
if (rtmsg->rtm_family == AF_MPLS) {
|
|
||||||
rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_NEWDST,
|
|
||||||
&out_lse,
|
|
||||||
num_labels * sizeof(mpls_lse_t));
|
|
||||||
rtnh->rtnh_len += RTA_LENGTH(
|
|
||||||
num_labels * sizeof(mpls_lse_t));
|
|
||||||
} else {
|
|
||||||
struct rtattr *nest;
|
|
||||||
u_int16_t encap = LWTUNNEL_ENCAP_MPLS;
|
|
||||||
int len = rta->rta_len;
|
|
||||||
|
|
||||||
rta_addattr_l(rta, NL_PKT_BUF_SIZE,
|
for (int i = 0; i < nh_label->num_labels; i++) {
|
||||||
RTA_ENCAP_TYPE, &encap,
|
if (nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL)
|
||||||
sizeof(u_int16_t));
|
continue;
|
||||||
nest = rta_nest(rta, NL_PKT_BUF_SIZE,
|
|
||||||
RTA_ENCAP);
|
if (IS_ZEBRA_DEBUG_KERNEL) {
|
||||||
rta_addattr_l(rta, NL_PKT_BUF_SIZE,
|
if (!num_labels)
|
||||||
MPLS_IPTUNNEL_DST, &out_lse,
|
sprintf(label_buf, "label %u",
|
||||||
num_labels * sizeof(mpls_lse_t));
|
nh_label->label[i]);
|
||||||
rta_nest_end(rta, nest);
|
else {
|
||||||
rtnh->rtnh_len += rta->rta_len - len;
|
sprintf(label_buf1, "/%u",
|
||||||
|
nh_label->label[i]);
|
||||||
|
strlcat(label_buf, label_buf1,
|
||||||
|
sizeof(label_buf));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out_lse[num_labels] =
|
||||||
|
mpls_lse_encode(nh_label->label[i], 0, 0, 0);
|
||||||
|
num_labels++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_labels) {
|
||||||
|
/* Set the BoS bit */
|
||||||
|
out_lse[num_labels - 1] |= htonl(1 << MPLS_LS_S_SHIFT);
|
||||||
|
|
||||||
|
if (rtmsg->rtm_family == AF_MPLS) {
|
||||||
|
rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_NEWDST,
|
||||||
|
&out_lse,
|
||||||
|
num_labels * sizeof(mpls_lse_t));
|
||||||
|
rtnh->rtnh_len +=
|
||||||
|
RTA_LENGTH(num_labels * sizeof(mpls_lse_t));
|
||||||
|
} else {
|
||||||
|
struct rtattr *nest;
|
||||||
|
u_int16_t encap = LWTUNNEL_ENCAP_MPLS;
|
||||||
|
int len = rta->rta_len;
|
||||||
|
|
||||||
|
rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_ENCAP_TYPE,
|
||||||
|
&encap, sizeof(u_int16_t));
|
||||||
|
nest = rta_nest(rta, NL_PKT_BUF_SIZE, RTA_ENCAP);
|
||||||
|
rta_addattr_l(rta, NL_PKT_BUF_SIZE, MPLS_IPTUNNEL_DST,
|
||||||
|
&out_lse,
|
||||||
|
num_labels * sizeof(mpls_lse_t));
|
||||||
|
rta_nest_end(rta, nest);
|
||||||
|
rtnh->rtnh_len += rta->rta_len - len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user