Skip to content

Commit f147517

Browse files
authored
CP-312082 Implement APIs for configuration of lldp (#7200)
Design doc: https://github.com/xapi-project/xen-api/blob/master/doc/content/design/lldp.md New fileds: pool.lldp_enabled pool.lldp_multicast_address (RW) pif.lldp_mode APIs: pool.set_lldp_enabled PIF.set_lldp_mode CLI: xe pool-set-lldp-enabled xe pif-set-lldp-mode
2 parents 8c3ad0b + 406a448 commit f147517

19 files changed

Lines changed: 330 additions & 23 deletions

doc/content/design/lldp.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ The following are introduced by this design:
2222
The implementation uses XAPI for configuration, networkd for per-host application of configuration, and [`lldpd`](https://github.com/lldpd/lldpd) as the LLDP agent in dom0 user space.
2323
XAPI stores LLDP configuration in the database and exposes LLDP neighbor data through XenAPI.
2424
networkd configures the LLDP agent to apply LLDP configuration for individual physical NICs and queries the LLDP agent for received LLDP TLVs.
25-
`lldpd` runs as a daemon process in dom0 user space. It receives and sends LLDPDUs via PF_PACKET + SOCK_RAW sockets. It is actively maintained by upstream as the time being.
25+
`lldpd` runs as a daemon process in dom0 user space. It receives and sends LLDPDUs via PF_PACKET + SOCK_RAW sockets. It is actively maintained by upstream for the time being.
2626

2727
## XAPI database changes
2828

@@ -37,7 +37,7 @@ When `false`, LLDP is disabled on the NIC associated with each managed physical
3737

3838
This setting does not apply to other types of PIFs, such as non-managed PIFs, bond PIFs, VLAN PIFs, tunnel PIFs, or SR-IOV PIFs.
3939

40-
`PIF.lldp_mode` determines the final effective state on individul PIF.
40+
`PIF.lldp_mode` determines the final effective state on individual PIF.
4141

4242
LLDP receiving and advertising are always enabled or disabled together.
4343

@@ -51,15 +51,15 @@ Type: `enum pif_lldp_mode`
5151

5252
Values:
5353

54-
- `default`: follow `pool.lldp_enabled`;
54+
- `inherited`: follow `pool.lldp_enabled`;
5555
- `enabled`: LLDP is enabled on the NIC associated with the managed physical PIF;
5656
- `disabled`: LLDP is disabled on the NIC associated with the managed physical PIF.
5757

5858
This setting does not apply to other types of PIFs, such as non-managed PIFs, bond PIFs, VLAN PIFs, tunnel PIFs, or SR-IOV PIFs.
5959

60-
Default after update/RPU from a version/release without LLDP support to a version/release with LLDP support: `default`.
60+
Default after update/RPU from a version/release without LLDP support to a version/release with LLDP support: `inherited`.
6161

62-
Default after fresh install: `default`.
62+
Default after fresh install: `inherited`.
6363

6464
### `pool.lldp_multicast_address`
6565

@@ -72,7 +72,7 @@ Values:
7272
- `nearestcustomerbridge`: `01:80:C2:00:00:00`
7373

7474
This value controls the multicast MAC address used for LLDP transmission.
75-
After a change, it is applied when `pool.set_lldp_enabled` or `PIF.set_lldp_mode` is called with `force=true`.
75+
After a change, it is applied when `pool.set_lldp_enabled` or `PIF.set_lldp_mode` is called (can apply with `force=true` if enabled or mode is not changed).
7676
This value is not considered to change often. Changing it does not trigger any application action for simplicity.
7777

7878
Default after update/RPU from a version/release without LLDP support to a version/release with LLDP support: `nearestbridge`.
@@ -110,7 +110,7 @@ Behavior:
110110
Parameters:
111111

112112
- `self`: the PIF reference;
113-
- `value`: `default`, `enabled`, or `disabled`;
113+
- `value`: `inherited`, `enabled`, or `disabled`;
114114
- `force`: `bool`, default `false`.
115115

116116
Behavior:
@@ -122,7 +122,7 @@ Behavior:
122122
## The networkd database
123123

124124
The `interface_config_t` record in the networkd database is extended with LLDP configuration. networkd can configure LLDP independently using its own database when XAPI is unavailable, for example during host boot.
125-
The default enabled setting is `false` to minimize impact without high-level configuration from XAPI or the user. This database can be updated as XAPI pushes configurtions to networkd through networkd calls.
125+
The default enabled setting is `false` to minimize impact without high-level configuration from XAPI or the user. This database can be updated as XAPI pushes configurations to networkd through networkd calls.
126126

127127
```ocaml
128128
type lldp_multicast_address =
@@ -136,8 +136,8 @@ type lldp = {
136136
; chassis_id: string [@default ""]
137137
; system_name: string [@default ""]
138138
; system_description: string [@default ""]
139-
; enabled: bool [@default false];
140-
; address: lldp_multicast_address list [@default [Nearestbridge]];
139+
; enabled: bool [@default false]
140+
; address: lldp_multicast_address list [@default [Nearestbridge]]
141141
}
142142
[@@deriving rpcty]
143143
@@ -172,9 +172,9 @@ The effective LLDP state on a NIC is determined by `pool.lldp_enabled`, `PIF.lld
172172

173173
| `pool.lldp_enabled` | `PIF.lldp_mode` | parameter passed to networkd | NIC driver in blocking list | effective LLDP state |
174174
| --- | --- | --- | --- | --- |
175-
| `true` | `default` | `true` | `no` | `enabled` |
176-
| `true` | `default` | `true` | `yes` | `disabled` |
177-
| `false` | `default` | `false` | `*` | `disabled` |
175+
| `true` | `inherited` | `true` | `no` | `enabled` |
176+
| `true` | `inherited` | `true` | `yes` | `disabled` |
177+
| `false` | `inherited` | `false` | `*` | `disabled` |
178178
| `*` | `enabled` | `true` | `*` | `enabled` |
179179
| `*` | `disabled` | `false` | `*` | `disabled` |
180180

@@ -212,7 +212,7 @@ type iface_stats = {
212212
lldp_neighbor: lldp_rx option;
213213
}
214214
```
215-
networkd queries `lldpd` for the LLDP TLVs recevied on individual NICs and writes them into `/dev/shm/network_stats`.
215+
networkd queries `lldpd` for the LLDP TLVs received on individual NICs and writes them into `/dev/shm/network_stats`.
216216
Monitor_dbcalls.monitor_dbcall_thread in XAPI reads the in-memory file `/dev/shm/network_stats` periodically, and exposes the data through `PIF_metrics.lldp_neighbor` by storing them in XenAPI map form.
217217

218218
## Scenarios

ocaml/idl/datamodel.ml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,6 +2265,44 @@ module PIF = struct
22652265
~lifecycle:[(Published, rel_tampa, "")]
22662266
~allowed_roles:_R_POOL_OP ()
22672267

2268+
let lldp_mode =
2269+
Enum
2270+
( "pif_lldp_mode"
2271+
, [
2272+
( "inherited"
2273+
, "LLDP is enabled or disabled based on pool.lldp_enabled."
2274+
)
2275+
; ( "enabled"
2276+
, "LLDP is enabled on the NIC of the managed physical PIF, \
2277+
overriding pool.lldp_enabled."
2278+
)
2279+
; ( "disabled"
2280+
, "LLDP is disabled on the NIC of the managed physical PIF, \
2281+
overriding pool.lldp_enabled."
2282+
)
2283+
]
2284+
)
2285+
2286+
let set_lldp_mode =
2287+
call ~name:"set_lldp_mode" ~lifecycle:[]
2288+
~doc:
2289+
"Set the LLDP mode of this PIF, then apply the change by re-plugging \
2290+
the PIF. Only valid for managed physical PIFs."
2291+
~params:
2292+
[
2293+
(Ref _pif, "self", "the PIF object to reconfigure")
2294+
; ( lldp_mode
2295+
, "value"
2296+
, "the LLDP mode to set (inherited, enabled or disabled)"
2297+
)
2298+
; ( Bool
2299+
, "force"
2300+
, "When true, apply the change even if value already matches the \
2301+
current PIF.lldp_mode; otherwise apply only when value differs."
2302+
)
2303+
]
2304+
~allowed_roles:_R_POOL_OP ()
2305+
22682306
let scan =
22692307
call ~name:"scan"
22702308
~doc:
@@ -2608,6 +2646,7 @@ module PIF = struct
26082646
; db_introduce
26092647
; db_forget
26102648
; set_property
2649+
; set_lldp_mode
26112650
]
26122651
~contents:
26132652
[
@@ -2891,6 +2930,11 @@ module PIF = struct
28912930
~lifecycle:[(Published, rel_kolkata, "")]
28922931
~default_value:(Some (VRef null_ref)) "PCI"
28932932
"Link to underlying PCI device"
2933+
; field ~qualifier:DynamicRO ~ty:lldp_mode ~lifecycle:[]
2934+
~default_value:(Some (VEnum "inherited")) "lldp_mode"
2935+
"The LLDP mode of the physical NIC for the PIF. This setting does \
2936+
not apply to other types of PIFs, such as non-managed PIFs, bond \
2937+
PIFs, VLAN PIFs, tunnel PIFs, or SR-IOV PIFs."
28942938
]
28952939
()
28962940
end

ocaml/idl/datamodel_pool.ml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,29 @@ let set_igmp_snooping_enabled =
11901190
~doc:"Enable or disable IGMP Snooping on the pool."
11911191
~allowed_roles:_R_POOL_OP ()
11921192

1193+
let set_lldp_enabled =
1194+
call ~name:"set_lldp_enabled" ~lifecycle:[]
1195+
~doc:
1196+
"Enable or disable LLDP on the NIC of every managed physical PIF in the \
1197+
pool, then apply the change by re-plugging the affected PIFs."
1198+
~params:
1199+
[
1200+
(Ref _pool, "self", "The pool")
1201+
; (Bool, "value", "true to enable LLDP, false to disable it")
1202+
; ( Bool
1203+
, "force"
1204+
, "When true, apply the change to all managed physical PIFs even if \
1205+
value already matches pool.lldp_enabled; otherwise apply only when \
1206+
value differs from pool.lldp_enabled."
1207+
)
1208+
]
1209+
~result:
1210+
( Map (Ref _pif, String)
1211+
, "A map of the PIFs that failed to be reconfigured and the \
1212+
corresponding error message."
1213+
)
1214+
~allowed_roles:_R_POOL_OP ()
1215+
11931216
let has_extension =
11941217
call ~name:"has_extension"
11951218
~lifecycle:
@@ -1782,6 +1805,24 @@ let exchange_crls_on_join =
17821805
~allowed_roles:(_R_POOL_OP ++ _R_CLIENT_CERT)
17831806
~hide_from_docs:true ~lifecycle:[] ()
17841807

1808+
let lldp_multicast_address =
1809+
Enum
1810+
( "lldp_multicast_address"
1811+
, [
1812+
( "nearestbridge"
1813+
, "Nearest bridge group address (MAC 01:80:C2:00:00:0E). LLDP frames \
1814+
reach only the immediate neighbor on the physical link."
1815+
)
1816+
; ( "nearestnontpmrbridge"
1817+
, "Nearest non-TPMR (Two-Port MAC Relay) bridge group address (MAC \
1818+
01:80:C2:00:00:03)."
1819+
)
1820+
; ( "nearestcustomerbridge"
1821+
, "Nearest customer bridge group address (MAC 01:80:C2:00:00:00)."
1822+
)
1823+
]
1824+
)
1825+
17851826
(** A pool class *)
17861827
let t =
17871828
create_obj ~in_db:true
@@ -1851,6 +1892,7 @@ let t =
18511892
; enable_ssl_legacy
18521893
; disable_ssl_legacy
18531894
; set_igmp_snooping_enabled
1895+
; set_lldp_enabled
18541896
; has_extension
18551897
; add_to_guest_agent_config
18561898
; remove_from_guest_agent_config
@@ -2442,6 +2484,19 @@ let t =
24422484
/import_metadata calls and disaster recovery (VM.recover and \
24432485
VM_appliance.recover); it does not apply to VM.clone or VM.copy, \
24442486
which inherit the source VM's state."
2487+
; field ~qualifier:DynamicRO ~lifecycle:[] ~ty:Bool
2488+
~default_value:(Some (VBool false)) "lldp_enabled"
2489+
"When true, LLDP is enabled on the NIC associated with each \
2490+
managed physical PIF on every host in the pool. When false, it is \
2491+
disabled. However, it can be overridden by PIF.lldp_mode settings \
2492+
when mode is not inherited. LLDP receiving and advertising are \
2493+
always enabled or disabled together."
2494+
; field ~writer_roles:_R_POOL_OP ~qualifier:RW ~lifecycle:[]
2495+
~ty:lldp_multicast_address
2496+
~default_value:(Some (VEnum "nearestbridge"))
2497+
"lldp_multicast_address"
2498+
"The multicast MAC address used for LLDP advertising. To apply a \
2499+
change, use pool.set_lldp_enabled(with force=true)."
24452500
]
24462501
)
24472502
()

ocaml/idl/schematest.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ let hash x = Digest.string x |> Digest.to_hex
33
(* BEWARE: if this changes, check that schema has been bumped accordingly in
44
ocaml/idl/datamodel_common.ml, usually schema_minor_vsn *)
55

6-
let last_known_schema_hash = "b88f7174944ef37e6f2c53b5232465e9"
6+
let last_known_schema_hash = "e5bb3f3b53e89a81d7a7fcee7ead9efe"
77

88
let current_schema_hash : string =
99
let open Datamodel_types in

ocaml/tests/common/test_common.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,8 @@ let make_pool ~__context ~master ?(name_label = "") ?(name_description = "")
338338
~ext_auth_cache_expiry:300L ~update_sync_frequency ~update_sync_day
339339
~update_sync_enabled ~recommendations ~license_server
340340
~ha_reboot_vm_on_internal_shutdown ~limit_console_sessions
341-
~vm_console_idle_timeout ~auto_update_vm_secureboot_certificates ;
341+
~vm_console_idle_timeout ~auto_update_vm_secureboot_certificates
342+
~lldp_enabled:false ~lldp_multicast_address:`nearestbridge ;
342343
pool_ref
343344

344345
let default_sm_features =

ocaml/xapi-cli-server/cli_frontend.ml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,16 @@ let rec cmdtable_data : (string * cmd_spec) list =
498498
; flags= []
499499
}
500500
)
501+
; ( "pool-set-lldp-enabled"
502+
, {
503+
reqd= ["value"]
504+
; optn= ["uuid"; "force"]
505+
; help=
506+
"Enable or disable LLDP on every managed physical PIF in the pool."
507+
; implementation= No_fd Cli_operations.pool_set_lldp_enabled
508+
; flags= []
509+
}
510+
)
501511
; ( "pool-set-vswitch-controller"
502512
, {
503513
reqd= ["address"]
@@ -2123,6 +2133,17 @@ let rec cmdtable_data : (string * cmd_spec) list =
21232133
; flags= []
21242134
}
21252135
)
2136+
; ( "pif-set-lldp-mode"
2137+
, {
2138+
reqd= ["uuid"; "value"]
2139+
; optn= ["force"]
2140+
; help=
2141+
"Set the LLDP mode (inherited, enabled or disabled) of a managed \
2142+
physical PIF."
2143+
; implementation= No_fd Cli_operations.pif_set_lldp_mode
2144+
; flags= []
2145+
}
2146+
)
21262147
; ( "pif-scan"
21272148
, {
21282149
reqd= ["host-uuid"]

ocaml/xapi-cli-server/cli_operations.ml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,6 +1945,20 @@ let pool_disable_client_certificate_auth _printer rpc session_id params =
19451945
let pool = get_pool_with_default rpc session_id params "uuid" in
19461946
Client.Pool.disable_client_certificate_auth ~rpc ~session_id ~self:pool
19471947

1948+
let pool_set_lldp_enabled printer rpc session_id params =
1949+
let pool = get_pool_with_default rpc session_id params "uuid" in
1950+
let value = bool_of_string "value" (List.assoc "value" params) in
1951+
let force = get_bool_param params "force" in
1952+
let failures =
1953+
Client.Pool.set_lldp_enabled ~rpc ~session_id ~self:pool ~value ~force
1954+
in
1955+
let table =
1956+
List.map
1957+
(fun (pif, msg) -> (Client.PIF.get_uuid ~rpc ~session_id ~self:pif, msg))
1958+
failures
1959+
in
1960+
printer (Cli_printer.PTable [table])
1961+
19481962
let pool_sync_updates printer rpc session_id params =
19491963
let pool = get_pool_with_default rpc session_id params "uuid" in
19501964
let force = get_bool_param params "force" in
@@ -6711,6 +6725,14 @@ let pif_set_primary_address_type _printer rpc session_id params =
67116725
in
67126726
()
67136727

6728+
let pif_set_lldp_mode _printer rpc session_id params =
6729+
let pif =
6730+
Client.PIF.get_by_uuid ~rpc ~session_id ~uuid:(List.assoc "uuid" params)
6731+
in
6732+
let value = Record_util.pif_lldp_mode_of_string (List.assoc "value" params) in
6733+
let force = get_bool_param params "force" in
6734+
Client.PIF.set_lldp_mode ~rpc ~session_id ~self:pif ~value ~force
6735+
67146736
let pif_unplug _printer rpc session_id params =
67156737
let pif =
67166738
Client.PIF.get_by_uuid ~rpc ~session_id ~uuid:(List.assoc "uuid" params)

ocaml/xapi-cli-server/records.ml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,11 @@ let pif_record rpc session_id pif =
736736
(x ()).API.pIF_igmp_snooping_status
737737
)
738738
()
739+
; make_field ~name:"lldp-mode"
740+
~get:(fun () ->
741+
Record_util.pif_lldp_mode_to_string (x ()).API.pIF_lldp_mode
742+
)
743+
()
739744
]
740745
}
741746

@@ -1337,6 +1342,19 @@ let pool_record rpc session_id pool =
13371342
~value:(bool_of_string x)
13381343
)
13391344
()
1345+
; make_field ~name:"lldp-enabled"
1346+
~get:(fun () -> string_of_bool (x ()).API.pool_lldp_enabled)
1347+
()
1348+
; make_field ~name:"lldp-multicast-address"
1349+
~get:(fun () ->
1350+
Record_util.lldp_multicast_address_to_string
1351+
(x ()).API.pool_lldp_multicast_address
1352+
)
1353+
~set:(fun v ->
1354+
Client.Pool.set_lldp_multicast_address ~rpc ~session_id ~self:pool
1355+
~value:(Record_util.lldp_multicast_address_of_string v)
1356+
)
1357+
()
13401358
; make_field ~name:"gui-config"
13411359
~get:(fun () -> get_from_map (x ()).API.pool_gui_config)
13421360
~add_to_map:(fun key value ->

ocaml/xapi/dbsync_master.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ let create_pool_record ~__context =
5555
~ext_auth_cache_size:50L ~ext_auth_cache_expiry:300L ~recommendations:[]
5656
~license_server:[] ~ha_reboot_vm_on_internal_shutdown:true
5757
~limit_console_sessions:false ~vm_console_idle_timeout:0L
58-
~auto_update_vm_secureboot_certificates:false
58+
~auto_update_vm_secureboot_certificates:false ~lldp_enabled:true
59+
~lldp_multicast_address:`nearestbridge
5960

6061
let set_master_ip ~__context =
6162
let ip =

0 commit comments

Comments
 (0)