mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 11:25:41 +00:00
Merge branch 'stable/3.0'
Conflicts: ldpd/lde.c zebra/label_manager.c Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
commit
fa84d1932b
@ -1550,8 +1550,7 @@ bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info
|
|||||||
if (!ifindex)
|
if (!ifindex)
|
||||||
{
|
{
|
||||||
if (info->peer->conf_if || info->peer->ifname)
|
if (info->peer->conf_if || info->peer->ifname)
|
||||||
ifindex = ifname2ifindex_vrf (info->peer->conf_if ? info->peer->conf_if :
|
ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname);
|
||||||
info->peer->ifname, bgp->vrf_id);
|
|
||||||
else if (info->peer->nexthop.ifp)
|
else if (info->peer->nexthop.ifp)
|
||||||
ifindex = info->peer->nexthop.ifp->ifindex;
|
ifindex = info->peer->nexthop.ifp->ifindex;
|
||||||
}
|
}
|
||||||
|
@ -1623,6 +1623,8 @@ zclient_sync_init(u_short instance)
|
|||||||
log_warnx("Error connecting synchronous zclient!");
|
log_warnx("Error connecting synchronous zclient!");
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
/* make socket non-blocking */
|
||||||
|
sock_set_nonblock(zclient_sync->sock);
|
||||||
|
|
||||||
/* Connect to label manager */
|
/* Connect to label manager */
|
||||||
while (lm_label_manager_connect(zclient_sync) != 0) {
|
while (lm_label_manager_connect(zclient_sync) != 0) {
|
||||||
@ -1647,8 +1649,6 @@ lde_get_label_chunk(void)
|
|||||||
ret = lm_get_label_chunk(zclient_sync, 0, CHUNK_SIZE, &start, &end);
|
ret = lm_get_label_chunk(zclient_sync, 0, CHUNK_SIZE, &start, &end);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
log_warnx("Error getting label chunk!");
|
log_warnx("Error getting label chunk!");
|
||||||
close(zclient_sync->sock);
|
|
||||||
zclient_sync->sock = -1;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1512,6 +1512,47 @@ zebra_interface_vrf_update_read (struct stream *s, vrf_id_t vrf_id,
|
|||||||
*new_vrf_id = new_id;
|
*new_vrf_id = new_id;
|
||||||
return ifp;
|
return ifp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* filter unwanted messages until the expected one arrives */
|
||||||
|
static int
|
||||||
|
zclient_read_sync_response (struct zclient *zclient, u_int16_t expected_cmd)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
u_int16_t size;
|
||||||
|
u_char marker;
|
||||||
|
u_char version;
|
||||||
|
vrf_id_t vrf_id;
|
||||||
|
u_int16_t cmd;
|
||||||
|
fd_set readfds;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cmd = expected_cmd + 1;
|
||||||
|
while (ret == 0 && cmd != expected_cmd)
|
||||||
|
{
|
||||||
|
s = zclient->ibuf;
|
||||||
|
stream_reset (s);
|
||||||
|
|
||||||
|
/* wait until response arrives */
|
||||||
|
FD_ZERO (&readfds);
|
||||||
|
FD_SET (zclient->sock, &readfds);
|
||||||
|
select (zclient->sock+1, &readfds, NULL, NULL, NULL);
|
||||||
|
if (!FD_ISSET(zclient->sock, &readfds))
|
||||||
|
continue;
|
||||||
|
/* read response */
|
||||||
|
ret = zclient_read_header (s, zclient->sock, &size, &marker, &version,
|
||||||
|
&vrf_id, &cmd);
|
||||||
|
if (zclient_debug)
|
||||||
|
zlog_debug ("%s: Response (%d bytes) received", __func__, size);
|
||||||
|
}
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
zlog_err ("%s: Invalid Sync Message Reply", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Connect to label manager in a syncronous way
|
* Connect to label manager in a syncronous way
|
||||||
*
|
*
|
||||||
@ -1527,11 +1568,6 @@ lm_label_manager_connect (struct zclient *zclient)
|
|||||||
int ret;
|
int ret;
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
u_char result;
|
u_char result;
|
||||||
u_int16_t size;
|
|
||||||
u_char marker;
|
|
||||||
u_char version;
|
|
||||||
vrf_id_t vrf_id;
|
|
||||||
u_int16_t cmd;
|
|
||||||
|
|
||||||
if (zclient_debug)
|
if (zclient_debug)
|
||||||
zlog_debug ("Connecting to Label Manager");
|
zlog_debug ("Connecting to Label Manager");
|
||||||
@ -1571,20 +1607,15 @@ lm_label_manager_connect (struct zclient *zclient)
|
|||||||
zlog_debug ("%s: Label manager connect request (%d bytes) sent", __func__, ret);
|
zlog_debug ("%s: Label manager connect request (%d bytes) sent", __func__, ret);
|
||||||
|
|
||||||
/* read response */
|
/* read response */
|
||||||
s = zclient->ibuf;
|
if (zclient_read_sync_response (zclient, ZEBRA_LABEL_MANAGER_CONNECT) != 0)
|
||||||
stream_reset (s);
|
|
||||||
|
|
||||||
ret = zclient_read_header (s, zclient->sock, &size, &marker, &version,
|
|
||||||
&vrf_id, &cmd);
|
|
||||||
if (ret != 0 || cmd != ZEBRA_LABEL_MANAGER_CONNECT) {
|
|
||||||
zlog_err ("%s: Invalid Label Manager Connect Message Reply Header", __func__);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
/* result */
|
/* result */
|
||||||
|
s = zclient->ibuf;
|
||||||
result = stream_getc(s);
|
result = stream_getc(s);
|
||||||
if (zclient_debug)
|
if (zclient_debug)
|
||||||
zlog_debug ("%s: Label Manager connect response (%d bytes) received, result %u",
|
zlog_debug ("%s: Label Manager connect response received, result %u",
|
||||||
__func__, size, result);
|
__func__, result);
|
||||||
|
|
||||||
return (int)result;
|
return (int)result;
|
||||||
}
|
}
|
||||||
@ -1608,11 +1639,6 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
u_int16_t size;
|
|
||||||
u_char marker;
|
|
||||||
u_char version;
|
|
||||||
vrf_id_t vrf_id;
|
|
||||||
u_int16_t cmd;
|
|
||||||
u_char response_keep;
|
u_char response_keep;
|
||||||
|
|
||||||
if (zclient_debug)
|
if (zclient_debug)
|
||||||
@ -1651,18 +1677,10 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size,
|
|||||||
zlog_debug ("%s: Label chunk request (%d bytes) sent", __func__, ret);
|
zlog_debug ("%s: Label chunk request (%d bytes) sent", __func__, ret);
|
||||||
|
|
||||||
/* read response */
|
/* read response */
|
||||||
s = zclient->ibuf;
|
if (zclient_read_sync_response (zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
|
||||||
stream_reset (s);
|
|
||||||
|
|
||||||
ret = zclient_read_header (s, zclient->sock, &size, &marker, &version,
|
|
||||||
&vrf_id, &cmd);
|
|
||||||
if (ret != 0 || cmd != ZEBRA_GET_LABEL_CHUNK) {
|
|
||||||
zlog_err ("%s: Invalid Get Label Chunk Message Reply Header", __func__);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
if (zclient_debug)
|
|
||||||
zlog_debug ("%s: Label chunk response (%d bytes) received", __func__, size);
|
|
||||||
|
|
||||||
|
s = zclient->ibuf;
|
||||||
/* keep */
|
/* keep */
|
||||||
response_keep = stream_getc(s);
|
response_keep = stream_getc(s);
|
||||||
/* start and end labels */
|
/* start and end labels */
|
||||||
@ -1670,14 +1688,16 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size,
|
|||||||
*end = stream_getl(s);
|
*end = stream_getl(s);
|
||||||
|
|
||||||
/* not owning this response */
|
/* not owning this response */
|
||||||
if (keep != response_keep) {
|
if (keep != response_keep)
|
||||||
|
{
|
||||||
zlog_err ("%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
|
zlog_err ("%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
|
||||||
__func__, *start, *end, keep, response_keep);
|
__func__, *start, *end, keep, response_keep);
|
||||||
}
|
}
|
||||||
/* sanity */
|
/* sanity */
|
||||||
if (*start > *end
|
if (*start > *end
|
||||||
|| *start < MPLS_MIN_UNRESERVED_LABEL
|
|| *start < MPLS_MIN_UNRESERVED_LABEL
|
||||||
|| *end > MPLS_MAX_UNRESERVED_LABEL) {
|
|| *end > MPLS_MAX_UNRESERVED_LABEL)
|
||||||
|
{
|
||||||
zlog_err ("%s: Invalid Label chunk: %u - %u", __func__,
|
zlog_err ("%s: Invalid Label chunk: %u - %u", __func__,
|
||||||
*start, *end);
|
*start, *end);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -55,6 +55,80 @@ static void delete_label_chunk(void *val)
|
|||||||
XFREE(MTYPE_LM_CHUNK, val);
|
XFREE(MTYPE_LM_CHUNK, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int relay_response_back(struct zserv *zserv)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
struct stream *src, *dst;
|
||||||
|
u_int16_t size = 0;
|
||||||
|
u_char marker;
|
||||||
|
u_char version;
|
||||||
|
vrf_id_t vrf_id;
|
||||||
|
u_int16_t resp_cmd;
|
||||||
|
|
||||||
|
src = zclient->ibuf;
|
||||||
|
dst = zserv->obuf;
|
||||||
|
|
||||||
|
stream_reset(src);
|
||||||
|
|
||||||
|
ret = zclient_read_header(src, zclient->sock, &size, &marker, &version,
|
||||||
|
&vrf_id, &resp_cmd);
|
||||||
|
if (ret < 0 && errno != EAGAIN) {
|
||||||
|
zlog_err("%s: Error reading Label Manager response: %s", __func__,
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
zlog_debug("%s: Label Manager response received, %d bytes", __func__,
|
||||||
|
size);
|
||||||
|
if (size == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* send response back */
|
||||||
|
stream_copy(dst, src);
|
||||||
|
ret = writen(zserv->sock, dst->data, stream_get_endp(dst));
|
||||||
|
if (ret <= 0) {
|
||||||
|
zlog_err("%s: Error sending Label Manager response back: %s",
|
||||||
|
__func__, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
zlog_debug("%s: Label Manager response (%d bytes) sent back", __func__,
|
||||||
|
ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lm_zclient_read(struct thread *t)
|
||||||
|
{
|
||||||
|
struct zserv *zserv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Get socket to zebra. */
|
||||||
|
zserv = THREAD_ARG(t);
|
||||||
|
zclient->t_read = NULL;
|
||||||
|
|
||||||
|
/* read response and send it back */
|
||||||
|
ret = relay_response_back(zserv);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int reply_error (int cmd, struct zserv *zserv, vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
|
||||||
|
s = zserv->obuf;
|
||||||
|
stream_reset (s);
|
||||||
|
|
||||||
|
zserv_create_header (s, cmd, vrf_id);
|
||||||
|
|
||||||
|
/* result */
|
||||||
|
stream_putc (s, 1);
|
||||||
|
|
||||||
|
/* Write packet size. */
|
||||||
|
stream_putw_at (s, 0, stream_get_endp (s));
|
||||||
|
|
||||||
|
return writen (zserv->sock, s->data, stream_get_endp (s));
|
||||||
|
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Receive a request to get or release a label chunk and forward it to external
|
* Receive a request to get or release a label chunk and forward it to external
|
||||||
* label manager.
|
* label manager.
|
||||||
@ -63,19 +137,25 @@ static void delete_label_chunk(void *val)
|
|||||||
* proxy.
|
* proxy.
|
||||||
*
|
*
|
||||||
* @param cmd Type of request (connect, get or release)
|
* @param cmd Type of request (connect, get or release)
|
||||||
* @param src Input buffer from zserv
|
* @param zserv
|
||||||
* @return 0 on success, -1 otherwise
|
* @return 0 on success, -1 otherwise
|
||||||
*/
|
*/
|
||||||
int zread_relay_label_manager_request(int cmd, struct zserv *zserv)
|
int zread_relay_label_manager_request(int cmd, struct zserv *zserv, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct stream *src, *dst;
|
struct stream *src, *dst;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
if (zclient->sock < 0) {
|
if (zclient->sock < 0) {
|
||||||
zlog_err("%s: Error relaying label chunk request: no zclient socket",
|
zlog_err("%s: Error relaying label chunk request: no zclient socket",
|
||||||
__func__);
|
__func__);
|
||||||
|
reply_error (cmd, zserv, vrf_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* in case there's any incoming message enqueued, read and forward it */
|
||||||
|
while (ret == 0)
|
||||||
|
ret = relay_response_back(zserv);
|
||||||
|
|
||||||
/* Send request to external label manager */
|
/* Send request to external label manager */
|
||||||
src = zserv->ibuf;
|
src = zserv->ibuf;
|
||||||
dst = zclient->obuf;
|
dst = zclient->obuf;
|
||||||
@ -86,6 +166,7 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv)
|
|||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
zlog_err("%s: Error relaying label chunk request: %s", __func__,
|
zlog_err("%s: Error relaying label chunk request: %s", __func__,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
reply_error (cmd, zserv, vrf_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
zlog_debug("%s: Label chunk request relayed. %d bytes sent", __func__,
|
zlog_debug("%s: Label chunk request relayed. %d bytes sent", __func__,
|
||||||
@ -95,43 +176,15 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv)
|
|||||||
if (cmd == ZEBRA_RELEASE_LABEL_CHUNK)
|
if (cmd == ZEBRA_RELEASE_LABEL_CHUNK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* read response */
|
/* make sure we listen to the response */
|
||||||
src = zclient->ibuf;
|
if (!zclient->t_read)
|
||||||
dst = zserv->obuf;
|
zclient->t_read =
|
||||||
|
thread_add_read(zclient->master, lm_zclient_read, zserv, zclient->sock);
|
||||||
stream_reset(src);
|
|
||||||
|
|
||||||
u_int16_t size;
|
|
||||||
u_char marker;
|
|
||||||
u_char version;
|
|
||||||
vrf_id_t vrf_id;
|
|
||||||
u_int16_t resp_cmd;
|
|
||||||
ret = zclient_read_header(src, zclient->sock, &size, &marker, &version,
|
|
||||||
&vrf_id, &resp_cmd);
|
|
||||||
if (ret < 0) {
|
|
||||||
zlog_err("%s: Error reading label chunk response: %s", __func__,
|
|
||||||
strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
zlog_debug("%s: Label chunk response received, %d bytes", __func__,
|
|
||||||
size);
|
|
||||||
|
|
||||||
/* send response back */
|
|
||||||
stream_copy(dst, src);
|
|
||||||
stream_copy(zserv->obuf, zclient->ibuf);
|
|
||||||
ret = writen(zserv->sock, dst->data, stream_get_endp(dst));
|
|
||||||
if (ret <= 0) {
|
|
||||||
zlog_err("%s: Error sending label chunk response back: %s",
|
|
||||||
__func__, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
zlog_debug("%s: Label chunk response (%d bytes) sent back", __func__,
|
|
||||||
ret);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zclient_connect(struct thread *t)
|
static int lm_zclient_connect(struct thread *t)
|
||||||
{
|
{
|
||||||
zclient->t_connect = NULL;
|
zclient->t_connect = NULL;
|
||||||
|
|
||||||
@ -140,11 +193,15 @@ static int zclient_connect(struct thread *t)
|
|||||||
|
|
||||||
if (zclient_socket_connect(zclient) < 0) {
|
if (zclient_socket_connect(zclient) < 0) {
|
||||||
zlog_err("Error connecting synchronous zclient!");
|
zlog_err("Error connecting synchronous zclient!");
|
||||||
thread_add_timer(zebrad.master, zclient_connect, zclient,
|
thread_add_timer(zebrad.master, lm_zclient_connect, zclient,
|
||||||
CONNECTION_DELAY, &zclient->t_connect);
|
CONNECTION_DELAY, &zclient->t_connect);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make socket non-blocking */
|
||||||
|
if (set_nonblocking(zclient->sock) < 0)
|
||||||
|
zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +220,7 @@ static void lm_zclient_init(char *lm_zserv_path)
|
|||||||
zclient = zclient_new(zebrad.master);
|
zclient = zclient_new(zebrad.master);
|
||||||
zclient->sock = -1;
|
zclient->sock = -1;
|
||||||
zclient->t_connect = NULL;
|
zclient->t_connect = NULL;
|
||||||
zclient_connect (NULL);
|
lm_zclient_connect(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +61,7 @@ struct label_manager {
|
|||||||
|
|
||||||
bool lm_is_external;
|
bool lm_is_external;
|
||||||
|
|
||||||
int zread_relay_label_manager_request(int cmd, struct zserv *zserv);
|
int zread_relay_label_manager_request(int cmd, struct zserv *zserv, vrf_id_t vrf_id);
|
||||||
void label_manager_init(char *lm_zserv_path);
|
void label_manager_init(char *lm_zserv_path);
|
||||||
struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance,
|
struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance,
|
||||||
u_char keep, uint32_t size);
|
u_char keep, uint32_t size);
|
||||||
|
@ -2045,10 +2045,7 @@ zread_label_manager_request (int cmd, struct zserv *client, vrf_id_t vrf_id)
|
|||||||
|
|
||||||
/* external label manager */
|
/* external label manager */
|
||||||
if (lm_is_external)
|
if (lm_is_external)
|
||||||
{
|
zread_relay_label_manager_request (cmd, client, vrf_id);
|
||||||
if (zread_relay_label_manager_request (cmd, client) != 0)
|
|
||||||
zsend_label_manager_connect_response (client, vrf_id, 1);
|
|
||||||
}
|
|
||||||
/* this is a label manager */
|
/* this is a label manager */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user