summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-05-30 10:58:03 -0400
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-05-30 10:58:03 -0400
commit293067f086565c294862b954bf58e1680d758280 (patch)
treecf5ebe06faba962952846ab2dc682cbdd62dadcd /lib/zclient.c
parent7217de2d8add45e71b49a15df965cc1d26389d5f (diff)
parente22ab7727d231ca477eb4f45ffb1950d5e4d12c4 (diff)
Merge remote-tracking branch 'origin/master' into babel
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c109
1 files changed, 65 insertions, 44 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index 1d3c93d85d..a53e8112c8 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -14,10 +14,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING. If not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
@@ -26,6 +25,8 @@
#include "stream.h"
#include "buffer.h"
#include "network.h"
+#include "vrf.h"
+#include "vrf_int.h"
#include "if.h"
#include "log.h"
#include "thread.h"
@@ -1511,6 +1512,47 @@ zebra_interface_vrf_update_read (struct stream *s, vrf_id_t vrf_id,
*new_vrf_id = new_id;
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
*
@@ -1526,11 +1568,6 @@ lm_label_manager_connect (struct zclient *zclient)
int ret;
struct stream *s;
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)
zlog_debug ("Connecting to Label Manager");
@@ -1570,20 +1607,15 @@ lm_label_manager_connect (struct zclient *zclient)
zlog_debug ("%s: Label manager connect request (%d bytes) sent", __func__, ret);
/* read response */
- s = zclient->ibuf;
- stream_reset (s);
+ if (zclient_read_sync_response (zclient, ZEBRA_LABEL_MANAGER_CONNECT) != 0)
+ return -1;
- 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;
- }
/* result */
+ s = zclient->ibuf;
result = stream_getc(s);
if (zclient_debug)
- zlog_debug ("%s: Label Manager connect response (%d bytes) received, result %u",
- __func__, size, result);
+ zlog_debug ("%s: Label Manager connect response received, result %u",
+ __func__, result);
return (int)result;
}
@@ -1607,11 +1639,6 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size,
{
int ret;
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;
if (zclient_debug)
@@ -1650,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);
/* read response */
- s = zclient->ibuf;
- 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;
- }
- if (zclient_debug)
- zlog_debug ("%s: Label chunk response (%d bytes) received", __func__, size);
+ if (zclient_read_sync_response (zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
+ return -1;
+ s = zclient->ibuf;
/* keep */
response_keep = stream_getc(s);
/* start and end labels */
@@ -1669,18 +1688,20 @@ lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size,
*end = stream_getl(s);
/* not owning this response */
- if (keep != response_keep) {
- zlog_err ("%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
- __func__, *start, *end, keep, response_keep);
- }
+ if (keep != response_keep)
+ {
+ zlog_err ("%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
+ __func__, *start, *end, keep, response_keep);
+ }
/* sanity */
if (*start > *end
|| *start < MPLS_MIN_UNRESERVED_LABEL
- || *end > MPLS_MAX_UNRESERVED_LABEL) {
- zlog_err ("%s: Invalid Label chunk: %u - %u", __func__,
- *start, *end);
- return -1;
- }
+ || *end > MPLS_MAX_UNRESERVED_LABEL)
+ {
+ zlog_err ("%s: Invalid Label chunk: %u - %u", __func__,
+ *start, *end);
+ return -1;
+ }
if (zclient_debug)
zlog_debug ("Label Chunk assign: %u - %u (%u) ",