1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
#!/usr/bin/env python3
# Copyright (C) 2023 Canonical, Ltd.
# Author: Lukas Märdian <slyon@ubuntu.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# 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 this program. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
from cffi import FFI
ffibuilder = FFI()
# cdef() expects a single string declaring the C types, functions and
# globals needed to use the shared object. It must be in valid C syntax.
ffibuilder.cdef("""
#define UINT_MAX ...
typedef int gboolean;
typedef unsigned int guint;
typedef int gint;
typedef struct GError NetplanError;
typedef struct netplan_parser NetplanParser;
typedef struct netplan_state NetplanState;
typedef struct netplan_net_definition NetplanNetDefinition;
typedef enum { ... } NetplanBackend;
typedef enum { ... } NetplanDefType;
// TODO: Introduce getters for .address/.lifetime/.label to avoid exposing the raw struct
typedef struct {
char* address;
char* lifetime;
char* label;
} NetplanAddressOptions;
struct address_iter { ...; };
struct nameserver_iter { ...; };
struct route_iter { ...; };
// TODO: Introduce getters for all these fields to avoid exposing the raw struct
typedef struct {
gint family;
char* type;
char* scope;
guint table;
char* from;
char* to;
char* via;
gboolean onlink;
guint metric;
guint mtubytes;
guint congestion_window;
guint advertised_receive_window;
guint advmss;
} NetplanIPRoute;
// Error handling
uint64_t netplan_error_code(NetplanError* error);
ssize_t netplan_error_message(NetplanError* error, char* buf, size_t buf_size);
// Parser
NetplanParser* netplan_parser_new();
void netplan_parser_clear(NetplanParser **npp);
gboolean netplan_parser_set_flags(NetplanParser *npp, unsigned int flags, NetplanError** error);
unsigned int netplan_parser_get_flags(NetplanParser *npp);
unsigned int netplan_parser_get_error_count(NetplanParser *npp);
gboolean netplan_parser_load_yaml(NetplanParser* npp, const char* filename, NetplanError** error);
gboolean netplan_parser_load_yaml_from_fd(NetplanParser* npp, int input_fd, NetplanError** error);
gboolean netplan_parser_load_yaml_hierarchy(NetplanParser* npp, const char* rootdir, NetplanError** error);
gboolean netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, NetplanError** error);
gboolean netplan_parser_load_nullable_fields(NetplanParser* npp, int input_fd, NetplanError** error);
gboolean netplan_parser_load_nullable_overrides(
NetplanParser* npp, int input_fd, const char* constraint, NetplanError** error);
// State
NetplanState* netplan_state_new();
void netplan_state_clear(NetplanState** np_state);
NetplanBackend netplan_state_get_backend(const NetplanState* np_state);
gboolean netplan_state_import_parser_results(NetplanState* np_state, NetplanParser* npp, NetplanError** error);
gboolean netplan_state_update_yaml_hierarchy(
const NetplanState* np_state, const char* default_filename, const char* rootdir, NetplanError** error);
gboolean netplan_state_write_yaml_file(
const NetplanState* np_state, const char* filename, const char* rootdir, NetplanError** error);
gboolean netplan_state_dump_yaml(const NetplanState* np_state, int output_fd, NetplanError** error);
NetplanNetDefinition* netplan_state_get_netdef(const NetplanState* np_state, const char* id);
guint netplan_state_get_netdefs_size(const NetplanState* np_state);
// NetDefinition
ssize_t netplan_netdef_get_id(const NetplanNetDefinition* netdef, char* out_buffer, size_t out_buffer_size);
NetplanDefType netplan_netdef_get_type(const NetplanNetDefinition* netdef);
NetplanBackend netplan_netdef_get_backend(const NetplanNetDefinition* netdef);
ssize_t netplan_netdef_get_filepath(const NetplanNetDefinition* netdef, char* out_buffer, size_t out_buffer_size);
NetplanNetDefinition* netplan_netdef_get_bridge_link(const NetplanNetDefinition* netdef);
NetplanNetDefinition* netplan_netdef_get_bond_link(const NetplanNetDefinition* netdef);
NetplanNetDefinition* netplan_netdef_get_peer_link(const NetplanNetDefinition* netdef);
NetplanNetDefinition* netplan_netdef_get_vlan_link(const NetplanNetDefinition* netdef);
NetplanNetDefinition* netplan_netdef_get_sriov_link(const NetplanNetDefinition* netdef);
NetplanNetDefinition* netplan_netdef_get_vrf_link(const NetplanNetDefinition* netdef);
ssize_t netplan_netdef_get_set_name(const NetplanNetDefinition* netdef, char* out_buffer, size_t out_buffer_size);
gboolean netplan_netdef_has_match(const NetplanNetDefinition* netdef);
gboolean netplan_netdef_match_interface(
const NetplanNetDefinition* netdef, const char* name, const char* mac, const char* driver_name);
gboolean netplan_netdef_get_dhcp4(const NetplanNetDefinition* netdef);
gboolean netplan_netdef_get_dhcp6(const NetplanNetDefinition* netdef);
gboolean netplan_netdef_get_link_local_ipv4(const NetplanNetDefinition* netdef);
gboolean netplan_netdef_get_link_local_ipv6(const NetplanNetDefinition* netdef);
int netplan_netdef_get_accept_ra(const NetplanNetDefinition* netdef);
ssize_t netplan_netdef_get_macaddress(const NetplanNetDefinition* netdef, char* out_buffer, size_t out_buffer_size);
// NetDefinition (internal)
ssize_t _netplan_netdef_get_embedded_switch_mode(const NetplanNetDefinition* netdef, char* out_buffer, size_t out_buf_size);
gboolean _netplan_netdef_get_sriov_vlan_filter(const NetplanNetDefinition* netdef);
guint _netplan_netdef_get_vlan_id(const NetplanNetDefinition* netdef);
gboolean _netplan_netdef_get_critical(const NetplanNetDefinition* netdef);
gboolean _netplan_netdef_get_delay_virtual_functions_rebind(const NetplanNetDefinition* netdef);
gboolean _netplan_netdef_is_trivial_compound_itf(const NetplanNetDefinition* netdef);
int _netplan_state_get_vf_count_for_def(
const NetplanState* np_state, const NetplanNetDefinition* netdef, NetplanError** error);
ssize_t _netplan_netdef_get_bond_mode(const NetplanNetDefinition* netdef, char* out_buffer, size_t out_buf_size);
ssize_t _netplan_netdef_get_gateway4(const NetplanNetDefinition* netdef, char* out_buffer, size_t out_buffer_size);
ssize_t _netplan_netdef_get_gateway6(const NetplanNetDefinition* netdef, char* out_buffer, size_t out_buffer_size);
// Iterators (internal)
struct netdef_pertype_iter* _netplan_state_new_netdef_pertype_iter(NetplanState* np_state, const char* def_type);
NetplanNetDefinition* _netplan_netdef_pertype_iter_next(struct netdef_pertype_iter* it);
void _netplan_netdef_pertype_iter_free(struct netdef_pertype_iter* it);
struct address_iter* _netplan_netdef_new_address_iter(NetplanNetDefinition* netdef);
NetplanAddressOptions* _netplan_address_iter_next(struct address_iter* it);
void _netplan_address_iter_free(struct address_iter* it);
struct nameserver_iter* _netplan_netdef_new_nameserver_iter(NetplanNetDefinition* netdef);
char* _netplan_nameserver_iter_next(struct nameserver_iter* it);
void _netplan_nameserver_iter_free(struct nameserver_iter* it);
struct nameserver_iter* _netplan_netdef_new_search_domain_iter(NetplanNetDefinition* netdef);
char* _netplan_search_domain_iter_next(struct nameserver_iter* it);
void _netplan_search_domain_iter_free(struct nameserver_iter* it);
struct route_iter* _netplan_netdef_new_route_iter(NetplanNetDefinition* netdef);
NetplanIPRoute* _netplan_route_iter_next(struct route_iter* it);
void _netplan_route_iter_free(struct route_iter* it);
// Utils
gboolean netplan_util_dump_yaml_subtree(const char* prefix, int input_fd, int output_fd, NetplanError** error);
gboolean netplan_util_create_yaml_patch(const char* conf_obj_path, const char* obj_payload, int out_fd, NetplanError** error);
// Names (internal)
const char* netplan_backend_name(NetplanBackend val);
const char* netplan_def_type_name(NetplanDefType val);
""")
cffi_inc = os.getenv('CFFI_INC', sys.argv[1])
cffi_lib = os.getenv('CFFI_LIB', sys.argv[2])
# set_source() gives the name of the python extension module to
# produce, and some C source code as a string. This C code needs
# to make the declarated functions, types and globals available,
# so it is often just the "#include".
ffibuilder.set_source_pkgconfig(
"_netplan_cffi", ['glib-2.0'],
"""
#include <glib.h>
// C API of libnetplan.so
#include "netplan.h"
#include "parse.h"
#include "parse-nm.h"
#include "util.h"
// internal headers (private API)
#include "util-internal.h"
#include "names.h"
""",
include_dirs=[cffi_inc],
library_dirs=[cffi_lib],
libraries=['glib-2.0']) # library name, for the linker
if __name__ == "__main__":
ffibuilder.distutils_extension('.')
|