2 * Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
4 * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
5 * Federico Simoncelli <fsimon@kronosnet.org>
7 * This software licensed under GPL-2.0+, LGPL-2.0+
17 #include "internals.h"
20 #include "transports.h"
22 #include "threads_common.h"
23 #include "links_acl.h"
25 int _link_updown(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
26 unsigned int enabled
, unsigned int connected
)
28 struct knet_link
*link
= &knet_h
->host_index
[host_id
]->link
[link_id
];
30 if ((link
->status
.enabled
== enabled
) &&
31 (link
->status
.connected
== connected
))
34 link
->status
.enabled
= enabled
;
35 link
->status
.connected
= connected
;
37 _host_dstcache_update_async(knet_h
, knet_h
->host_index
[host_id
]);
39 if ((link
->status
.dynconnected
) &&
40 (!link
->status
.connected
))
41 link
->status
.dynconnected
= 0;
44 time(&link
->status
.stats
.last_up_times
[link
->status
.stats
.last_up_time_index
]);
45 link
->status
.stats
.up_count
++;
46 if (++link
->status
.stats
.last_up_time_index
> MAX_LINK_EVENTS
) {
47 link
->status
.stats
.last_up_time_index
= 0;
50 time(&link
->status
.stats
.last_down_times
[link
->status
.stats
.last_down_time_index
]);
51 link
->status
.stats
.down_count
++;
52 if (++link
->status
.stats
.last_down_time_index
> MAX_LINK_EVENTS
) {
53 link
->status
.stats
.last_down_time_index
= 0;
59 void _link_clear_stats(knet_handle_t knet_h
)
61 struct knet_host
*host
;
62 struct knet_link
*link
;
66 for (host_id
= 0; host_id
< KNET_MAX_HOST
; host_id
++) {
67 host
= knet_h
->host_index
[host_id
];
71 for (link_id
= 0; link_id
< KNET_MAX_LINK
; link_id
++) {
72 link
= &host
->link
[link_id
];
73 memset(&link
->status
.stats
, 0, sizeof(struct knet_link_stats
));
78 int knet_link_set_config(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
80 struct sockaddr_storage
*src_addr
,
81 struct sockaddr_storage
*dst_addr
,
84 int savederrno
= 0, err
= 0, i
;
85 struct knet_host
*host
;
86 struct knet_link
*link
;
93 if (link_id
>= KNET_MAX_LINK
) {
103 if (dst_addr
&& (src_addr
->ss_family
!= dst_addr
->ss_family
)) {
104 log_err(knet_h
, KNET_SUB_LINK
, "Source address family does not match destination address family");
109 if (transport
>= KNET_MAX_TRANSPORTS
) {
114 savederrno
= get_global_wrlock(knet_h
);
116 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get write lock: %s",
117 strerror(savederrno
));
122 if (transport
== KNET_TRANSPORT_LOOPBACK
&& knet_h
->host_id
!= host_id
) {
123 log_err(knet_h
, KNET_SUB_LINK
, "Cannot create loopback link to remote node");
129 if (knet_h
->host_id
== host_id
&& knet_h
->has_loop_link
) {
130 log_err(knet_h
, KNET_SUB_LINK
, "Cannot create more than 1 link when loopback is active");
136 host
= knet_h
->host_index
[host_id
];
140 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
141 host_id
, strerror(savederrno
));
145 if (transport
== KNET_TRANSPORT_LOOPBACK
&& knet_h
->host_id
== host_id
) {
146 for (i
=0; i
<KNET_MAX_LINK
; i
++) {
147 if (host
->link
[i
].configured
) {
148 log_err(knet_h
, KNET_SUB_LINK
, "Cannot add loopback link when other links are already configured.");
156 link
= &host
->link
[link_id
];
158 if (link
->configured
!= 0) {
161 log_err(knet_h
, KNET_SUB_LINK
, "Host %u link %u is currently configured: %s",
162 host_id
, link_id
, strerror(savederrno
));
166 if (link
->status
.enabled
!= 0) {
169 log_err(knet_h
, KNET_SUB_LINK
, "Host %u link %u is currently in use: %s",
170 host_id
, link_id
, strerror(savederrno
));
174 memmove(&link
->src_addr
, src_addr
, sizeof(struct sockaddr_storage
));
176 err
= knet_addrtostr(src_addr
, sizeof(struct sockaddr_storage
),
177 link
->status
.src_ipaddr
, KNET_MAX_HOST_LEN
,
178 link
->status
.src_port
, KNET_MAX_PORT_LEN
);
180 if (err
== EAI_SYSTEM
) {
182 log_warn(knet_h
, KNET_SUB_LINK
,
183 "Unable to resolve host: %u link: %u source addr/port: %s",
184 host_id
, link_id
, strerror(savederrno
));
187 log_warn(knet_h
, KNET_SUB_LINK
,
188 "Unable to resolve host: %u link: %u source addr/port: %s",
189 host_id
, link_id
, gai_strerror(err
));
196 link
->dynamic
= KNET_LINK_DYNIP
;
199 link
->dynamic
= KNET_LINK_STATIC
;
201 memmove(&link
->dst_addr
, dst_addr
, sizeof(struct sockaddr_storage
));
202 err
= knet_addrtostr(dst_addr
, sizeof(struct sockaddr_storage
),
203 link
->status
.dst_ipaddr
, KNET_MAX_HOST_LEN
,
204 link
->status
.dst_port
, KNET_MAX_PORT_LEN
);
206 if (err
== EAI_SYSTEM
) {
208 log_warn(knet_h
, KNET_SUB_LINK
,
209 "Unable to resolve host: %u link: %u destination addr/port: %s",
210 host_id
, link_id
, strerror(savederrno
));
213 log_warn(knet_h
, KNET_SUB_LINK
,
214 "Unable to resolve host: %u link: %u destination addr/port: %s",
215 host_id
, link_id
, gai_strerror(err
));
222 link
->pong_count
= KNET_LINK_DEFAULT_PONG_COUNT
;
223 link
->has_valid_mtu
= 0;
224 link
->ping_interval
= KNET_LINK_DEFAULT_PING_INTERVAL
* 1000; /* microseconds */
225 link
->pong_timeout
= KNET_LINK_DEFAULT_PING_TIMEOUT
* 1000; /* microseconds */
226 link
->pong_timeout_backoff
= KNET_LINK_PONG_TIMEOUT_BACKOFF
;
227 link
->pong_timeout_adj
= link
->pong_timeout
* link
->pong_timeout_backoff
; /* microseconds */
228 link
->latency_fix
= KNET_LINK_DEFAULT_PING_PRECISION
;
229 link
->latency_exp
= KNET_LINK_DEFAULT_PING_PRECISION
- \
230 ((link
->ping_interval
* KNET_LINK_DEFAULT_PING_PRECISION
) / 8000000);
233 if (transport_link_set_config(knet_h
, link
, transport
) < 0) {
240 * we can only configure default access lists if we know both endpoints
241 * and the protocol uses GENERIC_ACL, otherwise the protocol has
242 * to setup their own access lists above in transport_link_set_config.
244 if ((transport_get_acl_type(knet_h
, transport
) == USE_GENERIC_ACL
) &&
245 (link
->dynamic
== KNET_LINK_STATIC
)) {
246 log_debug(knet_h
, KNET_SUB_LINK
, "Configuring default access lists for host: %u link: %u socket: %d",
247 host_id
, link_id
, link
->outsock
);
248 if ((check_add(knet_h
, link
->outsock
, transport
, -1,
249 &link
->dst_addr
, &link
->dst_addr
,
250 CHECK_TYPE_ADDRESS
, CHECK_ACCEPT
) < 0) && (errno
!= EEXIST
)) {
251 log_warn(knet_h
, KNET_SUB_LINK
, "Failed to configure default access lists for host: %u link: %u", host_id
, link_id
);
258 link
->configured
= 1;
259 log_debug(knet_h
, KNET_SUB_LINK
, "host: %u link: %u is configured",
262 if (transport
== KNET_TRANSPORT_LOOPBACK
) {
263 knet_h
->has_loop_link
= 1;
264 knet_h
->loop_link
= link_id
;
265 host
->status
.reachable
= 1;
266 link
->status
.mtu
= KNET_PMTUD_SIZE_V6
;
268 link
->status
.mtu
= KNET_PMTUD_MIN_MTU_V4
- KNET_HEADER_ALL_SIZE
- knet_h
->sec_header_size
;
269 link
->has_valid_mtu
= 1;
273 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
274 errno
= err
? savederrno
: 0;
278 int knet_link_get_config(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
280 struct sockaddr_storage
*src_addr
,
281 struct sockaddr_storage
*dst_addr
,
285 int savederrno
= 0, err
= 0;
286 struct knet_host
*host
;
287 struct knet_link
*link
;
294 if (link_id
>= KNET_MAX_LINK
) {
319 savederrno
= pthread_rwlock_rdlock(&knet_h
->global_rwlock
);
321 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get read lock: %s",
322 strerror(savederrno
));
327 host
= knet_h
->host_index
[host_id
];
331 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
332 host_id
, strerror(savederrno
));
336 link
= &host
->link
[link_id
];
338 if (!link
->configured
) {
341 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
342 host_id
, link_id
, strerror(savederrno
));
346 if ((link
->dynamic
== KNET_LINK_STATIC
) && (!dst_addr
)) {
352 memmove(src_addr
, &link
->src_addr
, sizeof(struct sockaddr_storage
));
354 *transport
= link
->transport
;
355 *flags
= link
->flags
;
357 if (link
->dynamic
== KNET_LINK_STATIC
) {
359 memmove(dst_addr
, &link
->dst_addr
, sizeof(struct sockaddr_storage
));
365 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
366 errno
= err
? savederrno
: 0;
370 int knet_link_clear_config(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
)
372 int savederrno
= 0, err
= 0;
373 struct knet_host
*host
;
374 struct knet_link
*link
;
383 if (link_id
>= KNET_MAX_LINK
) {
388 savederrno
= get_global_wrlock(knet_h
);
390 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get write lock: %s",
391 strerror(savederrno
));
396 host
= knet_h
->host_index
[host_id
];
400 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
401 host_id
, strerror(savederrno
));
405 link
= &host
->link
[link_id
];
407 if (link
->configured
!= 1) {
410 log_err(knet_h
, KNET_SUB_LINK
, "Host %u link %u is not configured: %s",
411 host_id
, link_id
, strerror(savederrno
));
415 if (link
->status
.enabled
!= 0) {
418 log_err(knet_h
, KNET_SUB_LINK
, "Host %u link %u is currently in use: %s",
419 host_id
, link_id
, strerror(savederrno
));
424 * remove well known access lists here.
425 * After the transport has done clearing the config,
426 * then we can remove any leftover access lists if the link
427 * is no longer in use.
429 if ((transport_get_acl_type(knet_h
, link
->transport
) == USE_GENERIC_ACL
) &&
430 (link
->dynamic
== KNET_LINK_STATIC
)) {
431 if ((check_rm(knet_h
, link
->outsock
, link
->transport
,
432 &link
->dst_addr
, &link
->dst_addr
,
433 CHECK_TYPE_ADDRESS
, CHECK_ACCEPT
) < 0) && (errno
!= ENOENT
)) {
436 log_err(knet_h
, KNET_SUB_LINK
, "Host %u link %u: unable to remove default access list",
443 * cache it for later as we don't know if the transport
444 * will clear link info during clear_config.
446 sock
= link
->outsock
;
447 transport
= link
->transport
;
449 if ((transport_link_clear_config(knet_h
, link
) < 0) &&
457 * remove any other access lists when the socket is no
458 * longer in use by the transport.
460 if ((transport_get_acl_type(knet_h
, link
->transport
) == USE_GENERIC_ACL
) &&
461 (knet_h
->knet_transport_fd_tracker
[sock
].transport
== KNET_MAX_TRANSPORTS
)) {
462 check_rmall(knet_h
, sock
, transport
);
465 memset(link
, 0, sizeof(struct knet_link
));
466 link
->link_id
= link_id
;
468 if (knet_h
->has_loop_link
&& host_id
== knet_h
->host_id
&& link_id
== knet_h
->loop_link
) {
469 knet_h
->has_loop_link
= 0;
470 if (host
->active_link_entries
== 0) {
471 host
->status
.reachable
= 0;
475 log_debug(knet_h
, KNET_SUB_LINK
, "host: %u link: %u config has been wiped",
479 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
480 errno
= err
? savederrno
: 0;
484 int knet_link_set_enable(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
485 unsigned int enabled
)
487 int savederrno
= 0, err
= 0;
488 struct knet_host
*host
;
489 struct knet_link
*link
;
496 if (link_id
>= KNET_MAX_LINK
) {
506 savederrno
= get_global_wrlock(knet_h
);
508 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get read lock: %s",
509 strerror(savederrno
));
514 host
= knet_h
->host_index
[host_id
];
518 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
519 host_id
, strerror(savederrno
));
523 link
= &host
->link
[link_id
];
525 if (!link
->configured
) {
528 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
529 host_id
, link_id
, strerror(savederrno
));
533 if (link
->status
.enabled
== enabled
) {
538 err
= _link_updown(knet_h
, host_id
, link_id
, enabled
, link
->status
.connected
);
545 log_debug(knet_h
, KNET_SUB_LINK
, "host: %u link: %u is disabled",
549 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
550 errno
= err
? savederrno
: 0;
554 int knet_link_get_enable(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
555 unsigned int *enabled
)
557 int savederrno
= 0, err
= 0;
558 struct knet_host
*host
;
559 struct knet_link
*link
;
566 if (link_id
>= KNET_MAX_LINK
) {
576 savederrno
= pthread_rwlock_rdlock(&knet_h
->global_rwlock
);
578 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get read lock: %s",
579 strerror(savederrno
));
584 host
= knet_h
->host_index
[host_id
];
588 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
589 host_id
, strerror(savederrno
));
593 link
= &host
->link
[link_id
];
595 if (!link
->configured
) {
598 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
599 host_id
, link_id
, strerror(savederrno
));
603 *enabled
= link
->status
.enabled
;
606 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
607 errno
= err
? savederrno
: 0;
611 int knet_link_set_pong_count(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
614 int savederrno
= 0, err
= 0;
615 struct knet_host
*host
;
616 struct knet_link
*link
;
623 if (link_id
>= KNET_MAX_LINK
) {
628 if (pong_count
< 1) {
633 savederrno
= get_global_wrlock(knet_h
);
635 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get write lock: %s",
636 strerror(savederrno
));
641 host
= knet_h
->host_index
[host_id
];
645 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
646 host_id
, strerror(savederrno
));
650 link
= &host
->link
[link_id
];
652 if (!link
->configured
) {
655 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
656 host_id
, link_id
, strerror(savederrno
));
660 link
->pong_count
= pong_count
;
662 log_debug(knet_h
, KNET_SUB_LINK
,
663 "host: %u link: %u pong count update: %u",
664 host_id
, link_id
, link
->pong_count
);
667 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
668 errno
= err
? savederrno
: 0;
672 int knet_link_get_pong_count(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
675 int savederrno
= 0, err
= 0;
676 struct knet_host
*host
;
677 struct knet_link
*link
;
684 if (link_id
>= KNET_MAX_LINK
) {
694 savederrno
= pthread_rwlock_rdlock(&knet_h
->global_rwlock
);
696 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get read lock: %s",
697 strerror(savederrno
));
702 host
= knet_h
->host_index
[host_id
];
706 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
707 host_id
, strerror(savederrno
));
711 link
= &host
->link
[link_id
];
713 if (!link
->configured
) {
716 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
717 host_id
, link_id
, strerror(savederrno
));
721 *pong_count
= link
->pong_count
;
724 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
725 errno
= err
? savederrno
: 0;
729 int knet_link_set_ping_timers(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
730 time_t interval
, time_t timeout
, unsigned int precision
)
732 int savederrno
= 0, err
= 0;
733 struct knet_host
*host
;
734 struct knet_link
*link
;
741 if (link_id
>= KNET_MAX_LINK
) {
761 savederrno
= get_global_wrlock(knet_h
);
763 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get write lock: %s",
764 strerror(savederrno
));
769 host
= knet_h
->host_index
[host_id
];
773 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
774 host_id
, strerror(savederrno
));
778 link
= &host
->link
[link_id
];
780 if (!link
->configured
) {
783 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
784 host_id
, link_id
, strerror(savederrno
));
788 link
->ping_interval
= interval
* 1000; /* microseconds */
789 link
->pong_timeout
= timeout
* 1000; /* microseconds */
790 link
->latency_fix
= precision
;
791 link
->latency_exp
= precision
- \
792 ((link
->ping_interval
* precision
) / 8000000);
794 log_debug(knet_h
, KNET_SUB_LINK
,
795 "host: %u link: %u timeout update - interval: %llu timeout: %llu precision: %u",
796 host_id
, link_id
, link
->ping_interval
, link
->pong_timeout
, precision
);
799 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
800 errno
= err
? savederrno
: 0;
804 int knet_link_get_ping_timers(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
805 time_t *interval
, time_t *timeout
, unsigned int *precision
)
807 int savederrno
= 0, err
= 0;
808 struct knet_host
*host
;
809 struct knet_link
*link
;
816 if (link_id
>= KNET_MAX_LINK
) {
836 savederrno
= pthread_rwlock_rdlock(&knet_h
->global_rwlock
);
838 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get read lock: %s",
839 strerror(savederrno
));
844 host
= knet_h
->host_index
[host_id
];
848 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
849 host_id
, strerror(savederrno
));
853 link
= &host
->link
[link_id
];
855 if (!link
->configured
) {
858 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
859 host_id
, link_id
, strerror(savederrno
));
863 *interval
= link
->ping_interval
/ 1000; /* microseconds */
864 *timeout
= link
->pong_timeout
/ 1000;
865 *precision
= link
->latency_fix
;
868 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
869 errno
= err
? savederrno
: 0;
873 int knet_link_set_priority(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
876 int savederrno
= 0, err
= 0;
877 struct knet_host
*host
;
878 struct knet_link
*link
;
879 uint8_t old_priority
;
886 if (link_id
>= KNET_MAX_LINK
) {
891 savederrno
= get_global_wrlock(knet_h
);
893 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get write lock: %s",
894 strerror(savederrno
));
899 host
= knet_h
->host_index
[host_id
];
903 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
904 host_id
, strerror(savederrno
));
908 link
= &host
->link
[link_id
];
910 if (!link
->configured
) {
913 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
914 host_id
, link_id
, strerror(savederrno
));
918 old_priority
= link
->priority
;
920 if (link
->priority
== priority
) {
925 link
->priority
= priority
;
927 if (_host_dstcache_update_sync(knet_h
, host
)) {
929 log_debug(knet_h
, KNET_SUB_LINK
,
930 "Unable to update link priority (host: %u link: %u priority: %u): %s",
931 host_id
, link_id
, link
->priority
, strerror(savederrno
));
932 link
->priority
= old_priority
;
937 log_debug(knet_h
, KNET_SUB_LINK
,
938 "host: %u link: %u priority set to: %u",
939 host_id
, link_id
, link
->priority
);
942 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
943 errno
= err
? savederrno
: 0;
947 int knet_link_get_priority(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
950 int savederrno
= 0, err
= 0;
951 struct knet_host
*host
;
952 struct knet_link
*link
;
959 if (link_id
>= KNET_MAX_LINK
) {
969 savederrno
= pthread_rwlock_rdlock(&knet_h
->global_rwlock
);
971 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get read lock: %s",
972 strerror(savederrno
));
977 host
= knet_h
->host_index
[host_id
];
981 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
982 host_id
, strerror(savederrno
));
986 link
= &host
->link
[link_id
];
988 if (!link
->configured
) {
991 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
992 host_id
, link_id
, strerror(savederrno
));
996 *priority
= link
->priority
;
999 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
1000 errno
= err
? savederrno
: 0;
1004 int knet_link_get_link_list(knet_handle_t knet_h
, knet_node_id_t host_id
,
1005 uint8_t *link_ids
, size_t *link_ids_entries
)
1007 int savederrno
= 0, err
= 0, i
, count
= 0;
1008 struct knet_host
*host
;
1009 struct knet_link
*link
;
1021 if (!link_ids_entries
) {
1026 savederrno
= pthread_rwlock_rdlock(&knet_h
->global_rwlock
);
1028 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get read lock: %s",
1029 strerror(savederrno
));
1034 host
= knet_h
->host_index
[host_id
];
1037 savederrno
= EINVAL
;
1038 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
1039 host_id
, strerror(savederrno
));
1043 for (i
= 0; i
< KNET_MAX_LINK
; i
++) {
1044 link
= &host
->link
[i
];
1045 if (!link
->configured
) {
1048 link_ids
[count
] = i
;
1052 *link_ids_entries
= count
;
1055 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
1056 errno
= err
? savederrno
: 0;
1060 int knet_link_get_status(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
1061 struct knet_link_status
*status
, size_t struct_size
)
1063 int savederrno
= 0, err
= 0;
1064 struct knet_host
*host
;
1065 struct knet_link
*link
;
1072 if (link_id
>= KNET_MAX_LINK
) {
1082 savederrno
= get_global_wrlock(knet_h
);
1084 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get read lock: %s",
1085 strerror(savederrno
));
1090 host
= knet_h
->host_index
[host_id
];
1093 savederrno
= EINVAL
;
1094 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
1095 host_id
, strerror(savederrno
));
1099 link
= &host
->link
[link_id
];
1101 if (!link
->configured
) {
1103 savederrno
= EINVAL
;
1104 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
1105 host_id
, link_id
, strerror(savederrno
));
1109 memmove(status
, &link
->status
, struct_size
);
1111 /* Calculate totals - no point in doing this on-the-fly */
1112 status
->stats
.rx_total_packets
=
1113 status
->stats
.rx_data_packets
+
1114 status
->stats
.rx_ping_packets
+
1115 status
->stats
.rx_pong_packets
+
1116 status
->stats
.rx_pmtu_packets
;
1117 status
->stats
.tx_total_packets
=
1118 status
->stats
.tx_data_packets
+
1119 status
->stats
.tx_ping_packets
+
1120 status
->stats
.tx_pong_packets
+
1121 status
->stats
.tx_pmtu_packets
;
1122 status
->stats
.rx_total_bytes
=
1123 status
->stats
.rx_data_bytes
+
1124 status
->stats
.rx_ping_bytes
+
1125 status
->stats
.rx_pong_bytes
+
1126 status
->stats
.rx_pmtu_bytes
;
1127 status
->stats
.tx_total_bytes
=
1128 status
->stats
.tx_data_bytes
+
1129 status
->stats
.tx_ping_bytes
+
1130 status
->stats
.tx_pong_bytes
+
1131 status
->stats
.tx_pmtu_bytes
;
1132 status
->stats
.tx_total_errors
=
1133 status
->stats
.tx_data_errors
+
1134 status
->stats
.tx_ping_errors
+
1135 status
->stats
.tx_pong_errors
+
1136 status
->stats
.tx_pmtu_errors
;
1137 status
->stats
.tx_total_retries
=
1138 status
->stats
.tx_data_retries
+
1139 status
->stats
.tx_ping_retries
+
1140 status
->stats
.tx_pong_retries
+
1141 status
->stats
.tx_pmtu_retries
;
1143 /* Tell the caller our full size in case they have an old version */
1144 status
->size
= sizeof(struct knet_link_status
);
1147 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
1148 errno
= err
? savederrno
: 0;
1152 int knet_link_add_acl(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
1153 struct sockaddr_storage
*ss1
,
1154 struct sockaddr_storage
*ss2
,
1155 check_type_t type
, check_acceptreject_t acceptreject
)
1157 int savederrno
= 0, err
= 0;
1158 struct knet_host
*host
;
1159 struct knet_link
*link
;
1171 if ((type
!= CHECK_TYPE_ADDRESS
) &&
1172 (type
!= CHECK_TYPE_MASK
) &&
1173 (type
!= CHECK_TYPE_RANGE
)) {
1178 if ((acceptreject
!= CHECK_ACCEPT
) &&
1179 (acceptreject
!= CHECK_REJECT
)) {
1184 if ((type
!= CHECK_TYPE_ADDRESS
) && (!ss2
)) {
1189 if ((type
== CHECK_TYPE_RANGE
) &&
1190 (ss1
->ss_family
!= ss2
->ss_family
)) {
1195 if (link_id
>= KNET_MAX_LINK
) {
1200 savederrno
= get_global_wrlock(knet_h
);
1202 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get write lock: %s",
1203 strerror(savederrno
));
1208 host
= knet_h
->host_index
[host_id
];
1211 savederrno
= EINVAL
;
1212 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
1213 host_id
, strerror(savederrno
));
1217 link
= &host
->link
[link_id
];
1219 if (!link
->configured
) {
1221 savederrno
= EINVAL
;
1222 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
1223 host_id
, link_id
, strerror(savederrno
));
1227 if (link
->dynamic
!= KNET_LINK_DYNIP
) {
1229 savederrno
= EINVAL
;
1230 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is a point to point connection: %s",
1231 host_id
, link_id
, strerror(savederrno
));
1235 err
= check_add(knet_h
, transport_link_get_acl_fd(knet_h
, link
), link
->transport
, -1,
1236 ss1
, ss2
, type
, acceptreject
);
1240 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
1246 int knet_link_insert_acl(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
1248 struct sockaddr_storage
*ss1
,
1249 struct sockaddr_storage
*ss2
,
1250 check_type_t type
, check_acceptreject_t acceptreject
)
1252 int savederrno
= 0, err
= 0;
1253 struct knet_host
*host
;
1254 struct knet_link
*link
;
1266 if ((type
!= CHECK_TYPE_ADDRESS
) &&
1267 (type
!= CHECK_TYPE_MASK
) &&
1268 (type
!= CHECK_TYPE_RANGE
)) {
1273 if ((acceptreject
!= CHECK_ACCEPT
) &&
1274 (acceptreject
!= CHECK_REJECT
)) {
1279 if ((type
!= CHECK_TYPE_ADDRESS
) && (!ss2
)) {
1284 if ((type
== CHECK_TYPE_RANGE
) &&
1285 (ss1
->ss_family
!= ss2
->ss_family
)) {
1290 if (link_id
>= KNET_MAX_LINK
) {
1295 savederrno
= get_global_wrlock(knet_h
);
1297 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get write lock: %s",
1298 strerror(savederrno
));
1303 host
= knet_h
->host_index
[host_id
];
1306 savederrno
= EINVAL
;
1307 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
1308 host_id
, strerror(savederrno
));
1312 link
= &host
->link
[link_id
];
1314 if (!link
->configured
) {
1316 savederrno
= EINVAL
;
1317 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
1318 host_id
, link_id
, strerror(savederrno
));
1322 if (link
->dynamic
!= KNET_LINK_DYNIP
) {
1324 savederrno
= EINVAL
;
1325 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is a point to point connection: %s",
1326 host_id
, link_id
, strerror(savederrno
));
1330 err
= check_add(knet_h
, transport_link_get_acl_fd(knet_h
, link
), link
->transport
, index
,
1331 ss1
, ss2
, type
, acceptreject
);
1335 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
1341 int knet_link_rm_acl(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
,
1342 struct sockaddr_storage
*ss1
,
1343 struct sockaddr_storage
*ss2
,
1344 check_type_t type
, check_acceptreject_t acceptreject
)
1346 int savederrno
= 0, err
= 0;
1347 struct knet_host
*host
;
1348 struct knet_link
*link
;
1360 if ((type
!= CHECK_TYPE_ADDRESS
) &&
1361 (type
!= CHECK_TYPE_MASK
) &&
1362 (type
!= CHECK_TYPE_RANGE
)) {
1367 if ((acceptreject
!= CHECK_ACCEPT
) &&
1368 (acceptreject
!= CHECK_REJECT
)) {
1373 if ((type
!= CHECK_TYPE_ADDRESS
) && (!ss2
)) {
1378 if ((type
== CHECK_TYPE_RANGE
) &&
1379 (ss1
->ss_family
!= ss2
->ss_family
)) {
1384 if (link_id
>= KNET_MAX_LINK
) {
1389 savederrno
= get_global_wrlock(knet_h
);
1391 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get write lock: %s",
1392 strerror(savederrno
));
1397 host
= knet_h
->host_index
[host_id
];
1400 savederrno
= EINVAL
;
1401 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
1402 host_id
, strerror(savederrno
));
1406 link
= &host
->link
[link_id
];
1408 if (!link
->configured
) {
1410 savederrno
= EINVAL
;
1411 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
1412 host_id
, link_id
, strerror(savederrno
));
1416 if (link
->dynamic
!= KNET_LINK_DYNIP
) {
1418 savederrno
= EINVAL
;
1419 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is a point to point connection: %s",
1420 host_id
, link_id
, strerror(savederrno
));
1424 err
= check_rm(knet_h
, transport_link_get_acl_fd(knet_h
, link
), link
->transport
,
1425 ss1
, ss2
, type
, acceptreject
);
1429 pthread_rwlock_unlock(&knet_h
->global_rwlock
);
1435 int knet_link_clear_acl(knet_handle_t knet_h
, knet_node_id_t host_id
, uint8_t link_id
)
1437 int savederrno
= 0, err
= 0;
1438 struct knet_host
*host
;
1439 struct knet_link
*link
;
1446 if (link_id
>= KNET_MAX_LINK
) {
1451 savederrno
= get_global_wrlock(knet_h
);
1453 log_err(knet_h
, KNET_SUB_LINK
, "Unable to get write lock: %s",
1454 strerror(savederrno
));
1459 host
= knet_h
->host_index
[host_id
];
1462 savederrno
= EINVAL
;
1463 log_err(knet_h
, KNET_SUB_LINK
, "Unable to find host %u: %s",
1464 host_id
, strerror(savederrno
));
1468 link
= &host
->link
[link_id
];
1470 if (!link
->configured
) {
1472 savederrno
= EINVAL
;
1473 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is not configured: %s",
1474 host_id
, link_id
, strerror(savederrno
));
1478 if (link
->dynamic
!= KNET_LINK_DYNIP
) {
1480 savederrno
= EINVAL
;
1481 log_err(knet_h
, KNET_SUB_LINK
, "host %u link %u is a point to point connection: %s",
1482 host_id
, link_id
, strerror(savederrno
));
1486 check_rmall(knet_h
, transport_link_get_acl_fd(knet_h
, link
), link
->transport
);
1489 pthread_rwlock_unlock(&knet_h
->global_rwlock
);