Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> --- domain.go | 1 + network.go | 1 + network_port.go | 200 ++++++++++++++++++++++++++++++++++++++++++++++++ xml_test.go | 3 + 4 files changed, 205 insertions(+) create mode 100644 network_port.go diff --git a/domain.go b/domain.go index 0757048..a7cbdcf 100644 --- a/domain.go +++ b/domain.go @@ -440,6 +440,7 @@ type DomainInterfaceSourceNetwork struct { Network string `xml:"network,attr,omitempty"` PortGroup string `xml:"portgroup,attr,omitempty"` Bridge string `xml:"bridge,attr,omitempty"` + PortID string `xml:"portid,attr,omitempty"` } type DomainInterfaceSourceBridge struct { diff --git a/network.go b/network.go index d4faf46..61c1af0 100644 --- a/network.go +++ b/network.go @@ -282,6 +282,7 @@ type NetworkBandwidthParams struct { } type NetworkBandwidth struct { + ClassID uint `xml:"classID,attr,omitempty"` Inbound *NetworkBandwidthParams `xml:"inbound"` Outbound *NetworkBandwidthParams `xml:"outbound"` } diff --git a/network_port.go b/network_port.go new file mode 100644 index 0000000..3cbc7fb --- /dev/null +++ b/network_port.go @@ -0,0 +1,200 @@ +/* + * This file is part of the libvirt-go-xml project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (C) 2019 Red Hat, Inc. + * + */ + +package libvirtxml + +import ( + "encoding/xml" + "fmt" +) + +type NetworkPort struct { + XMLName xml.Name `xml:"networkport"` + UUID string `xml:"uuid,omitempty"` + Owner *NetworkPortOwner `xml:"owner",` + MAC *NetworkPortMAC `xml:"mac"` + Group string `xml:"group,omitempty"` + Bandwidth *NetworkBandwidth `xml:"bandwidth"` + VirtualPort *NetworkVirtualPort `xml:"virtualport"` + RXFilters *NetworkPortRXFilters `xml:"rxfilters"` + Plug *NetworkPortPlug `xml:"plug"` +} + +type NetworkPortOwner struct { + UUID string `xml:"uuid,omitempty"` + Name string `xml:"name,omitempty"` +} + +type NetworkPortMAC struct { + Address string `xml:"address,attr"` +} + +type NetworkPortRXFilters struct { + TrustGuest string `xml:"trustGuest,attr"` +} + +type NetworkPortPlug struct { + Bridge *NetworkPortPlugBridge `xml:"-"` + Network *NetworkPortPlugNetwork `xml:"-"` + Direct *NetworkPortPlugDirect `xml:"-"` + HostDevPCI *NetworkPortPlugHostDevPCI `xml:"-"` +} + +type NetworkPortPlugBridge struct { + Bridge string `xml:"bridge,attr"` + MacTableManager string `xml:"macTableManager,attr,omitempty"` +} + +type NetworkPortPlugNetwork struct { + Bridge string `xml:"bridge,attr"` + MacTableManager string `xml:"macTableManager,attr,omitempty"` +} + +type NetworkPortPlugDirect struct { + Dev string `xml:"dev,attr"` + Mode string `xml:"mode,attr"` +} + +type NetworkPortPlugHostDevPCI struct { + Managed string `xml:"managed,attr,omitempty"` + Driver *NetworkPortPlugHostDevPCIDriver `xml:"driver"` + Address *NetworkPortPlugHostDevPCIAddress `xml:"address"` +} + +type NetworkPortPlugHostDevPCIDriver struct { + Name string `xml:"name,attr"` +} + +type NetworkPortPlugHostDevPCIAddress struct { + Domain *uint `xml:"domain,attr"` + Bus *uint `xml:"bus,attr"` + Slot *uint `xml:"slot,attr"` + Function *uint `xml:"function,attr"` +} + +func (a *NetworkPortPlugHostDevPCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + marshalUintAttr(&start, "domain", a.Domain, "0x%04x") + marshalUintAttr(&start, "bus", a.Bus, "0x%02x") + marshalUintAttr(&start, "slot", a.Slot, "0x%02x") + marshalUintAttr(&start, "function", a.Function, "0x%x") + e.EncodeToken(start) + e.EncodeToken(start.End()) + return nil +} + +func (a *NetworkPortPlugHostDevPCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + for _, attr := range start.Attr { + if attr.Name.Local == "domain" { + if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil { + return err + } + } else if attr.Name.Local == "bus" { + if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil { + return err + } + } else if attr.Name.Local == "slot" { + if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil { + return err + } + } else if attr.Name.Local == "function" { + if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil { + return err + } + } + } + d.Skip() + return nil +} + +func (p *NetworkPortPlug) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + start.Name.Local = "plug" + if p.Bridge != nil { + start.Attr = append(start.Attr, xml.Attr{ + xml.Name{Local: "type"}, "bridge", + }) + return e.EncodeElement(p.Bridge, start) + } else if p.Network != nil { + start.Attr = append(start.Attr, xml.Attr{ + xml.Name{Local: "type"}, "network", + }) + return e.EncodeElement(p.Network, start) + } else if p.Direct != nil { + start.Attr = append(start.Attr, xml.Attr{ + xml.Name{Local: "type"}, "direct", + }) + return e.EncodeElement(p.Direct, start) + } else if p.HostDevPCI != nil { + start.Attr = append(start.Attr, xml.Attr{ + xml.Name{Local: "type"}, "hostdev-pci", + }) + return e.EncodeElement(p.HostDevPCI, start) + } + return nil +} + +func (p *NetworkPortPlug) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + typ, ok := getAttr(start.Attr, "type") + if !ok { + return fmt.Errorf("Missing type attribute on plug") + } else if typ == "bridge" { + var pb NetworkPortPlugBridge + if err := d.DecodeElement(&pb, &start); err != nil { + return err + } + p.Bridge = &pb + } else if typ == "network" { + var pn NetworkPortPlugNetwork + if err := d.DecodeElement(&pn, &start); err != nil { + return err + } + p.Network = &pn + } else if typ == "direct" { + var pd NetworkPortPlugDirect + if err := d.DecodeElement(&pd, &start); err != nil { + return err + } + p.Direct = &pd + } else if typ == "hostdev-pci" { + var ph NetworkPortPlugHostDevPCI + if err := d.DecodeElement(&ph, &start); err != nil { + return err + } + p.HostDevPCI = &ph + } + d.Skip() + return nil +} + +func (s *NetworkPort) Unmarshal(doc string) error { + return xml.Unmarshal([]byte(doc), s) +} + +func (s *NetworkPort) Marshal() (string, error) { + doc, err := xml.MarshalIndent(s, "", " ") + if err != nil { + return "", err + } + return string(doc), nil +} diff --git a/xml_test.go b/xml_test.go index 320c248..7e3876a 100644 --- a/xml_test.go +++ b/xml_test.go @@ -83,6 +83,7 @@ var xmldirs = []string{ "testdata/libvirt/tests/storagevolxml2xmlin", "testdata/libvirt/tests/storagevolxml2xmlout", "testdata/libvirt/tests/vircaps2xmldata", + "testdata/libvirt/tests/virnetworkportxml2xmldata", "testdata/libvirt/tests/virstorageutildata", "testdata/libvirt/tests/vmx2xmldata", "testdata/libvirt/tests/xlconfigdata", @@ -306,6 +307,8 @@ func testRoundTrip(t *testing.T, xml string, filename string) { doc = &Domain{} } else if strings.HasPrefix(xml, "<capabilities") { doc = &Caps{} + } else if strings.HasPrefix(xml, "<networkport") { + doc = &NetworkPort{} } else if strings.HasPrefix(xml, "<network") { doc = &Network{} } else if strings.HasPrefix(xml, "<secret") { -- 2.21.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list