11cb875aeSCathy Zhou /* 21cb875aeSCathy Zhou * CDDL HEADER START 31cb875aeSCathy Zhou * 41cb875aeSCathy Zhou * The contents of this file are subject to the terms of the 51cb875aeSCathy Zhou * Common Development and Distribution License (the "License"). 61cb875aeSCathy Zhou * You may not use this file except in compliance with the License. 71cb875aeSCathy Zhou * 81cb875aeSCathy Zhou * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91cb875aeSCathy Zhou * or http://www.opensolaris.org/os/licensing. 101cb875aeSCathy Zhou * See the License for the specific language governing permissions 111cb875aeSCathy Zhou * and limitations under the License. 121cb875aeSCathy Zhou * 131cb875aeSCathy Zhou * When distributing Covered Code, include this CDDL HEADER in each 141cb875aeSCathy Zhou * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151cb875aeSCathy Zhou * If applicable, add the following below this CDDL HEADER, with the 161cb875aeSCathy Zhou * fields enclosed by brackets "[]" replaced with your own identifying 171cb875aeSCathy Zhou * information: Portions Copyright [yyyy] [name of copyright owner] 181cb875aeSCathy Zhou * 191cb875aeSCathy Zhou * CDDL HEADER END 201cb875aeSCathy Zhou */ 211cb875aeSCathy Zhou 221cb875aeSCathy Zhou /* 23*c5e0ece0SCathy Zhou * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 241cb875aeSCathy Zhou * Use is subject to license terms. 251cb875aeSCathy Zhou */ 261cb875aeSCathy Zhou 271cb875aeSCathy Zhou #ifndef _LIBVRRPADM_H 281cb875aeSCathy Zhou #define _LIBVRRPADM_H 291cb875aeSCathy Zhou 301cb875aeSCathy Zhou #include <sys/types.h> 311cb875aeSCathy Zhou #include <sys/socket.h> 321cb875aeSCathy Zhou #include <netinet/in.h> /* in(6)_addr_t */ 331cb875aeSCathy Zhou #include <arpa/inet.h> 341cb875aeSCathy Zhou #include <net/if.h> /* LIFNAMSIZ */ 351cb875aeSCathy Zhou #include <limits.h> 361cb875aeSCathy Zhou #include <netinet/vrrp.h> 371cb875aeSCathy Zhou #include <syslog.h> 381cb875aeSCathy Zhou #include <libdladm.h> 391cb875aeSCathy Zhou 401cb875aeSCathy Zhou #ifdef __cplusplus 411cb875aeSCathy Zhou extern "C" { 421cb875aeSCathy Zhou #endif 431cb875aeSCathy Zhou 441cb875aeSCathy Zhou #define VRRP_NAME_MAX 32 451cb875aeSCathy Zhou #define VRRPD_SOCKET "/var/run/vrrpd.socket" 461cb875aeSCathy Zhou 471cb875aeSCathy Zhou /* 481cb875aeSCathy Zhou * to store the IP addresses 491cb875aeSCathy Zhou */ 501cb875aeSCathy Zhou typedef struct vrrp_addr { 511cb875aeSCathy Zhou union { 521cb875aeSCathy Zhou struct sockaddr_in a4; 531cb875aeSCathy Zhou struct sockaddr_in6 a6; 541cb875aeSCathy Zhou } in; 551cb875aeSCathy Zhou #define in4 in.a4 561cb875aeSCathy Zhou #define in6 in.a6 571cb875aeSCathy Zhou } vrrp_addr_t; 581cb875aeSCathy Zhou 591cb875aeSCathy Zhou /* 601cb875aeSCathy Zhou * VRRP instance (configuration information). 611cb875aeSCathy Zhou * Passed to vrrp_create(), returned by vrrp_query(). 621cb875aeSCathy Zhou */ 631cb875aeSCathy Zhou typedef struct vrrp_vr_conf_s { 641cb875aeSCathy Zhou char vvc_name[VRRP_NAME_MAX]; /* VRRP router name */ 651cb875aeSCathy Zhou char vvc_link[MAXLINKNAMELEN]; /* data-link name */ 661cb875aeSCathy Zhou vrid_t vvc_vrid; /* VRID */ 671cb875aeSCathy Zhou int vvc_af; /* IPv4/IPv6 */ 681cb875aeSCathy Zhou int vvc_pri; 691cb875aeSCathy Zhou uint32_t vvc_adver_int; /* in ms */ 701cb875aeSCathy Zhou boolean_t vvc_preempt; 711cb875aeSCathy Zhou boolean_t vvc_accept; 721cb875aeSCathy Zhou boolean_t vvc_enabled; 731cb875aeSCathy Zhou } vrrp_vr_conf_t; 741cb875aeSCathy Zhou 751cb875aeSCathy Zhou /* 761cb875aeSCathy Zhou * VRRP state machine 771cb875aeSCathy Zhou */ 781cb875aeSCathy Zhou typedef enum { 791cb875aeSCathy Zhou VRRP_STATE_NONE = -1, 801cb875aeSCathy Zhou VRRP_STATE_INIT, 811cb875aeSCathy Zhou VRRP_STATE_MASTER, 821cb875aeSCathy Zhou VRRP_STATE_BACKUP 831cb875aeSCathy Zhou } vrrp_state_t; 841cb875aeSCathy Zhou 851cb875aeSCathy Zhou /* 861cb875aeSCathy Zhou * VRRP status structure 871cb875aeSCathy Zhou * Returned by vrrp_query() as part of vrrp_queryinfo_t. 881cb875aeSCathy Zhou */ 891cb875aeSCathy Zhou typedef struct vrrp_statusinfo_s { 901cb875aeSCathy Zhou vrrp_state_t vs_state; 911cb875aeSCathy Zhou vrrp_state_t vs_prev_state; 921cb875aeSCathy Zhou struct timeval vs_st_time; /* timestamp of last state trans */ 931cb875aeSCathy Zhou } vrrp_stateinfo_t; 941cb875aeSCathy Zhou 951cb875aeSCathy Zhou /* 961cb875aeSCathy Zhou * The information obtained from peer's advertisements 971cb875aeSCathy Zhou * Returned by vrrp_query() as part of vrrp_queryinfo_t. 981cb875aeSCathy Zhou */ 991cb875aeSCathy Zhou typedef struct vrrp_peer_s { 1001cb875aeSCathy Zhou vrrp_addr_t vp_addr; /* source IP addr of the message */ 1011cb875aeSCathy Zhou int vp_prio; /* priority in adv message */ 1021cb875aeSCathy Zhou struct timeval vp_time; /* timestamp of the adv message */ 1031cb875aeSCathy Zhou int vp_adver_int; /* adv interval in adv message */ 1041cb875aeSCathy Zhou } vrrp_peer_t; 1051cb875aeSCathy Zhou 1061cb875aeSCathy Zhou /* 1071cb875aeSCathy Zhou * Useful timer information, in ms 1081cb875aeSCathy Zhou */ 1091cb875aeSCathy Zhou typedef struct vrrp_timeinfo_s { 1101cb875aeSCathy Zhou int vt_since_last_tran; /* time since last state transition */ 1111cb875aeSCathy Zhou int vt_since_last_adv; /* time since last advertisement */ 1121cb875aeSCathy Zhou int vt_master_down_intv; /* timer interval for backup to */ 1131cb875aeSCathy Zhou /* declare master down */ 1141cb875aeSCathy Zhou } vrrp_timerinfo_t; 1151cb875aeSCathy Zhou 1161cb875aeSCathy Zhou /* 1171cb875aeSCathy Zhou * Address information 1181cb875aeSCathy Zhou */ 1191cb875aeSCathy Zhou typedef struct vrrp_addrinfo_s { 1201cb875aeSCathy Zhou char va_vnic[MAXLINKNAMELEN]; 1211cb875aeSCathy Zhou vrrp_addr_t va_primary; 1221cb875aeSCathy Zhou uint32_t va_vipcnt; 1231cb875aeSCathy Zhou vrrp_addr_t va_vips[1]; 1241cb875aeSCathy Zhou } vrrp_addrinfo_t; 1251cb875aeSCathy Zhou 1261cb875aeSCathy Zhou /* 1271cb875aeSCathy Zhou * VRRP instance configuration and run-time states information 1281cb875aeSCathy Zhou * Returned by vrrp_query(). 1291cb875aeSCathy Zhou */ 1301cb875aeSCathy Zhou typedef struct vrrp_queryinfo { 1311cb875aeSCathy Zhou vrrp_vr_conf_t show_vi; 1321cb875aeSCathy Zhou vrrp_stateinfo_t show_vs; 1331cb875aeSCathy Zhou vrrp_peer_t show_vp; 1341cb875aeSCathy Zhou vrrp_timerinfo_t show_vt; 1351cb875aeSCathy Zhou vrrp_addrinfo_t show_va; 1361cb875aeSCathy Zhou } vrrp_queryinfo_t; 1371cb875aeSCathy Zhou 1381cb875aeSCathy Zhou /* 1391cb875aeSCathy Zhou * flags sent with the VRRP_CMD_MODIFY command. Used in vrrp_setprop(). 1401cb875aeSCathy Zhou */ 1411cb875aeSCathy Zhou #define VRRP_CONF_PRIORITY 0x01 1421cb875aeSCathy Zhou #define VRRP_CONF_INTERVAL 0x02 1431cb875aeSCathy Zhou #define VRRP_CONF_PREEMPT 0x04 1441cb875aeSCathy Zhou #define VRRP_CONF_ACCEPT 0x08 1451cb875aeSCathy Zhou 1461cb875aeSCathy Zhou /* 1471cb875aeSCathy Zhou * Errors 1481cb875aeSCathy Zhou */ 1491cb875aeSCathy Zhou typedef enum { 1501cb875aeSCathy Zhou VRRP_SUCCESS = 0, 1511cb875aeSCathy Zhou VRRP_EINVAL, /* invalid parameter */ 1521cb875aeSCathy Zhou VRRP_EINVALVRNAME, /* invalid router name */ 1531cb875aeSCathy Zhou VRRP_ENOMEM, /* no memory */ 1541cb875aeSCathy Zhou VRRP_ENOVIRT, /* no virtual IP addresses */ 1551cb875aeSCathy Zhou VRRP_ENOPRIM, /* no primary IP address */ 1561cb875aeSCathy Zhou VRRP_ENOVNIC, /* no vnic created */ 1571cb875aeSCathy Zhou VRRP_ENOLINK, /* the link does not exist */ 1581cb875aeSCathy Zhou VRRP_EINVALLINK, /* invalid link */ 1591cb875aeSCathy Zhou VRRP_EINVALADDR, /* invalid IP address */ 1601cb875aeSCathy Zhou VRRP_EINVALAF, /* invalid IP address familty */ 1611cb875aeSCathy Zhou VRRP_EDB, /* configuration error */ 1621cb875aeSCathy Zhou VRRP_EPERM, /* permission denied */ 1631cb875aeSCathy Zhou VRRP_EBADSTATE, /* VRRP router in bad state */ 1641cb875aeSCathy Zhou VRRP_EVREXIST, /* <vrid, intf, af> three-tuple exists */ 1651cb875aeSCathy Zhou VRRP_EINSTEXIST, /* router name already exists */ 1661cb875aeSCathy Zhou VRRP_EEXIST, /* already exists */ 1671cb875aeSCathy Zhou VRRP_ENOTFOUND, /* vrrp router not found */ 1681cb875aeSCathy Zhou VRRP_ETOOSMALL, /* too small space */ 1691cb875aeSCathy Zhou VRRP_EAGAIN, /* Try again */ 1701cb875aeSCathy Zhou VRRP_EALREADY, /* already */ 1711cb875aeSCathy Zhou VRRP_EDLADM, /* dladm failure */ 1721cb875aeSCathy Zhou VRRP_EIPADM, /* ipadm failure */ 1731cb875aeSCathy Zhou VRRP_ESYS, /* system error */ 174*c5e0ece0SCathy Zhou VRRP_ENOSVC /* VRRP service not enabled */ 1751cb875aeSCathy Zhou } vrrp_err_t; 1761cb875aeSCathy Zhou 1771cb875aeSCathy Zhou /* 1781cb875aeSCathy Zhou * Internal commands used between vrrpadm and vrrpd. 1791cb875aeSCathy Zhou */ 1801cb875aeSCathy Zhou typedef enum { 1811cb875aeSCathy Zhou VRRP_CMD_RETURN = 0, 1821cb875aeSCathy Zhou VRRP_CMD_CREATE, 1831cb875aeSCathy Zhou VRRP_CMD_DELETE, 1841cb875aeSCathy Zhou VRRP_CMD_ENABLE, 1851cb875aeSCathy Zhou VRRP_CMD_DISABLE, 1861cb875aeSCathy Zhou VRRP_CMD_MODIFY, 1871cb875aeSCathy Zhou VRRP_CMD_LIST, 1881cb875aeSCathy Zhou VRRP_CMD_QUERY 1891cb875aeSCathy Zhou } vrrp_cmd_type_t; 1901cb875aeSCathy Zhou 1911cb875aeSCathy Zhou #define addr_len(af) ((af) == AF_INET ? sizeof (in_addr_t): sizeof (in6_addr_t)) 1921cb875aeSCathy Zhou 1931cb875aeSCathy Zhou #define VRRPADDR_UNSPECIFIED(af, addr) \ 1941cb875aeSCathy Zhou (((af) == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED( \ 1951cb875aeSCathy Zhou &(addr)->in6.sin6_addr)) || ((af) == AF_INET && \ 1961cb875aeSCathy Zhou ((addr)->in4.sin_addr.s_addr == INADDR_ANY))) 1971cb875aeSCathy Zhou 1981cb875aeSCathy Zhou #define VRRPADDR2STR(af, addr, abuf, size, append) { \ 1991cb875aeSCathy Zhou char ap[INET6_ADDRSTRLEN]; \ 2001cb875aeSCathy Zhou \ 2011cb875aeSCathy Zhou if (VRRPADDR_UNSPECIFIED(af, addr)) { \ 2021cb875aeSCathy Zhou (void) strlcpy(ap, "--", INET6_ADDRSTRLEN); \ 2031cb875aeSCathy Zhou } else if ((af) == AF_INET) { \ 2041cb875aeSCathy Zhou (void) inet_ntop((af), &(addr)->in4.sin_addr, ap, \ 2051cb875aeSCathy Zhou INET6_ADDRSTRLEN); \ 2061cb875aeSCathy Zhou } else { \ 2071cb875aeSCathy Zhou (void) inet_ntop((af), &(addr)->in6.sin6_addr, ap, \ 2081cb875aeSCathy Zhou INET6_ADDRSTRLEN); \ 2091cb875aeSCathy Zhou } \ 2101cb875aeSCathy Zhou if (append) \ 2111cb875aeSCathy Zhou (void) strlcat(abuf, ap, size); \ 2121cb875aeSCathy Zhou else \ 2131cb875aeSCathy Zhou (void) strlcpy(abuf, ap, size); \ 2141cb875aeSCathy Zhou } 2151cb875aeSCathy Zhou 2161cb875aeSCathy Zhou typedef struct vrrp_cmd_create_s { 2171cb875aeSCathy Zhou uint32_t vcc_cmd; 2181cb875aeSCathy Zhou vrrp_vr_conf_t vcc_conf; 2191cb875aeSCathy Zhou } vrrp_cmd_create_t; 2201cb875aeSCathy Zhou 2211cb875aeSCathy Zhou typedef struct vrrp_ret_create_s { 2221cb875aeSCathy Zhou vrrp_err_t vrc_err; 2231cb875aeSCathy Zhou } vrrp_ret_create_t; 2241cb875aeSCathy Zhou 2251cb875aeSCathy Zhou typedef struct vrrp_cmd_delete_s { 2261cb875aeSCathy Zhou uint32_t vcd_cmd; 2271cb875aeSCathy Zhou char vcd_name[VRRP_NAME_MAX]; 2281cb875aeSCathy Zhou } vrrp_cmd_delete_t; 2291cb875aeSCathy Zhou 2301cb875aeSCathy Zhou typedef struct vrrp_ret_delete_s { 2311cb875aeSCathy Zhou vrrp_err_t vrd_err; 2321cb875aeSCathy Zhou } vrrp_ret_delete_t; 2331cb875aeSCathy Zhou 2341cb875aeSCathy Zhou typedef struct vrrp_cmd_enable_s { 2351cb875aeSCathy Zhou uint32_t vcs_cmd; 2361cb875aeSCathy Zhou char vcs_name[VRRP_NAME_MAX]; 2371cb875aeSCathy Zhou } vrrp_cmd_enable_t; 2381cb875aeSCathy Zhou 2391cb875aeSCathy Zhou typedef struct vrrp_ret_enable_s { 2401cb875aeSCathy Zhou vrrp_err_t vrs_err; 2411cb875aeSCathy Zhou } vrrp_ret_enable_t; 2421cb875aeSCathy Zhou 2431cb875aeSCathy Zhou typedef struct vrrp_cmd_disable_s { 2441cb875aeSCathy Zhou uint32_t vcx_cmd; 2451cb875aeSCathy Zhou char vcx_name[VRRP_NAME_MAX]; 2461cb875aeSCathy Zhou } vrrp_cmd_disable_t; 2471cb875aeSCathy Zhou 2481cb875aeSCathy Zhou typedef struct vrrp_ret_disable_s { 2491cb875aeSCathy Zhou vrrp_err_t vrx_err; 2501cb875aeSCathy Zhou } vrrp_ret_disable_t; 2511cb875aeSCathy Zhou 2521cb875aeSCathy Zhou typedef struct vrrp_cmd_modify_s { 2531cb875aeSCathy Zhou uint32_t vcm_cmd; 2541cb875aeSCathy Zhou uint32_t vcm_mask; 2551cb875aeSCathy Zhou vrrp_vr_conf_t vcm_conf; 2561cb875aeSCathy Zhou } vrrp_cmd_modify_t; 2571cb875aeSCathy Zhou 2581cb875aeSCathy Zhou typedef struct vrrp_ret_modify_s { 2591cb875aeSCathy Zhou vrrp_err_t vrm_err; 2601cb875aeSCathy Zhou } vrrp_ret_modify_t; 2611cb875aeSCathy Zhou 2621cb875aeSCathy Zhou typedef struct vrrp_cmd_list_s { 2631cb875aeSCathy Zhou uint32_t vcl_cmd; 2641cb875aeSCathy Zhou vrid_t vcl_vrid; 2651cb875aeSCathy Zhou char vcl_ifname[LIFNAMSIZ]; 2661cb875aeSCathy Zhou int vcl_af; 2671cb875aeSCathy Zhou } vrrp_cmd_list_t; 2681cb875aeSCathy Zhou 2691cb875aeSCathy Zhou typedef struct vrrp_ret_list_s { 2701cb875aeSCathy Zhou vrrp_err_t vrl_err; 2711cb875aeSCathy Zhou uint32_t vrl_cnt; 2721cb875aeSCathy Zhou /* 2731cb875aeSCathy Zhou * When vrl_cnt is non-zero, the return structure will be followed 2741cb875aeSCathy Zhou * by the list of router names, separated by '\0'. Its size will 2751cb875aeSCathy Zhou * be vrl_cnt * VRRP_NAME_MAX. 2761cb875aeSCathy Zhou */ 2771cb875aeSCathy Zhou } vrrp_ret_list_t; 2781cb875aeSCathy Zhou 2791cb875aeSCathy Zhou typedef struct vrrp_cmd_query_s { 2801cb875aeSCathy Zhou uint32_t vcq_cmd; 2811cb875aeSCathy Zhou char vcq_name[VRRP_NAME_MAX]; 2821cb875aeSCathy Zhou } vrrp_cmd_query_t; 2831cb875aeSCathy Zhou 2841cb875aeSCathy Zhou typedef struct vrrp_ret_query_s { 2851cb875aeSCathy Zhou vrrp_err_t vrq_err; 2861cb875aeSCathy Zhou vrrp_queryinfo_t vrq_qinfo; 2871cb875aeSCathy Zhou } vrrp_ret_query_t; 2881cb875aeSCathy Zhou 2891cb875aeSCathy Zhou /* 2901cb875aeSCathy Zhou * Union of all VRRP commands 2911cb875aeSCathy Zhou */ 2921cb875aeSCathy Zhou typedef union vrrp_cmd_s { 2931cb875aeSCathy Zhou uint32_t vc_cmd; 2941cb875aeSCathy Zhou vrrp_cmd_create_t vc_cmd_create; 2951cb875aeSCathy Zhou vrrp_cmd_delete_t vc_cmd_delete; 2961cb875aeSCathy Zhou vrrp_cmd_enable_t vc_cmd_enable; 2971cb875aeSCathy Zhou vrrp_cmd_disable_t vc_cmd_disable; 2981cb875aeSCathy Zhou vrrp_cmd_modify_t vc_cmd_modify; 2991cb875aeSCathy Zhou vrrp_cmd_list_t vc_cmd_list; 3001cb875aeSCathy Zhou } vrrp_cmd_t; 3011cb875aeSCathy Zhou 3021cb875aeSCathy Zhou /* 3031cb875aeSCathy Zhou * Union of all VRRP replies of the VRRP commands 3041cb875aeSCathy Zhou */ 3051cb875aeSCathy Zhou typedef union vrrp_ret_s { 3061cb875aeSCathy Zhou vrrp_err_t vr_err; 3071cb875aeSCathy Zhou vrrp_ret_create_t vr_ret_create; 3081cb875aeSCathy Zhou vrrp_ret_delete_t vr_ret_delete; 3091cb875aeSCathy Zhou vrrp_ret_enable_t vr_ret_enable; 3101cb875aeSCathy Zhou vrrp_ret_disable_t vr_ret_disable; 3111cb875aeSCathy Zhou vrrp_ret_modify_t vr_ret_modify; 3121cb875aeSCathy Zhou vrrp_ret_list_t vr_ret_list; 3131cb875aeSCathy Zhou vrrp_ret_query_t vr_ret_query; 3141cb875aeSCathy Zhou } vrrp_ret_t; 3151cb875aeSCathy Zhou 3161cb875aeSCathy Zhou /* 3171cb875aeSCathy Zhou * Public APIs 3181cb875aeSCathy Zhou */ 3191cb875aeSCathy Zhou struct vrrp_handle { 3201cb875aeSCathy Zhou dladm_handle_t vh_dh; 3211cb875aeSCathy Zhou }; 3221cb875aeSCathy Zhou typedef struct vrrp_handle *vrrp_handle_t; 3231cb875aeSCathy Zhou 3241cb875aeSCathy Zhou const char *vrrp_err2str(vrrp_err_t); 3251cb875aeSCathy Zhou const char *vrrp_state2str(vrrp_state_t); 3261cb875aeSCathy Zhou 3271cb875aeSCathy Zhou vrrp_err_t vrrp_open(vrrp_handle_t *); 3281cb875aeSCathy Zhou void vrrp_close(vrrp_handle_t); 3291cb875aeSCathy Zhou 3301cb875aeSCathy Zhou boolean_t vrrp_valid_name(const char *); 3311cb875aeSCathy Zhou 3321cb875aeSCathy Zhou vrrp_err_t vrrp_create(vrrp_handle_t, vrrp_vr_conf_t *); 3331cb875aeSCathy Zhou vrrp_err_t vrrp_delete(vrrp_handle_t, const char *); 3341cb875aeSCathy Zhou 3351cb875aeSCathy Zhou vrrp_err_t vrrp_enable(vrrp_handle_t, const char *); 3361cb875aeSCathy Zhou vrrp_err_t vrrp_disable(vrrp_handle_t, const char *); 3371cb875aeSCathy Zhou 3381cb875aeSCathy Zhou vrrp_err_t vrrp_modify(vrrp_handle_t, vrrp_vr_conf_t *, uint32_t); 3391cb875aeSCathy Zhou 3401cb875aeSCathy Zhou vrrp_err_t vrrp_query(vrrp_handle_t, const char *, vrrp_queryinfo_t **); 3411cb875aeSCathy Zhou 3421cb875aeSCathy Zhou vrrp_err_t vrrp_list(vrrp_handle_t, vrid_t, const char *, int, 3431cb875aeSCathy Zhou uint32_t *, char *); 3441cb875aeSCathy Zhou 3451cb875aeSCathy Zhou boolean_t vrrp_is_vrrp_vnic(vrrp_handle_t, datalink_id_t, 3461cb875aeSCathy Zhou datalink_id_t *, uint16_t *, vrid_t *, int *); 3471cb875aeSCathy Zhou 3481cb875aeSCathy Zhou vrrp_err_t vrrp_get_vnicname(vrrp_handle_t, vrid_t, int, char *, 3491cb875aeSCathy Zhou datalink_id_t *, uint16_t *, char *, size_t); 3501cb875aeSCathy Zhou 3511cb875aeSCathy Zhou #ifdef __cplusplus 3521cb875aeSCathy Zhou } 3531cb875aeSCathy Zhou #endif 3541cb875aeSCathy Zhou 3551cb875aeSCathy Zhou #endif /* _LIBVRRPADM_H */ 356