summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2017-08-21 00:57:36 +0200
committerRenato Westphal <renato@opensourcerouting.org>2017-08-23 23:58:35 +0200
commit52dd3aa483441880ac46eb4bb50069d26dbecf13 (patch)
tree07765fedaa8990f775a4a1baee54ae711759cb68
parentbabeld: unify kernel_route_v4() and kernel_route_v6() (diff)
downloadfrr-52dd3aa483441880ac46eb4bb50069d26dbecf13.tar.xz
frr-52dd3aa483441880ac46eb4bb50069d26dbecf13.zip
zapi: add support for routes with multiple labels
This will be necessary for the Segment Routing feature. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
-rw-r--r--lib/mpls.h3
-rw-r--r--lib/zclient.c42
-rw-r--r--lib/zclient.h5
-rw-r--r--zebra/zebra_mpls.h2
-rw-r--r--zebra/zserv.c5
5 files changed, 44 insertions, 13 deletions
diff --git a/lib/mpls.h b/lib/mpls.h
index 025770d47..bf98eecd8 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 3f5c7a0f6..e063c7151 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 2e450ed39..40ddbf62d 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 6bddc4d00..c8df8670f 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 94e34865b..de475dccf 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]);
}
}
}