mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 04:26:12 +00:00
zebra: fec register
Implement interface that allows a client to register a FEC for obtaining a label binding (in-label). Update client whenever the label binding is updated and cleanup when client goes away. Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
This commit is contained in:
parent
f31e084c7c
commit
5aba114af4
@ -1867,6 +1867,12 @@ zclient_read (struct thread *thread)
|
|||||||
if (zclient->interface_link_params)
|
if (zclient->interface_link_params)
|
||||||
(*zclient->interface_link_params) (command, zclient, length);
|
(*zclient->interface_link_params) (command, zclient, length);
|
||||||
break;
|
break;
|
||||||
|
case ZEBRA_FEC_UPDATE:
|
||||||
|
if (zclient_debug)
|
||||||
|
zlog_debug("zclient rcvd fec update\n");
|
||||||
|
if (zclient->fec_update)
|
||||||
|
(*zclient->fec_update) (command, zclient, length);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,9 @@ typedef enum {
|
|||||||
ZEBRA_LABEL_MANAGER_CONNECT,
|
ZEBRA_LABEL_MANAGER_CONNECT,
|
||||||
ZEBRA_GET_LABEL_CHUNK,
|
ZEBRA_GET_LABEL_CHUNK,
|
||||||
ZEBRA_RELEASE_LABEL_CHUNK,
|
ZEBRA_RELEASE_LABEL_CHUNK,
|
||||||
|
ZEBRA_FEC_REGISTER,
|
||||||
|
ZEBRA_FEC_UNREGISTER,
|
||||||
|
ZEBRA_FEC_UPDATE,
|
||||||
} zebra_message_types_t;
|
} zebra_message_types_t;
|
||||||
|
|
||||||
struct redist_proto
|
struct redist_proto
|
||||||
@ -164,6 +167,7 @@ struct zclient
|
|||||||
int (*redistribute_route_ipv4_del) (int, struct zclient *, uint16_t, vrf_id_t);
|
int (*redistribute_route_ipv4_del) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||||
int (*redistribute_route_ipv6_add) (int, struct zclient *, uint16_t, vrf_id_t);
|
int (*redistribute_route_ipv6_add) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||||
int (*redistribute_route_ipv6_del) (int, struct zclient *, uint16_t, vrf_id_t);
|
int (*redistribute_route_ipv6_del) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||||
|
int (*fec_update) (int, struct zclient *, uint16_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Zebra API message flag. */
|
/* Zebra API message flag. */
|
||||||
|
@ -40,7 +40,7 @@ testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
|
|||||||
zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c zebra_vrf.c \
|
zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c zebra_vrf.c \
|
||||||
kernel_null.c redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c \
|
kernel_null.c redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c \
|
||||||
zebra_ptm_null.c rtadv_null.c if_null.c zserv_null.c zebra_static.c \
|
zebra_ptm_null.c rtadv_null.c if_null.c zserv_null.c zebra_static.c \
|
||||||
zebra_memory.c zebra_mpls.c zebra_mpls_vty.c zebra_mpls_null.c
|
zebra_memory.c zebra_mpls_vty.c zebra_mpls_null.c
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
zebra_memory.h \
|
zebra_memory.h \
|
||||||
|
@ -60,6 +60,10 @@ extern struct zebra_t zebrad;
|
|||||||
|
|
||||||
/* static function declarations */
|
/* static function declarations */
|
||||||
|
|
||||||
|
static int
|
||||||
|
fec_send (zebra_fec_t *fec, struct zserv *client);
|
||||||
|
static void
|
||||||
|
fec_update_clients (zebra_fec_t *fec);
|
||||||
static void
|
static void
|
||||||
fec_print (zebra_fec_t *fec, struct vty *vty);
|
fec_print (zebra_fec_t *fec, struct vty *vty);
|
||||||
static zebra_fec_t *
|
static zebra_fec_t *
|
||||||
@ -148,6 +152,49 @@ mpls_processq_init (struct zebra_t *zebra);
|
|||||||
|
|
||||||
/* Static functions */
|
/* Static functions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inform about FEC to a registered client.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
fec_send (zebra_fec_t *fec, struct zserv *client)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
struct route_node *rn;
|
||||||
|
|
||||||
|
rn = fec->rn;
|
||||||
|
|
||||||
|
/* Get output stream. */
|
||||||
|
s = client->obuf;
|
||||||
|
stream_reset (s);
|
||||||
|
|
||||||
|
zserv_create_header (s, ZEBRA_FEC_UPDATE, VRF_DEFAULT);
|
||||||
|
|
||||||
|
stream_putw(s, rn->p.family);
|
||||||
|
stream_put_prefix (s, &rn->p);
|
||||||
|
stream_putl(s, fec->label);
|
||||||
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
|
return zebra_server_send_message(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update all registered clients about this FEC. Caller should've updated
|
||||||
|
* FEC and ensure no duplicate updates.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
fec_update_clients (zebra_fec_t *fec)
|
||||||
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
struct zserv *client;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, client))
|
||||||
|
{
|
||||||
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
|
zlog_debug ("Update client %s", zebra_route_string(client->proto));
|
||||||
|
fec_send(fec, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print a FEC-label binding entry.
|
* Print a FEC-label binding entry.
|
||||||
*/
|
*/
|
||||||
@ -155,6 +202,8 @@ static void
|
|||||||
fec_print (zebra_fec_t *fec, struct vty *vty)
|
fec_print (zebra_fec_t *fec, struct vty *vty)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
|
struct listnode *node;
|
||||||
|
struct zserv *client;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
rn = fec->rn;
|
rn = fec->rn;
|
||||||
@ -162,6 +211,14 @@ fec_print (zebra_fec_t *fec, struct vty *vty)
|
|||||||
vty_out(vty, "%s%s", buf, VTY_NEWLINE);
|
vty_out(vty, "%s%s", buf, VTY_NEWLINE);
|
||||||
vty_out(vty, " Label: %s", label2str(fec->label, buf, BUFSIZ));
|
vty_out(vty, " Label: %s", label2str(fec->label, buf, BUFSIZ));
|
||||||
vty_out(vty, "%s", VTY_NEWLINE);
|
vty_out(vty, "%s", VTY_NEWLINE);
|
||||||
|
if (!list_isempty(fec->client_list))
|
||||||
|
{
|
||||||
|
vty_out(vty, " Client list:");
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, client))
|
||||||
|
vty_out(vty, " %s(fd %d)",
|
||||||
|
zebra_route_string(client->proto), client->sock);
|
||||||
|
vty_out(vty, "%s", VTY_NEWLINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -182,7 +239,8 @@ fec_find (struct route_table *table, struct prefix *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a FEC.
|
* Add a FEC. This may be upon a client registering for a binding
|
||||||
|
* or when a binding is configured.
|
||||||
*/
|
*/
|
||||||
static zebra_fec_t *
|
static zebra_fec_t *
|
||||||
fec_add (struct route_table *table, struct prefix *p,
|
fec_add (struct route_table *table, struct prefix *p,
|
||||||
@ -209,6 +267,7 @@ fec_add (struct route_table *table, struct prefix *p,
|
|||||||
rn->info = fec;
|
rn->info = fec;
|
||||||
fec->rn = rn;
|
fec->rn = rn;
|
||||||
fec->label = label;
|
fec->label = label;
|
||||||
|
fec->client_list = list_new();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
route_unlock_node (rn); /* for the route_node_get */
|
route_unlock_node (rn); /* for the route_node_get */
|
||||||
@ -219,11 +278,14 @@ fec_add (struct route_table *table, struct prefix *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete a FEC.
|
* Delete a FEC. This may be upon the last client deregistering for
|
||||||
|
* a FEC and no binding exists or when the binding is deleted and there
|
||||||
|
* are no registered clients.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
fec_del (zebra_fec_t *fec)
|
fec_del (zebra_fec_t *fec)
|
||||||
{
|
{
|
||||||
|
list_free (fec->client_list);
|
||||||
fec->rn->info = NULL;
|
fec->rn->info = NULL;
|
||||||
route_unlock_node (fec->rn);
|
route_unlock_node (fec->rn);
|
||||||
XFREE (MTYPE_FEC, fec);
|
XFREE (MTYPE_FEC, fec);
|
||||||
@ -1370,6 +1432,142 @@ mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Registration from a client for the label binding for a FEC. If a binding
|
||||||
|
* already exists, it is informed to the client.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zebra_mpls_fec_register (struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
|
struct zserv *client)
|
||||||
|
{
|
||||||
|
struct route_table *table;
|
||||||
|
zebra_fec_t *fec;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
|
table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
|
||||||
|
if (!table)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
|
prefix2str(p, buf, BUFSIZ);
|
||||||
|
|
||||||
|
/* Locate FEC */
|
||||||
|
fec = fec_find (table, p);
|
||||||
|
if (!fec)
|
||||||
|
{
|
||||||
|
fec = fec_add (table, p, MPLS_INVALID_LABEL, 0);
|
||||||
|
if (!fec)
|
||||||
|
{
|
||||||
|
prefix2str(p, buf, BUFSIZ);
|
||||||
|
zlog_err("Failed to add FEC %s upon register, client %s",
|
||||||
|
buf, zebra_route_string(client->proto));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (listnode_lookup(fec->client_list, client))
|
||||||
|
/* Duplicate register */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
listnode_add (fec->client_list, client);
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
|
zlog_debug("FEC %s registered by client %s",
|
||||||
|
buf, zebra_route_string(client->proto));
|
||||||
|
|
||||||
|
if (fec->label != MPLS_INVALID_LABEL)
|
||||||
|
{
|
||||||
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
|
zlog_debug ("Update client label %u", fec->label);
|
||||||
|
fec_send (fec, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deregistration from a client for the label binding for a FEC. The FEC
|
||||||
|
* itself is deleted if no other registered clients exist and there is no
|
||||||
|
* label bound to the FEC.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zebra_mpls_fec_unregister (struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
|
struct zserv *client)
|
||||||
|
{
|
||||||
|
struct route_table *table;
|
||||||
|
zebra_fec_t *fec;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
|
table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
|
||||||
|
if (!table)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
|
prefix2str(p, buf, BUFSIZ);
|
||||||
|
|
||||||
|
fec = fec_find (table, p);
|
||||||
|
if (!fec)
|
||||||
|
{
|
||||||
|
prefix2str(p, buf, BUFSIZ);
|
||||||
|
zlog_err("Failed to find FEC %s upon unregister, client %s",
|
||||||
|
buf, zebra_route_string(client->proto));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
listnode_delete(fec->client_list, client);
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
|
zlog_debug("FEC %s unregistered by client %s",
|
||||||
|
buf, zebra_route_string(client->proto));
|
||||||
|
|
||||||
|
if (list_isempty(fec->client_list) && (fec->label == MPLS_INVALID_LABEL))
|
||||||
|
fec_del (fec);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup any FECs registered by this client.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zebra_mpls_cleanup_fecs_for_client (struct zebra_vrf *zvrf, struct zserv *client)
|
||||||
|
{
|
||||||
|
struct route_node *rn;
|
||||||
|
zebra_fec_t *fec;
|
||||||
|
struct listnode *node;
|
||||||
|
struct zserv *fec_client;
|
||||||
|
int af;
|
||||||
|
|
||||||
|
for (af = AFI_IP; af < AFI_MAX; af++)
|
||||||
|
{
|
||||||
|
if (zvrf->fec_table[af] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
|
||||||
|
{
|
||||||
|
fec = rn->info;
|
||||||
|
if (!fec || list_isempty(fec->client_list))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, fec_client))
|
||||||
|
{
|
||||||
|
if (fec_client == client)
|
||||||
|
{
|
||||||
|
listnode_delete(fec->client_list, fec_client);
|
||||||
|
if (!(fec->flags & FEC_FLAG_CONFIGURED) &&
|
||||||
|
list_isempty(fec->client_list))
|
||||||
|
fec_del (fec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return FEC (if any) to which this label is bound.
|
* Return FEC (if any) to which this label is bound.
|
||||||
* Note: Only works for per-prefix binding and when the label is not
|
* Note: Only works for per-prefix binding and when the label is not
|
||||||
@ -1412,8 +1610,9 @@ zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add static FEC to label binding.
|
* Add static FEC to label binding. If there are clients registered for this
|
||||||
*/
|
* FEC, notify them.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
|
zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
mpls_label_t in_label)
|
mpls_label_t in_label)
|
||||||
@ -1452,17 +1651,20 @@ zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
|
|||||||
/* Duplicate config */
|
/* Duplicate config */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* Label change, update clients. */
|
||||||
if (IS_ZEBRA_DEBUG_MPLS)
|
if (IS_ZEBRA_DEBUG_MPLS)
|
||||||
zlog_debug ("Update fec %s new label %u", buf, in_label);
|
zlog_debug ("Update fec %s new label %u", buf, in_label);
|
||||||
|
|
||||||
fec->label = in_label;
|
fec->label = in_label;
|
||||||
|
fec_update_clients (fec);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove static FEC to label binding.
|
* Remove static FEC to label binding. If there are no clients registered
|
||||||
|
* for this FEC, delete the FEC; else notify clients
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p)
|
zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p)
|
||||||
@ -1489,7 +1691,18 @@ zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p)
|
|||||||
zlog_debug ("Delete fec %s", buf);
|
zlog_debug ("Delete fec %s", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fec_del (fec);
|
fec->flags &= ~FEC_FLAG_CONFIGURED;
|
||||||
|
fec->label = MPLS_INVALID_LABEL;
|
||||||
|
|
||||||
|
/* If no client exists, just delete the FEC. */
|
||||||
|
if (list_isempty(fec->client_list))
|
||||||
|
{
|
||||||
|
fec_del (fec);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fec_update_clients (fec);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,6 +162,9 @@ struct zebra_fec_t_
|
|||||||
/* Flags. */
|
/* Flags. */
|
||||||
u_int32_t flags;
|
u_int32_t flags;
|
||||||
#define FEC_FLAG_CONFIGURED (1 << 0)
|
#define FEC_FLAG_CONFIGURED (1 << 0)
|
||||||
|
|
||||||
|
/* Clients interested in this FEC. */
|
||||||
|
struct list *client_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function declarations. */
|
/* Function declarations. */
|
||||||
@ -180,6 +183,29 @@ char *
|
|||||||
mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
|
mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
|
||||||
char *buf, int len);
|
char *buf, int len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Registration from a client for the label binding for a FEC. If a binding
|
||||||
|
* already exists, it is informed to the client.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zebra_mpls_fec_register (struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
|
struct zserv *client);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deregistration from a client for the label binding for a FEC. The FEC
|
||||||
|
* itself is deleted if no other registered clients exist and there is no
|
||||||
|
* label bound to the FEC.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zebra_mpls_fec_unregister (struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
|
struct zserv *client);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup any FECs registered by this client.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zebra_mpls_cleanup_fecs_for_client (struct zebra_vrf *zvrf, struct zserv *client);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return FEC (if any) to which this label is bound.
|
* Return FEC (if any) to which this label is bound.
|
||||||
* Note: Only works for per-prefix binding and when the label is not
|
* Note: Only works for per-prefix binding and when the label is not
|
||||||
@ -197,14 +223,16 @@ int
|
|||||||
zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label);
|
zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add static FEC to label binding.
|
* Add static FEC to label binding. If there are clients registered for this
|
||||||
|
* FEC, notify them.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
|
zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
mpls_label_t in_label);
|
mpls_label_t in_label);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove static FEC to label binding.
|
* Remove static FEC to label binding. If there are no clients registered
|
||||||
|
* for this FEC, delete the FEC; else notify clients.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p);
|
zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p);
|
||||||
|
@ -27,3 +27,138 @@ int kernel_add_lsp (zebra_lsp_t *lsp) { return 0; }
|
|||||||
int kernel_upd_lsp (zebra_lsp_t *lsp) { return 0; }
|
int kernel_upd_lsp (zebra_lsp_t *lsp) { return 0; }
|
||||||
int kernel_del_lsp (zebra_lsp_t *lsp) { return 0; }
|
int kernel_del_lsp (zebra_lsp_t *lsp) { return 0; }
|
||||||
int mpls_kernel_init (void) { return -1; };
|
int mpls_kernel_init (void) { return -1; };
|
||||||
|
|
||||||
|
int mpls_enabled;
|
||||||
|
|
||||||
|
char *
|
||||||
|
mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
|
||||||
|
char *buf, int len)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mpls_str2label (const char *label_str, u_int8_t *num_labels,
|
||||||
|
mpls_label_t *labels)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zebra_mpls_init_tables (struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zebra_mpls_print_lsp (struct vty *vty, struct zebra_vrf *zvrf, mpls_label_t label,
|
||||||
|
u_char use_json)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf,
|
||||||
|
u_char use_json)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
|
||||||
|
mpls_label_t out_label, enum nexthop_types_t gtype,
|
||||||
|
union g_addr *gate, char *ifname, ifindex_t ifindex)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
|
||||||
|
mpls_label_t out_label, enum nexthop_types_t gtype,
|
||||||
|
union g_addr *gate, char *ifname, ifindex_t ifindex)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,
|
||||||
|
enum nexthop_types_t gtype, union g_addr *gate,
|
||||||
|
char *ifname, ifindex_t ifindex)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zebra_mpls_lsp_schedule (struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zebra_mpls_close_tables (struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
zebra_fec_t *
|
||||||
|
zebra_mpls_fec_for_label (struct zebra_vrf *zvrf, mpls_label_t label)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
|
mpls_label_t in_label)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_write_fec_config (struct vty *vty, struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zebra_mpls_print_fec_table (struct vty *vty, struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zebra_mpls_print_fec (struct vty *vty, struct zebra_vrf *zvrf, struct prefix *p)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_fec_register (struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
|
struct zserv *client)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_fec_unregister (struct zebra_vrf *zvrf, struct prefix *p,
|
||||||
|
struct zserv *client)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zebra_mpls_cleanup_fecs_for_client (struct zebra_vrf *zvrf, struct zserv *client)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -934,6 +934,60 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FEC register */
|
||||||
|
static int
|
||||||
|
zserv_fec_register (struct zserv *client, int sock, u_short length)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
u_short l = 0;
|
||||||
|
struct prefix p;
|
||||||
|
|
||||||
|
s = client->ibuf;
|
||||||
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||||
|
if (!zvrf)
|
||||||
|
return 0; // unexpected
|
||||||
|
|
||||||
|
while (l < length)
|
||||||
|
{
|
||||||
|
p.family = stream_getw(s);
|
||||||
|
p.prefixlen = stream_getc(s);
|
||||||
|
l += 5;
|
||||||
|
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
|
||||||
|
l += PSIZE(p.prefixlen);
|
||||||
|
zebra_mpls_fec_register (zvrf, &p, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FEC unregister */
|
||||||
|
static int
|
||||||
|
zserv_fec_unregister (struct zserv *client, int sock, u_short length)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
u_short l = 0;
|
||||||
|
struct prefix p;
|
||||||
|
|
||||||
|
s = client->ibuf;
|
||||||
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
||||||
|
if (!zvrf)
|
||||||
|
return 0; // unexpected
|
||||||
|
|
||||||
|
while (l < length)
|
||||||
|
{
|
||||||
|
p.family = stream_getw(s);
|
||||||
|
p.prefixlen = stream_getc(s);
|
||||||
|
l += 5;
|
||||||
|
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
|
||||||
|
l += PSIZE(p.prefixlen);
|
||||||
|
zebra_mpls_fec_unregister (zvrf, &p, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Modified version of zsend_ipv4_nexthop_lookup():
|
Modified version of zsend_ipv4_nexthop_lookup():
|
||||||
Query unicast rib if nexthop is not found on mrib.
|
Query unicast rib if nexthop is not found on mrib.
|
||||||
@ -1975,6 +2029,9 @@ zebra_client_close (struct zserv *client)
|
|||||||
/* Release Label Manager chunks */
|
/* Release Label Manager chunks */
|
||||||
release_daemon_chunks (client->proto, client->instance);
|
release_daemon_chunks (client->proto, client->instance);
|
||||||
|
|
||||||
|
/* Cleanup any FECs registered by this client. */
|
||||||
|
zebra_mpls_cleanup_fecs_for_client (vrf_info_lookup(VRF_DEFAULT), client);
|
||||||
|
|
||||||
/* Close file descriptor. */
|
/* Close file descriptor. */
|
||||||
if (client->sock)
|
if (client->sock)
|
||||||
{
|
{
|
||||||
@ -2263,6 +2320,12 @@ zebra_client_read (struct thread *thread)
|
|||||||
case ZEBRA_RELEASE_LABEL_CHUNK:
|
case ZEBRA_RELEASE_LABEL_CHUNK:
|
||||||
zread_label_manager_request (command, client, vrf_id);
|
zread_label_manager_request (command, client, vrf_id);
|
||||||
break;
|
break;
|
||||||
|
case ZEBRA_FEC_REGISTER:
|
||||||
|
zserv_fec_register (client, sock, length);
|
||||||
|
break;
|
||||||
|
case ZEBRA_FEC_UNREGISTER:
|
||||||
|
zserv_fec_unregister (client, sock, length);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
zlog_info ("Zebra received unknown command %d", command);
|
zlog_info ("Zebra received unknown command %d", command);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user