mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 15:03:27 +00:00
zebra: increase maximum label stack depth
* Bump MPLS_MAX_LABELS from 2 to 16; * Adjust the static_nh_label structure and the mpls_label2str() function; * On OpenBSD, print an error message when trying to push more than one label at once (kernel limitation). While here, add support for MPLSv6 FTNs in OpenBSD. This is not the full package. We still can't pop multiple labels at once, or do things like swap a label and push other ones. We'll address that in the future. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
1d84515ca9
commit
5e8c8947e3
@ -71,6 +71,27 @@ static int sin_masklen(struct in_addr mask)
|
||||
}
|
||||
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
static int kernel_rtm_add_labels(struct nexthop_label *nh_label,
|
||||
struct sockaddr_mpls *smpls)
|
||||
{
|
||||
if (nh_label->num_labels > 1) {
|
||||
zlog_warn(
|
||||
"%s: can't push %u labels at "
|
||||
"once (maximum is 1)",
|
||||
__func__, nh_label->num_labels);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(smpls, 0, sizeof(*smpls));
|
||||
smpls->smpls_len = sizeof(*smpls);
|
||||
smpls->smpls_family = AF_MPLS;
|
||||
smpls->smpls_label = htonl(nh_label->label[0] << MPLS_LABEL_OFFSET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Interface between zebra message and rtm message. */
|
||||
static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
|
||||
|
||||
@ -150,15 +171,11 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
|
||||
}
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
if (nexthop->nh_label) {
|
||||
memset(&smpls, 0, sizeof(smpls));
|
||||
smpls.smpls_len = sizeof(smpls);
|
||||
smpls.smpls_family = AF_MPLS;
|
||||
smpls.smpls_label =
|
||||
htonl(nexthop->nh_label->label[0]
|
||||
<< MPLS_LABEL_OFFSET);
|
||||
smplsp = (union sockunion *)&smpls;
|
||||
}
|
||||
if (nexthop->nh_label
|
||||
&& !kernel_rtm_add_labels(nexthop->nh_label,
|
||||
&smpls))
|
||||
continue;
|
||||
smplsp = (union sockunion *)&smpls;
|
||||
#endif
|
||||
|
||||
error = rtm_write(
|
||||
@ -266,6 +283,10 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
|
||||
{
|
||||
struct sockaddr_in6 *mask;
|
||||
struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
|
||||
#ifdef __OpenBSD__
|
||||
struct sockaddr_mpls smpls;
|
||||
#endif
|
||||
union sockunion *smplsp = NULL;
|
||||
struct nexthop *nexthop;
|
||||
int nexthop_num = 0;
|
||||
ifindex_t ifindex = 0;
|
||||
@ -338,10 +359,17 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
|
||||
mask = &sin_mask;
|
||||
}
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
if (nexthop->nh_label
|
||||
&& !kernel_rtm_add_labels(nexthop->nh_label, &smpls))
|
||||
continue;
|
||||
smplsp = (union sockunion *)&smpls;
|
||||
#endif
|
||||
|
||||
error = rtm_write(cmd, (union sockunion *)&sin_dest,
|
||||
(union sockunion *)mask,
|
||||
gate ? (union sockunion *)&sin_gate : NULL,
|
||||
NULL, ifindex, re->flags, re->metric);
|
||||
smplsp, ifindex, re->flags, re->metric);
|
||||
|
||||
#if 0
|
||||
if (error)
|
||||
|
@ -1671,27 +1671,20 @@ int mpls_str2label(const char *label_str, u_int8_t *num_labels,
|
||||
char *mpls_label2str(u_int8_t num_labels, mpls_label_t *labels, char *buf,
|
||||
int len, int pretty)
|
||||
{
|
||||
char *buf_ptr = buf;
|
||||
char label_buf[BUFSIZ];
|
||||
int i;
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
if (pretty) {
|
||||
if (num_labels == 1) {
|
||||
label2str(labels[0], buf, len);
|
||||
} else if (num_labels == 2) {
|
||||
label2str(labels[0], buf, len);
|
||||
buf_ptr += strlen(buf);
|
||||
|
||||
snprintf(buf_ptr, len, "/");
|
||||
buf_ptr++;
|
||||
|
||||
label2str(labels[1], buf_ptr, len);
|
||||
}
|
||||
} else {
|
||||
if (num_labels == 1)
|
||||
snprintf(buf, len, "%u", labels[0]);
|
||||
else if (num_labels == 2)
|
||||
snprintf(buf, len, "%u/%u", labels[0], labels[1]);
|
||||
for (i = 0; i < num_labels; i++) {
|
||||
if (i != 0)
|
||||
strlcat(buf, "/", len);
|
||||
if (pretty)
|
||||
label2str(labels[i], label_buf, sizeof(label_buf));
|
||||
else
|
||||
snprintf(label_buf, sizeof(label_buf), "%u", labels[i]);
|
||||
strlcat(buf, label_buf, len);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
/* Definitions and macros. */
|
||||
|
||||
#define MPLS_MAX_LABELS 2 /* Maximum # labels that can be pushed. */
|
||||
#define MPLS_MAX_LABELS 16 /* Maximum # labels that can be pushed. */
|
||||
|
||||
#define NHLFE_FAMILY(nhlfe) \
|
||||
(((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6 \
|
||||
|
@ -256,6 +256,15 @@ static int kernel_lsp_cmd(int action, zebra_lsp_t *lsp)
|
||||
|| (action == RTM_DELETE
|
||||
&& (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)
|
||||
&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)))) {
|
||||
if (nhlfe->nexthop->nh_label->num_labels > 1) {
|
||||
zlog_warn(
|
||||
"%s: can't push %u labels at once "
|
||||
"(maximum is 1)",
|
||||
__func__,
|
||||
nhlfe->nexthop->nh_label->num_labels);
|
||||
continue;
|
||||
}
|
||||
|
||||
nexthop_num++;
|
||||
|
||||
switch (NHLFE_FAMILY(nhlfe)) {
|
||||
|
@ -22,11 +22,13 @@
|
||||
#ifndef __ZEBRA_STATIC_H__
|
||||
#define __ZEBRA_STATIC_H__
|
||||
|
||||
#include "zebra/zebra_mpls.h"
|
||||
|
||||
/* Static route label information */
|
||||
struct static_nh_label {
|
||||
u_int8_t num_labels;
|
||||
u_int8_t reserved[3];
|
||||
mpls_label_t label[2];
|
||||
mpls_label_t label[MPLS_MAX_LABELS];
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
Loading…
Reference in New Issue
Block a user