From: Philippe Guibert Date: Thu, 12 Jan 2023 07:33:50 +0000 (+0100) Subject: zebra: accept LSP entries with an mpls-less outgoing interface X-Git-Tag: base_9.0~73^2~16 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=bd21ba79aa13b7421baaa09335901c1dafeb158a;p=matthieu%2Ffrr.git zebra: accept LSP entries with an mpls-less outgoing interface The ZEBRA_MPLS_LABELS_[ADD/DELETE/REPLACE] messages may change an LSP entry based on an incoming MPLS entry, followed by a given next-hop. Having a next hop with no label information inside is rejected by the zebra layer. As illustration, the following ZAPI message would be rejected, because the next hop does not contain any label information. > ip -f mpls route add 105 via inet 192.0.2.45 At the same time, such configuration is desirable to be supported: An attempt has been done to configure the next-hop with an implicit- null label. But the message is rejected by the kernel: > ip -f mpls route add 104 as 3 via inet 192.0.2.45 > Error: Implicit NULL Label (3) can not be used in encapsulation. The commit proposes to accept ZEBRA_MPLS_LABELS_[XX] messages with a nexthop that does not contain any label information. Signed-off-by: Philippe Guibert --- diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index f1a99d89ce..11eee62c49 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1325,14 +1325,6 @@ static struct zebra_nhlfe *nhlfe_add(struct zebra_lsp *lsp, if (!lsp) return NULL; - /* Must have labels */ - if (num_labels == 0 || labels == NULL) { - if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug("%s: invalid nexthop: no labels", __func__); - - return NULL; - } - /* Allocate new object */ nhlfe = nhlfe_alloc(lsp, lsp_type, gtype, gate, ifindex, num_labels, labels); @@ -1510,16 +1502,18 @@ static json_object *nhlfe_json(struct zebra_nhlfe *nhlfe) json_nhlfe = json_object_new_object(); json_object_string_add(json_nhlfe, "type", nhlfe_type2str(nhlfe->type)); - json_object_int_add(json_nhlfe, "outLabel", - nexthop->nh_label->label[0]); - - json_label_stack = json_object_new_array(); - json_object_object_add(json_nhlfe, "outLabelStack", json_label_stack); - for (i = 0; i < nexthop->nh_label->num_labels; i++) - json_object_array_add( - json_label_stack, - json_object_new_int(nexthop->nh_label->label[i])); - + if (nexthop->nh_label) { + json_object_int_add(json_nhlfe, "outLabel", + nexthop->nh_label->label[0]); + json_label_stack = json_object_new_array(); + json_object_object_add(json_nhlfe, "outLabelStack", + json_label_stack); + for (i = 0; i < nexthop->nh_label->num_labels; i++) + json_object_array_add( + json_label_stack, + json_object_new_int( + nexthop->nh_label->label[i])); + } json_object_int_add(json_nhlfe, "distance", nhlfe->distance); if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) @@ -2270,11 +2264,9 @@ struct zebra_nhlfe *zebra_mpls_lsp_add_nh(struct zebra_lsp *lsp, { struct zebra_nhlfe *nhlfe; - if (nh->nh_label == NULL || nh->nh_label->num_labels == 0) - return NULL; - nhlfe = nhlfe_add(lsp, lsp_type, nh->type, &nh->gate, nh->ifindex, - nh->nh_label->num_labels, nh->nh_label->label, + nh->nh_label ? nh->nh_label->num_labels : 0, + nh->nh_label ? nh->nh_label->label : NULL, false /*backup*/); return nhlfe; @@ -2290,12 +2282,9 @@ struct zebra_nhlfe *zebra_mpls_lsp_add_backup_nh(struct zebra_lsp *lsp, { struct zebra_nhlfe *nhlfe; - if (nh->nh_label == NULL || nh->nh_label->num_labels == 0) - return NULL; - - nhlfe = nhlfe_add(lsp, lsp_type, nh->type, &nh->gate, - nh->ifindex, nh->nh_label->num_labels, - nh->nh_label->label, true); + nhlfe = nhlfe_add(lsp, lsp_type, nh->type, &nh->gate, nh->ifindex, + nh->nh_label ? nh->nh_label->num_labels : 0, + nh->nh_label ? nh->nh_label->label : NULL, true); return nhlfe; } @@ -3133,13 +3122,18 @@ lsp_add_nhlfe(struct zebra_lsp *lsp, enum lsp_types_t type, struct nexthop *nh = nhlfe->nexthop; assert(nh); - assert(nh->nh_label); /* Clear deleted flag (in case it was set) */ UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED); - if (nh->nh_label->num_labels == num_out_labels - && !memcmp(nh->nh_label->label, out_labels, - sizeof(mpls_label_t) * num_out_labels)) + + if (!nh->nh_label || num_out_labels == 0) + /* No change */ + return nhlfe; + + if (nh->nh_label && + nh->nh_label->num_labels == num_out_labels && + !memcmp(nh->nh_label->label, out_labels, + sizeof(mpls_label_t) * num_out_labels)) /* No change */ return nhlfe; @@ -3160,7 +3154,7 @@ lsp_add_nhlfe(struct zebra_lsp *lsp, enum lsp_types_t type, } /* Update out label(s), trigger processing. */ - if (nh->nh_label->num_labels == num_out_labels) + if (nh->nh_label && nh->nh_label->num_labels == num_out_labels) memcpy(nh->nh_label->label, out_labels, sizeof(mpls_label_t) * num_out_labels); else { @@ -3179,8 +3173,11 @@ lsp_add_nhlfe(struct zebra_lsp *lsp, enum lsp_types_t type, char buf2[MPLS_LABEL_STRLEN]; nhlfe2str(nhlfe, buf, sizeof(buf)); - mpls_label2str(num_out_labels, out_labels, buf2, - sizeof(buf2), 0, 0); + if (num_out_labels) + mpls_label2str(num_out_labels, out_labels, buf2, + sizeof(buf2), 0, 0); + else + snprintf(buf2, sizeof(buf2), "-"); zlog_debug("Add LSP in-label %u type %d %snexthop %s out-label(s) %s", lsp->ile.in_label, type, backup_str, buf, @@ -3820,7 +3817,8 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, break; } - if (nexthop->type != NEXTHOP_TYPE_IFINDEX) + if (nexthop->type != NEXTHOP_TYPE_IFINDEX && + nexthop->nh_label) out_label_str = mpls_label2str( nexthop->nh_label->num_labels, &nexthop->nh_label->label[0],