1 /* -*- mode: c; c-file-style: "openbsd" -*- */
3 * Copyright (c) 2015 Vincent Bernat <vincent@bernat.im>
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <arpa/inet.h>
23 #include "../lldpctl.h"
28 static struct atom_map bond_slave_src_mac_map
= {
29 .key
= lldpctl_k_config_bond_slave_src_mac_type
,
31 { LLDP_BOND_SLAVE_SRC_MAC_TYPE_REAL
, "real"},
32 { LLDP_BOND_SLAVE_SRC_MAC_TYPE_ZERO
, "zero"},
33 { LLDP_BOND_SLAVE_SRC_MAC_TYPE_FIXED
, "fixed"},
34 { LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED
, "local" },
35 { LLDP_BOND_SLAVE_SRC_MAC_TYPE_UNKNOWN
, NULL
},
39 static struct atom_map lldp_portid_map
= {
40 .key
= lldpctl_k_config_lldp_portid_type
,
42 { LLDP_PORTID_SUBTYPE_IFNAME
, "ifname"},
43 { LLDP_PORTID_SUBTYPE_LLADDR
, "macaddress"},
44 { LLDP_PORTID_SUBTYPE_LOCAL
, "local"},
45 { LLDP_PORTID_SUBTYPE_UNKNOWN
, NULL
},
49 static struct atom_map lldp_agent_map
= {
50 .key
= lldpctl_k_config_lldp_agent_type
,
52 { LLDP_AGENT_TYPE_NEAREST_BRIDGE
, "nearest bridge"},
53 { LLDP_AGENT_TYPE_NEAREST_NONTPMR_BRIDGE
, "nearest non-TPMR bridge"},
54 { LLDP_AGENT_TYPE_NEAREST_CUSTOMER_BRIDGE
, "nearest customer bridge"},
55 { LLDP_AGENT_TYPE_UNKNOWN
, NULL
},
59 ATOM_MAP_REGISTER(bond_slave_src_mac_map
, 1);
60 ATOM_MAP_REGISTER(lldp_portid_map
, 2);
61 ATOM_MAP_REGISTER(lldp_agent_map
, 3);
64 _lldpctl_atom_new_config(lldpctl_atom_t
*atom
, va_list ap
)
66 struct _lldpctl_atom_config_t
*c
=
67 (struct _lldpctl_atom_config_t
*)atom
;
68 c
->config
= va_arg(ap
, struct lldpd_config
*);
73 _lldpctl_atom_free_config(lldpctl_atom_t
*atom
)
75 struct _lldpctl_atom_config_t
*c
=
76 (struct _lldpctl_atom_config_t
*)atom
;
77 lldpd_config_cleanup(c
->config
);
82 _lldpctl_atom_get_str_config(lldpctl_atom_t
*atom
, lldpctl_key_t key
)
85 struct _lldpctl_atom_config_t
*c
=
86 (struct _lldpctl_atom_config_t
*)atom
;
88 case lldpctl_k_config_mgmt_pattern
:
89 res
= c
->config
->c_mgmt_pattern
; break;
90 case lldpctl_k_config_iface_pattern
:
91 res
= c
->config
->c_iface_pattern
; break;
92 case lldpctl_k_config_cid_pattern
:
93 res
= c
->config
->c_cid_pattern
; break;
94 case lldpctl_k_config_cid_string
:
95 res
= c
->config
->c_cid_string
; break;
96 case lldpctl_k_config_description
:
97 res
= c
->config
->c_description
; break;
98 case lldpctl_k_config_platform
:
99 res
= c
->config
->c_platform
; break;
100 case lldpctl_k_config_hostname
:
101 res
= c
->config
->c_hostname
; break;
102 case lldpctl_k_config_bond_slave_src_mac_type
:
103 return map_lookup(bond_slave_src_mac_map
.map
,
104 c
->config
->c_bond_slave_src_mac_type
);
105 case lldpctl_k_config_lldp_portid_type
:
106 return map_lookup(lldp_portid_map
.map
,
107 c
->config
->c_lldp_portid_type
);
108 case lldpctl_k_config_lldp_agent_type
:
109 return map_lookup(lldp_agent_map
.map
,
110 c
->config
->c_lldp_agent_type
);
112 SET_ERROR(atom
->conn
, LLDPCTL_ERR_NOT_EXIST
);
118 static struct _lldpctl_atom_config_t
*
119 __lldpctl_atom_set_str_config(struct _lldpctl_atom_config_t
*c
,
120 char **local
, char **global
,
124 size_t len
= strlen(value
) + 1;
125 aval
= _lldpctl_alloc_in_atom((lldpctl_atom_t
*)c
, len
);
126 if (!aval
) return NULL
;
127 memcpy(aval
, value
, len
);
129 free(*global
); *global
= strdup(aval
);
132 *local
= *global
= NULL
;
137 static lldpctl_atom_t
*
138 _lldpctl_atom_set_str_config(lldpctl_atom_t
*atom
, lldpctl_key_t key
,
141 struct _lldpctl_atom_config_t
*c
=
142 (struct _lldpctl_atom_config_t
*)atom
;
143 struct lldpd_config config
;
144 memcpy(&config
, c
->config
, sizeof(struct lldpd_config
));
149 case lldpctl_k_config_iface_pattern
:
150 if (!__lldpctl_atom_set_str_config(c
,
151 &config
.c_iface_pattern
, &c
->config
->c_iface_pattern
,
155 case lldpctl_k_config_mgmt_pattern
:
156 if (!__lldpctl_atom_set_str_config(c
,
157 &config
.c_mgmt_pattern
, &c
->config
->c_mgmt_pattern
,
161 case lldpctl_k_config_cid_string
:
162 if (!__lldpctl_atom_set_str_config(c
,
163 &config
.c_cid_string
, &c
->config
->c_cid_string
,
167 case lldpctl_k_config_description
:
168 if (!__lldpctl_atom_set_str_config(c
,
169 &config
.c_description
, &c
->config
->c_description
,
173 case lldpctl_k_config_platform
:
174 if (!__lldpctl_atom_set_str_config(c
,
175 &config
.c_platform
, &c
->config
->c_platform
,
179 case lldpctl_k_config_hostname
:
180 if (!__lldpctl_atom_set_str_config(c
,
181 &config
.c_hostname
, &c
->config
->c_hostname
,
186 SET_ERROR(atom
->conn
, LLDPCTL_ERR_NOT_EXIST
);
190 if (asprintf(&canary
, "%d%s", key
, value
?value
:"(NULL)") == -1) {
191 SET_ERROR(atom
->conn
, LLDPCTL_ERR_NOMEM
);
194 rc
= _lldpctl_do_something(atom
->conn
,
195 CONN_STATE_SET_CONFIG_SEND
, CONN_STATE_SET_CONFIG_RECV
,
197 SET_CONFIG
, &config
, &MARSHAL_INFO(lldpd_config
),
200 if (rc
== 0) return atom
;
208 _lldpctl_atom_get_int_config(lldpctl_atom_t
*atom
, lldpctl_key_t key
)
210 struct _lldpctl_atom_config_t
*c
=
211 (struct _lldpctl_atom_config_t
*)atom
;
213 case lldpctl_k_config_paused
:
214 return c
->config
->c_paused
;
215 case lldpctl_k_config_tx_interval
:
216 return c
->config
->c_tx_interval
;
217 case lldpctl_k_config_receiveonly
:
218 return c
->config
->c_receiveonly
;
219 case lldpctl_k_config_advertise_version
:
220 return c
->config
->c_advertise_version
;
221 case lldpctl_k_config_ifdescr_update
:
222 return c
->config
->c_set_ifdescr
;
223 case lldpctl_k_config_iface_promisc
:
224 return c
->config
->c_promisc
;
225 case lldpctl_k_config_chassis_cap_advertise
:
226 return c
->config
->c_cap_advertise
;
227 case lldpctl_k_config_chassis_mgmt_advertise
:
228 return c
->config
->c_mgmt_advertise
;
229 #ifdef ENABLE_LLDPMED
230 case lldpctl_k_config_lldpmed_noinventory
:
231 return c
->config
->c_noinventory
;
232 case lldpctl_k_config_fast_start_enabled
:
233 return c
->config
->c_enable_fast_start
;
234 case lldpctl_k_config_fast_start_interval
:
235 return c
->config
->c_tx_fast_interval
;
237 case lldpctl_k_config_tx_hold
:
238 return c
->config
->c_tx_hold
;
240 return SET_ERROR(atom
->conn
, LLDPCTL_ERR_NOT_EXIST
);
244 static lldpctl_atom_t
*
245 _lldpctl_atom_set_int_config(lldpctl_atom_t
*atom
, lldpctl_key_t key
,
250 struct _lldpctl_atom_config_t
*c
=
251 (struct _lldpctl_atom_config_t
*)atom
;
252 struct lldpd_config config
;
253 memcpy(&config
, c
->config
, sizeof(struct lldpd_config
));
256 case lldpctl_k_config_paused
:
257 config
.c_paused
= c
->config
->c_paused
= value
;
259 case lldpctl_k_config_tx_interval
:
260 config
.c_tx_interval
= value
;
261 if (value
> 0) c
->config
->c_tx_interval
= value
;
263 case lldpctl_k_config_ifdescr_update
:
264 config
.c_set_ifdescr
= c
->config
->c_set_ifdescr
= value
;
266 case lldpctl_k_config_iface_promisc
:
267 config
.c_promisc
= c
->config
->c_promisc
= value
;
269 case lldpctl_k_config_chassis_cap_advertise
:
270 config
.c_cap_advertise
= c
->config
->c_cap_advertise
= value
;
272 case lldpctl_k_config_chassis_mgmt_advertise
:
273 config
.c_mgmt_advertise
= c
->config
->c_mgmt_advertise
= value
;
275 #ifdef ENABLE_LLDPMED
276 case lldpctl_k_config_fast_start_enabled
:
277 config
.c_enable_fast_start
= c
->config
->c_enable_fast_start
= value
;
279 case lldpctl_k_config_fast_start_interval
:
280 config
.c_tx_fast_interval
= c
->config
->c_tx_fast_interval
= value
;
283 case lldpctl_k_config_tx_hold
:
284 config
.c_tx_hold
= value
;
285 if (value
> 0) c
->config
->c_tx_hold
= value
;
287 case lldpctl_k_config_bond_slave_src_mac_type
:
288 config
.c_bond_slave_src_mac_type
= value
;
289 c
->config
->c_bond_slave_src_mac_type
= value
;
291 case lldpctl_k_config_lldp_portid_type
:
292 config
.c_lldp_portid_type
= value
;
293 c
->config
->c_lldp_portid_type
= value
;
295 case lldpctl_k_config_lldp_agent_type
:
296 config
.c_lldp_agent_type
= value
;
297 c
->config
->c_lldp_agent_type
= value
;
300 SET_ERROR(atom
->conn
, LLDPCTL_ERR_NOT_EXIST
);
304 if (asprintf(&canary
, "%d%ld", key
, value
) == -1) {
305 SET_ERROR(atom
->conn
, LLDPCTL_ERR_NOMEM
);
308 rc
= _lldpctl_do_something(atom
->conn
,
309 CONN_STATE_SET_CONFIG_SEND
, CONN_STATE_SET_CONFIG_RECV
,
311 SET_CONFIG
, &config
, &MARSHAL_INFO(lldpd_config
),
314 if (rc
== 0) return atom
;
318 static struct atom_builder config
=
319 { atom_config
, sizeof(struct _lldpctl_atom_config_t
),
320 .init
= _lldpctl_atom_new_config
,
321 .free
= _lldpctl_atom_free_config
,
322 .get_str
= _lldpctl_atom_get_str_config
,
323 .set_str
= _lldpctl_atom_set_str_config
,
324 .get_int
= _lldpctl_atom_get_int_config
,
325 .set_int
= _lldpctl_atom_set_int_config
};
327 ATOM_BUILDER_REGISTER(config
, 1);