]>
git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_mlag_private.c
2 * Copyright (C) 2019 Cumulus Networks, Inc.
5 * This file is part of FRR.
7 * FRR is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * FRR is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
31 #include "lib/stream.h"
33 #include "zebra/debug.h"
34 #include "zebra/zebra_router.h"
35 #include "zebra/zebra_mlag.h"
36 #include "zebra/zebra_mlag_private.h"
42 * This file will have platform specific apis to communicate with MCLAG.
48 static struct thread_master
*zmlag_master
;
49 static int mlag_socket
;
51 static int zebra_mlag_connect(struct thread
*thread
);
52 static int zebra_mlag_read(struct thread
*thread
);
55 * Write teh data to MLAGD
57 int zebra_mlag_private_write_data(uint8_t *data
, uint32_t len
)
61 if (IS_ZEBRA_DEBUG_MLAG
) {
62 zlog_debug("%s: Writing %d length Data to clag", __func__
, len
);
63 zlog_hexdump(data
, len
);
65 rc
= write(mlag_socket
, data
, len
);
69 static void zebra_mlag_sched_read(void)
71 pthread_mutex_lock(&zrouter
.mlag_info
.mlag_th_mtx
);
72 thread_add_read(zmlag_master
, zebra_mlag_read
, NULL
, mlag_socket
,
73 &zrouter
.mlag_info
.t_read
);
74 pthread_mutex_unlock(&zrouter
.mlag_info
.mlag_th_mtx
);
77 static int zebra_mlag_read(struct thread
*thread
)
81 uint32_t tot_len
, curr_len
= mlag_rd_buf_offset
;
83 pthread_mutex_lock(&zrouter
.mlag_info
.mlag_th_mtx
);
84 zrouter
.mlag_info
.t_read
= NULL
;
85 pthread_mutex_unlock(&zrouter
.mlag_info
.mlag_th_mtx
);
88 * Received message in sock_stream looks like below
89 * | len-1 (4 Bytes) | payload-1 (len-1) |
90 * len-2 (4 Bytes) | payload-2 (len-2) | ..
92 * Idea is read one message completely, then process, until message is
93 * read completely, keep on reading from the socket
95 if (curr_len
< ZEBRA_MLAG_LEN_SIZE
) {
98 data_len
= read(mlag_socket
, mlag_rd_buffer
+ curr_len
,
99 ZEBRA_MLAG_LEN_SIZE
- curr_len
);
100 if (data_len
== 0 || data_len
== -1) {
101 if (IS_ZEBRA_DEBUG_MLAG
)
102 zlog_debug("MLAG connection closed socket : %d",
105 zebra_mlag_handle_process_state(MLAG_DOWN
);
108 if (data_len
!= (ssize_t
)ZEBRA_MLAG_LEN_SIZE
- curr_len
) {
109 /* Try again later */
110 zebra_mlag_sched_read();
113 curr_len
= ZEBRA_MLAG_LEN_SIZE
;
116 /* Get the actual packet length */
117 msglen
= (uint32_t *)mlag_rd_buffer
;
118 h_msglen
= ntohl(*msglen
);
120 /* This will be the actual length of the packet */
121 tot_len
= h_msglen
+ ZEBRA_MLAG_LEN_SIZE
;
123 if (curr_len
< tot_len
) {
126 data_len
= read(mlag_socket
, mlag_rd_buffer
+ curr_len
,
128 if (data_len
== 0 || data_len
== -1) {
129 if (IS_ZEBRA_DEBUG_MLAG
)
130 zlog_debug("MLAG connection closed socket : %d",
133 zebra_mlag_handle_process_state(MLAG_DOWN
);
136 if (data_len
!= (ssize_t
)tot_len
- curr_len
) {
137 /* Try again later */
138 zebra_mlag_sched_read();
143 if (IS_ZEBRA_DEBUG_MLAG
) {
144 zlog_debug("Received a MLAG Message from socket: %d, len:%u ",
145 mlag_socket
, tot_len
);
146 zlog_hexdump(mlag_rd_buffer
, tot_len
);
149 tot_len
-= ZEBRA_MLAG_LEN_SIZE
;
151 /* Process the packet */
152 zebra_mlag_process_mlag_data(mlag_rd_buffer
+ ZEBRA_MLAG_LEN_SIZE
,
155 /* Register read thread. */
156 zebra_mlag_reset_read_buffer();
157 zebra_mlag_sched_read();
161 static int zebra_mlag_connect(struct thread
*thread
)
163 struct sockaddr_un svr
;
167 /* Reset the Timer-running flag */
168 zrouter
.mlag_info
.timer_running
= false;
170 zrouter
.mlag_info
.t_read
= NULL
;
171 memset(&svr
, 0, sizeof(svr
));
172 svr
.sun_family
= AF_UNIX
;
173 #define MLAG_SOCK_NAME "/var/run/clag-zebra.socket"
174 strlcpy(svr
.sun_path
, MLAG_SOCK_NAME
, sizeof(MLAG_SOCK_NAME
) + 1);
176 mlag_socket
= socket(svr
.sun_family
, SOCK_STREAM
, 0);
180 if (connect(mlag_socket
, (struct sockaddr
*)&svr
, sizeof(svr
)) == -1) {
181 if (IS_ZEBRA_DEBUG_MLAG
)
183 "Unable to connect to %s try again in 10 secs",
186 zrouter
.mlag_info
.timer_running
= true;
187 thread_add_timer(zmlag_master
, zebra_mlag_connect
, NULL
, 10,
188 &zrouter
.mlag_info
.t_read
);
191 len
= sizeof(struct ucred
);
192 ucred
.pid
= getpid();
194 set_nonblocking(mlag_socket
);
195 setsockopt(mlag_socket
, SOL_SOCKET
, SO_PEERCRED
, &ucred
, len
);
197 if (IS_ZEBRA_DEBUG_MLAG
)
198 zlog_debug("%s: Connection with MLAG is established ",
201 thread_add_read(zmlag_master
, zebra_mlag_read
, NULL
, mlag_socket
,
202 &zrouter
.mlag_info
.t_read
);
204 * Connection is established with MLAGD, post to clients
206 zebra_mlag_handle_process_state(MLAG_UP
);
211 * Currently we are doing polling later we will look for better options
213 void zebra_mlag_private_monitor_state(void)
215 thread_add_event(zmlag_master
, zebra_mlag_connect
, NULL
, 0,
216 &zrouter
.mlag_info
.t_read
);
219 int zebra_mlag_private_open_channel(void)
221 zmlag_master
= zrouter
.mlag_info
.th_master
;
223 if (zrouter
.mlag_info
.connected
== true) {
224 if (IS_ZEBRA_DEBUG_MLAG
)
225 zlog_debug("%s: Zebra already connected to MLAGD",
230 if (zrouter
.mlag_info
.timer_running
== true) {
231 if (IS_ZEBRA_DEBUG_MLAG
)
233 "%s: Connection retry is in progress for MLAGD",
238 if (zrouter
.mlag_info
.clients_interested_cnt
) {
240 * Connect only if any clients are showing interest
242 thread_add_event(zmlag_master
, zebra_mlag_connect
, NULL
, 0,
243 &zrouter
.mlag_info
.t_read
);
248 int zebra_mlag_private_close_channel(void)
250 if (zmlag_master
== NULL
)
253 if (zrouter
.mlag_info
.clients_interested_cnt
) {
254 if (IS_ZEBRA_DEBUG_MLAG
)
255 zlog_debug("%s: still %d clients are connected, skip",
257 zrouter
.mlag_info
.clients_interested_cnt
);
262 * Post the De-register to MLAG, so that it can do necesasry cleanup
264 zebra_mlag_send_deregister();
269 void zebra_mlag_private_cleanup_data(void)
272 zrouter
.mlag_info
.connected
= false;
273 zrouter
.mlag_info
.timer_running
= false;
278 #else /*HAVE_CUMULUS */
280 int zebra_mlag_private_write_data(uint8_t *data
, uint32_t len
)
285 void zebra_mlag_private_monitor_state(void)
289 int zebra_mlag_private_open_channel(void)
294 int zebra_mlag_private_close_channel(void)
299 void zebra_mlag_private_cleanup_data(void)
302 #endif /*HAVE_CUMULUS*/