diff options
| -rw-r--r-- | lib/mpls.h | 3 | ||||
| -rw-r--r-- | lib/zclient.c | 42 | ||||
| -rw-r--r-- | lib/zclient.h | 5 | ||||
| -rw-r--r-- | zebra/zebra_mpls.h | 2 | ||||
| -rw-r--r-- | zebra/zserv.c | 5 | 
5 files changed, 44 insertions, 13 deletions
diff --git a/lib/mpls.h b/lib/mpls.h index 025770d479..bf98eecd81 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -44,6 +44,9 @@  #define MPLS_DEFAULT_MIN_SRGB_LABEL        16000  #define MPLS_DEFAULT_MAX_SRGB_LABEL        23999 +/* Maximum # labels that can be pushed. */ +#define MPLS_MAX_LABELS                    16 +  #define IS_MPLS_RESERVED_LABEL(label)                                          \  	(label >= MPLS_MIN_RESERVED_LABEL && label <= MPLS_MAX_RESERVED_LABEL) diff --git a/lib/zclient.c b/lib/zclient.c index 3f5c7a0f6f..e063c7151f 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -970,10 +970,26 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api)  				break;  			} -			/* For labeled-unicast, each nexthop is followed -			 * by label. */ -			if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) -				stream_putl(s, api_nh->label); +			/* MPLS labels for BGP-LU or Segment Routing */ +			if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) { +				if (api_nh->label_num > MPLS_MAX_LABELS) { +					char buf[PREFIX2STR_BUFFER]; +					prefix2str(&api->prefix, buf, +						   sizeof(buf)); +					zlog_err( +						"%s: prefix %s: can't encode " +						"%u labels (maximum is %u)", +						__func__, buf, +						api_nh->label_num, +						MPLS_MAX_LABELS); +					return -1; +				} + +				stream_putc(s, api_nh->label_num); +				stream_put(s, &api_nh->labels[0], +					   api_nh->label_num +						   * sizeof(mpls_label_t)); +			}  		}  	} @@ -1064,11 +1080,21 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)  				break;  			} -			/* For labeled-unicast, each nexthop is followed -			 * by label. */ +			/* MPLS labels for BGP-LU or Segment Routing */  			if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) { -				stream_get(&api_nh->label, s, -					   sizeof(api_nh->label)); +				api_nh->label_num = stream_getc(s); + +				if (api_nh->label_num > MPLS_MAX_LABELS) { +					zlog_warn( +						"%s: invalid number of MPLS " +						"labels (%u)", +						__func__, api_nh->label_num); +					return -1; +				} + +				stream_get(&api_nh->labels[0], s, +					   api_nh->label_num +						   * sizeof(mpls_label_t));  			}  		}  	} diff --git a/lib/zclient.h b/lib/zclient.h index 2e450ed398..40ddbf62df 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -230,7 +230,10 @@ struct zapi_nexthop {  	enum nexthop_types_t type;  	ifindex_t ifindex;  	union g_addr gate; -	mpls_label_t label; + +	/* MPLS labels for BGP-LU or Segment Routing */ +	uint8_t label_num; +	mpls_label_t labels[MPLS_MAX_LABELS];  };  struct zapi_route { diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index 6bddc4d00f..c8df8670f4 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -37,8 +37,6 @@  /* Definitions and macros. */ -#define MPLS_MAX_LABELS 16  /* Maximum # labels that can be pushed. */ -  #define NHLFE_FAMILY(nhlfe)                                                    \  	(((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6                          \  	  || (nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)              \ diff --git a/zebra/zserv.c b/zebra/zserv.c index 94e34865b5..de475dccfd 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1222,8 +1222,9 @@ static int zread_route_add(struct zserv *client, u_short length,  				label_type =  					lsp_type_from_re_type(client->proto); -				nexthop_add_labels(nexthop, label_type, 1, -						   &api_nh->label); +				nexthop_add_labels(nexthop, label_type, +						   api_nh->label_num, +						   &api_nh->labels[0]);  			}  		}  	}  | 
