static void ifp2kif(struct interface *, struct kif *);
static void ifc2kaddr(struct interface *, struct connected *,
struct kaddr *);
-static int zebra_send_mpls_labels(int, struct kroute *);
+static int ldp_zebra_send_mpls_labels(int, struct kroute *);
static int ldp_router_id_update(ZAPI_CALLBACK_ARGS);
static int ldp_interface_add(ZAPI_CALLBACK_ARGS);
static int ldp_interface_delete(ZAPI_CALLBACK_ARGS);
}
static int
-zebra_send_mpls_labels(int cmd, struct kroute *kr)
+ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
{
- struct stream *s;
+ struct zapi_labels zl = {};
if (kr->local_label < MPLS_LABEL_RESERVED_MAX ||
kr->remote_label == NO_LABEL)
log_label(kr->local_label), log_label(kr->remote_label),
(cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete");
- /* Reset stream. */
- s = zclient->obuf;
- stream_reset(s);
-
- zclient_create_header(s, cmd, VRF_DEFAULT);
- stream_putc(s, ZEBRA_LSP_LDP);
- stream_putl(s, kr->af);
+ zl.type = ZEBRA_LSP_LDP;
+ zl.prefix.family = kr->af;
+ zl.prefix.prefixlen = kr->prefixlen;
switch (kr->af) {
case AF_INET:
- stream_put_in_addr(s, &kr->prefix.v4);
- stream_putc(s, kr->prefixlen);
- stream_put_in_addr(s, &kr->nexthop.v4);
+ zl.prefix.u.prefix4 = kr->prefix.v4;
+ zl.nexthop.ipv4 = kr->nexthop.v4;
break;
case AF_INET6:
- stream_write(s, (uint8_t *)&kr->prefix.v6, 16);
- stream_putc(s, kr->prefixlen);
- stream_write(s, (uint8_t *)&kr->nexthop.v6, 16);
+ zl.prefix.u.prefix6 = kr->prefix.v6;
+ zl.nexthop.ipv6 = kr->nexthop.v6;
break;
default:
fatalx("kr_change: unknown af");
}
- stream_putl(s, kr->ifindex);
- stream_putc(s, kr->priority);
- stream_putl(s, kr->local_label);
- stream_putl(s, kr->remote_label);
-
- /* Put length at the first point of the stream. */
- stream_putw_at(s, 0, stream_get_endp(s));
+ zl.ifindex = kr->ifindex;
+ zl.distance = kr->priority;
+ zl.local_label = kr->local_label;
+ zl.remote_label = kr->remote_label;
- return (zclient_send_message(zclient));
+ return zebra_send_mpls_labels(zclient, cmd, &zl);
}
int
kr_change(struct kroute *kr)
{
- return (zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, kr));
+ return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, kr));
}
int
kr_delete(struct kroute *kr)
{
- return (zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, kr));
+ return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, kr));
}
int
return zclient_send_message(zclient);
}
+int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
+ struct zapi_labels *zl)
+{
+ if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
+ return -1;
+ return zclient_send_message(zclient);
+}
+
+int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
+{
+ stream_reset(s);
+
+ zclient_create_header(s, cmd, VRF_DEFAULT);
+ stream_putc(s, zl->type);
+ stream_putw(s, zl->prefix.family);
+ stream_put_prefix(s, &zl->prefix);
+ switch (zl->prefix.family) {
+ case AF_INET:
+ stream_put_in_addr(s, &zl->nexthop.ipv4);
+ break;
+ case AF_INET6:
+ stream_write(s, (uint8_t *)&zl->nexthop.ipv6, 16);
+ break;
+ default:
+ flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
+ return -1;
+ }
+ stream_putl(s, zl->ifindex);
+ stream_putc(s, zl->distance);
+ stream_putl(s, zl->local_label);
+ stream_putl(s, zl->remote_label);
+
+ /* Put length at the first point of the stream. */
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return 0;
+}
+
+int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
+{
+ size_t psize;
+
+ memset(zl, 0, sizeof(*zl));
+
+ /* Get data. */
+ STREAM_GETC(s, zl->type);
+ STREAM_GETW(s, zl->prefix.family);
+ STREAM_GETC(s, zl->prefix.prefixlen);
+ psize = PSIZE(zl->prefix.prefixlen);
+
+ switch (zl->prefix.family) {
+ case AF_INET:
+ if (zl->prefix.prefixlen > IPV4_MAX_BITLEN) {
+ zlog_debug(
+ "%s: Specified prefix length %d is greater than a v4 address can support",
+ __PRETTY_FUNCTION__, zl->prefix.prefixlen);
+ return -1;
+ }
+ STREAM_GET(&zl->prefix.u.prefix4.s_addr, s, psize);
+ STREAM_GET(&zl->nexthop.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
+ break;
+ case AF_INET6:
+ if (zl->prefix.prefixlen > IPV6_MAX_BITLEN) {
+ zlog_debug(
+ "%s: Specified prefix length %d is greater than a v6 address can support",
+ __PRETTY_FUNCTION__, zl->prefix.prefixlen);
+ return -1;
+ }
+ STREAM_GET(&zl->prefix.u.prefix6, s, psize);
+ STREAM_GET(&zl->nexthop.ipv6, s, 16);
+ break;
+ default:
+ zlog_debug("%s: Specified AF %d is not supported for this call",
+ __PRETTY_FUNCTION__, zl->prefix.family);
+ return -1;
+ }
+ STREAM_GETL(s, zl->ifindex);
+ STREAM_GETC(s, zl->distance);
+ STREAM_GETL(s, zl->local_label);
+ STREAM_GETL(s, zl->remote_label);
+
+ return 0;
+stream_failure:
+ return -1;
+}
int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
{
uint32_t tableid;
};
+struct zapi_labels {
+ enum lsp_types_t type;
+ struct prefix prefix;
+ union g_addr nexthop;
+ ifindex_t ifindex;
+ uint8_t distance;
+ mpls_label_t local_label;
+ mpls_label_t remote_label;
+};
+
struct zapi_pw {
char ifname[IF_NAMESIZE];
ifindex_t ifindex;
extern int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
uint32_t end);
+extern int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
+ struct zapi_labels *zl);
+extern int zapi_labels_encode(struct stream *s, int cmd,
+ struct zapi_labels *zl);
+extern int zapi_labels_decode(struct stream *s, struct zapi_labels *zl);
+
extern int zebra_send_pw(struct zclient *zclient, int command,
struct zapi_pw *pw);
extern void zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw);
/* Send MPLS Label entry to Zebra for installation or deletion */
static int ospf_zebra_send_mpls_labels(int cmd, struct sr_nhlfe nhlfe)
{
- struct stream *s;
-
- /* Reset stream. */
- s = zclient->obuf;
- stream_reset(s);
-
- zclient_create_header(s, cmd, VRF_DEFAULT);
- stream_putc(s, ZEBRA_LSP_SR);
- /* OSPF Segment Routing currently support only IPv4 */
- stream_putl(s, nhlfe.prefv4.family);
- stream_put_in_addr(s, &nhlfe.prefv4.prefix);
- stream_putc(s, nhlfe.prefv4.prefixlen);
- stream_put_in_addr(s, &nhlfe.nexthop);
- stream_putl(s, nhlfe.ifindex);
- stream_putc(s, OSPF_SR_PRIORITY_DEFAULT);
- stream_putl(s, nhlfe.label_in);
- stream_putl(s, nhlfe.label_out);
-
- /* Put length at the first point of the stream. */
- stream_putw_at(s, 0, stream_get_endp(s));
+ struct zapi_labels zl = {};
if (IS_DEBUG_OSPF_SR)
zlog_debug(" |- %s LSP %u/%u for %s/%u via %u",
inet_ntoa(nhlfe.prefv4.prefix),
nhlfe.prefv4.prefixlen, nhlfe.ifindex);
- return zclient_send_message(zclient);
+ zl.type = ZEBRA_LSP_SR;
+ zl.prefix.family = nhlfe.prefv4.family;
+ zl.prefix.prefixlen = nhlfe.prefv4.prefixlen;
+ zl.prefix.u.prefix4 = nhlfe.prefv4.prefix;
+ zl.nexthop.ipv4 = nhlfe.nexthop;
+ zl.ifindex = nhlfe.ifindex;
+ zl.distance = OSPF_SR_PRIORITY_DEFAULT;
+ zl.local_label = nhlfe.label_in;
+ zl.remote_label = nhlfe.label_out;
+
+ return zebra_send_mpls_labels(zclient, cmd, &zl);
}
/* Request zebra to install/remove FEC in FIB */
static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
{
struct stream *s;
- enum lsp_types_t type;
- struct prefix prefix;
+ struct zapi_labels zl;
enum nexthop_types_t gtype;
- union g_addr gate;
- ifindex_t ifindex;
- mpls_label_t in_label, out_label;
- uint8_t distance;
/* Get input stream. */
s = msg;
-
- /* Get data. */
- STREAM_GETC(s, type);
- STREAM_GETL(s, prefix.family);
- switch (prefix.family) {
- case AF_INET:
- STREAM_GET(&prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
- STREAM_GETC(s, prefix.prefixlen);
- if (prefix.prefixlen > IPV4_MAX_BITLEN) {
- zlog_debug(
- "%s: Specified prefix length %d is greater than a v4 address can support",
- __PRETTY_FUNCTION__, prefix.prefixlen);
- return;
- }
- STREAM_GET(&gate.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
- break;
- case AF_INET6:
- STREAM_GET(&prefix.u.prefix6, s, 16);
- STREAM_GETC(s, prefix.prefixlen);
- if (prefix.prefixlen > IPV6_MAX_BITLEN) {
- zlog_debug(
- "%s: Specified prefix length %d is greater than a v6 address can support",
- __PRETTY_FUNCTION__, prefix.prefixlen);
- return;
- }
- STREAM_GET(&gate.ipv6, s, 16);
- break;
- default:
- zlog_debug("%s: Specified AF %d is not supported for this call",
- __PRETTY_FUNCTION__, prefix.family);
+ if (zapi_labels_decode(s, &zl) < 0) {
+ if (IS_ZEBRA_DEBUG_RECV)
+ zlog_debug("%s: Unable to decode zapi_labels sent",
+ __PRETTY_FUNCTION__);
return;
}
- STREAM_GETL(s, ifindex);
- STREAM_GETC(s, distance);
- STREAM_GETL(s, in_label);
- STREAM_GETL(s, out_label);
- switch (prefix.family) {
+ switch (zl.prefix.family) {
case AF_INET:
- if (ifindex)
+ if (zl.ifindex)
gtype = NEXTHOP_TYPE_IPV4_IFINDEX;
else
gtype = NEXTHOP_TYPE_IPV4;
break;
case AF_INET6:
- if (ifindex)
+ if (zl.ifindex)
gtype = NEXTHOP_TYPE_IPV6_IFINDEX;
else
gtype = NEXTHOP_TYPE_IPV6;
return;
if (hdr->command == ZEBRA_MPLS_LABELS_ADD) {
- mpls_lsp_install(zvrf, type, in_label, out_label, gtype, &gate,
- ifindex);
- mpls_ftn_update(1, zvrf, type, &prefix, gtype, &gate, ifindex,
- distance, out_label);
+ mpls_lsp_install(zvrf, zl.type, zl.local_label, zl.remote_label,
+ gtype, &zl.nexthop, zl.ifindex);
+ mpls_ftn_update(1, zvrf, zl.type, &zl.prefix, gtype,
+ &zl.nexthop, zl.ifindex, zl.distance,
+ zl.remote_label);
} else if (hdr->command == ZEBRA_MPLS_LABELS_DELETE) {
- mpls_lsp_uninstall(zvrf, type, in_label, gtype, &gate, ifindex);
- mpls_ftn_update(0, zvrf, type, &prefix, gtype, &gate, ifindex,
- distance, out_label);
+ mpls_lsp_uninstall(zvrf, zl.type, zl.local_label, gtype,
+ &zl.nexthop, zl.ifindex);
+ mpls_ftn_update(0, zvrf, zl.type, &zl.prefix, gtype,
+ &zl.nexthop, zl.ifindex, zl.distance,
+ zl.remote_label);
}
-stream_failure:
- return;
}
/* Send response to a table manager connect request to client */