Line data Source code
1 : /*
2 : * Copyright (C) 2021 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 1 : import React, { useState, useContext } from 'react';
7 1 : import cockpit from 'cockpit';
8 : import { Checkbox } from "@patternfly/react-core/dist/esm/components/Checkbox/index.js";
9 : import { FormGroup } from "@patternfly/react-core/dist/esm/components/Form/index.js";
10 : import { TextInput } from "@patternfly/react-core/dist/esm/components/TextInput/index.js";
11 :
12 : import { MemberInterfaceChoices, NetworkModal, Name, dialogSave } from './dialogs-common.jsx';
13 : import { ModelContext } from './model-context.jsx';
14 : import { useDialogs } from "dialogs.jsx";
15 :
16 : import { v4 as uuidv4 } from 'uuid';
17 : import {
18 : member_connection_for_interface,
19 : member_interface_choices,
20 : } from './interfaces.js';
21 :
22 1 : const _ = cockpit.gettext;
23 :
24 0 : export const BridgeDialog = ({ connection, dev, settings }) => {
25 0 : const Dialogs = useDialogs();
26 0 : const idPrefix = "network-bridge-settings";
27 0 : const model = useContext(ModelContext);
28 0 : const memberChoicesInit = {};
29 :
30 0 : member_interface_choices(model, connection).forEach((iface) => {
31 0 : memberChoicesInit[iface.Name] = !!member_connection_for_interface(connection, iface);
32 0 : });
33 :
34 0 : const [dialogError, setDialogError] = useState(undefined);
35 0 : const [iface, setIface] = useState(settings.connection.interface_name);
36 0 : const [stp, setStp] = useState(!!settings.bridge.stp);
37 0 : const [priority, setPriority] = useState(settings.bridge.priority || 10);
38 0 : const [forwardDelay, setForwardDelay] = useState(settings.bridge.forward_delay || 10);
39 0 : const [helloTime, setHelloTime] = useState(settings.bridge.hello_time || 10);
40 0 : const [maxAge, setMaxAge] = useState(settings.bridge.max_age || 10);
41 0 : const [memberChoices, setMemberChoices] = useState(memberChoicesInit);
42 :
43 0 : const onSubmit = (ev) => {
44 0 : const createSettingsObj = () => ({
45 0 : ...settings,
46 0 : connection: {
47 0 : ...settings.connection,
48 0 : id: iface,
49 0 : interface_name: iface,
50 0 : },
51 0 : bridge: {
52 0 : ...settings.bridge,
53 0 : stp,
54 0 : ...(stp && { priority, forward_delay: forwardDelay, hello_time: helloTime, max_age: maxAge }),
55 0 : interface_name: iface,
56 0 : }
57 0 : });
58 :
59 0 : dialogSave({
60 0 : model,
61 0 : dev,
62 0 : connection,
63 0 : members: memberChoices,
64 0 : membersInit: memberChoicesInit,
65 0 : settings: createSettingsObj(),
66 0 : setDialogError,
67 0 : onClose: Dialogs.close,
68 0 : });
69 :
70 : // Prevent dialog from closing because of <form> onsubmit event
71 0 : if (event)
72 0 : event.preventDefault();
73 :
74 0 : return false;
75 0 : };
76 :
77 0 : return (
78 0 : <NetworkModal dialogError={dialogError}
79 0 : idPrefix="network-bridge-settings"
80 0 : onSubmit={onSubmit}
81 0 : title={!connection ? _("Add bridge") : _("Edit bridge settings")}
82 0 : isCreateDialog={!connection}
83 : >
84 0 : <>
85 0 : <Name idPrefix={idPrefix} iface={iface} setIface={setIface} />
86 0 : <FormGroup label={_("Ports")} fieldId={idPrefix + "-interface-members-list"} hasNoPaddingTop>
87 0 : <MemberInterfaceChoices idPrefix={idPrefix} memberChoices={memberChoices} setMemberChoices={setMemberChoices} model={model} group={connection} />
88 0 : </FormGroup>
89 0 : <FormGroup label={_("Options")} fieldId={idPrefix + "-stp-enabled-input"} hasNoPaddingTop>
90 0 : <Checkbox id={idPrefix + "-stp-enabled-input"} isChecked={stp} onChange={(_, s) => setStp(s)} label={_("Spanning tree protocol (STP)")} />
91 0 : {stp && <>
92 0 : <FormGroup fieldId="network-bridge-stp-settings-priority-input" label={_("STP priority")}>
93 0 : <TextInput id="network-bridge-stp-settings-priority-input" className="network-number-field" value={priority} onChange={(_event, value) => setPriority(value)} />
94 0 : </FormGroup>
95 0 : <FormGroup fieldId="network-bridge-stp-settings-forward-delay-input" label={_("STP forward delay")}>
96 0 : <TextInput id="network-bridge-stp-settings-forward-delay-input" className="network-number-field" value={forwardDelay} onChange={(_event, value) => setForwardDelay(value)} />
97 0 : </FormGroup>
98 0 : <FormGroup fieldId="network-bridge-stp-settings-hello-time-input" label={_("STP hello time")}>
99 0 : <TextInput id="network-bridge-stp-settings-hello-time-input" className="network-number-field" value={helloTime} onChange={(_event, value) => setHelloTime(value)} />
100 0 : </FormGroup>
101 0 : <FormGroup fieldId="network-bridge-stp-settings-max-age-input" label={_("STP maximum message age")}>
102 0 : <TextInput id="network-bridge-stp-settings-max-age-input" className="network-number-field" value={maxAge} onChange={(_event, value) => setMaxAge(value)} />
103 0 : </FormGroup>
104 0 : </>}
105 0 : </FormGroup>
106 0 : </>
107 0 : </NetworkModal>
108 : );
109 0 : };
110 :
111 0 : export const getGhostSettings = ({ newIfaceName }) => {
112 0 : return (
113 0 : {
114 0 : connection: {
115 0 : id: newIfaceName,
116 0 : autoconnect: true,
117 0 : type: "bridge",
118 0 : uuid: uuidv4(),
119 0 : interface_name: newIfaceName
120 0 : },
121 0 : bridge: {
122 0 : interface_name: newIfaceName,
123 0 : stp: false,
124 0 : priority: 32768,
125 0 : forward_delay: 15,
126 0 : hello_time: 2,
127 0 : max_age: 20,
128 0 : ageing_time: 300
129 0 : }
130 0 : }
131 : );
132 0 : };
|