libvirt.org/go/libvirtxml@v1.10003.0/nwfilter.go (about) 1 /* 2 * This file is part of the libvirt-go-xml-module project 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 * THE SOFTWARE. 21 * 22 * Copyright (C) 2017 Lian Duan <blazeblue@gmail.com> 23 * 24 */ 25 26 package libvirtxml 27 28 import ( 29 "encoding/xml" 30 "fmt" 31 "io" 32 "strconv" 33 "strings" 34 ) 35 36 type NWFilter struct { 37 XMLName xml.Name `xml:"filter"` 38 Name string `xml:"name,attr"` 39 UUID string `xml:"uuid,omitempty"` 40 Chain string `xml:"chain,attr,omitempty"` 41 Priority int `xml:"priority,attr,omitempty"` 42 Entries []NWFilterEntry 43 } 44 45 type NWFilterEntry struct { 46 Rule *NWFilterRule 47 Ref *NWFilterRef 48 } 49 50 type NWFilterRef struct { 51 Filter string `xml:"filter,attr"` 52 Parameters []NWFilterParameter `xml:"parameter"` 53 } 54 55 type NWFilterParameter struct { 56 Name string `xml:"name,attr"` 57 Value string `xml:"value,attr"` 58 } 59 60 type NWFilterField struct { 61 Var string 62 Str string 63 Uint *uint 64 } 65 66 type NWFilterRule struct { 67 Action string `xml:"action,attr,omitempty"` 68 Direction string `xml:"direction,attr,omitempty"` 69 Priority int `xml:"priority,attr,omitempty"` 70 StateMatch string `xml:"statematch,attr,omitempty"` 71 72 ARP *NWFilterRuleARP `xml:"arp"` 73 RARP *NWFilterRuleRARP `xml:"rarp"` 74 MAC *NWFilterRuleMAC `xml:"mac"` 75 VLAN *NWFilterRuleVLAN `xml:"vlan"` 76 STP *NWFilterRuleSTP `xml:"stp"` 77 IP *NWFilterRuleIP `xml:"ip"` 78 IPv6 *NWFilterRuleIPv6 `xml:"ipv6"` 79 TCP *NWFilterRuleTCP `xml:"tcp"` 80 UDP *NWFilterRuleUDP `xml:"udp"` 81 UDPLite *NWFilterRuleUDPLite `xml:"udplite"` 82 ESP *NWFilterRuleESP `xml:"esp"` 83 AH *NWFilterRuleAH `xml:"ah"` 84 SCTP *NWFilterRuleSCTP `xml:"sctp"` 85 ICMP *NWFilterRuleICMP `xml:"icmp"` 86 All *NWFilterRuleAll `xml:"all"` 87 IGMP *NWFilterRuleIGMP `xml:"igmp"` 88 TCPIPv6 *NWFilterRuleTCPIPv6 `xml:"tcp-ipv6"` 89 UDPIPv6 *NWFilterRuleUDPIPv6 `xml:"udp-ipv6"` 90 UDPLiteIPv6 *NWFilterRuleUDPLiteIPv6 `xml:"udplite-ipv6"` 91 ESPIPv6 *NWFilterRuleESPIPv6 `xml:"esp-ipv6"` 92 AHIPv6 *NWFilterRuleAHIPv6 `xml:"ah-ipv6"` 93 SCTPIPv6 *NWFilterRuleSCTPIPv6 `xml:"sctp-ipv6"` 94 ICMPv6 *NWFilterRuleICMPIPv6 `xml:"icmpv6"` 95 AllIPv6 *NWFilterRuleAllIPv6 `xml:"all-ipv6"` 96 } 97 98 type NWFilterRuleCommonMAC struct { 99 SrcMACAddr NWFilterField `xml:"srcmacaddr,attr,omitempty"` 100 SrcMACMask NWFilterField `xml:"srcmacmask,attr,omitempty"` 101 DstMACAddr NWFilterField `xml:"dstmacaddr,attr,omitempty"` 102 DstMACMask NWFilterField `xml:"dstmacmask,attr,omitempty"` 103 } 104 105 type NWFilterRuleCommonIP struct { 106 SrcMACAddr NWFilterField `xml:"srcmacaddr,attr,omitempty"` 107 SrcIPAddr NWFilterField `xml:"srcipaddr,attr,omitempty"` 108 SrcIPMask NWFilterField `xml:"srcipmask,attr,omitempty"` 109 DstIPAddr NWFilterField `xml:"dstipaddr,attr,omitempty"` 110 DstIPMask NWFilterField `xml:"dstipmask,attr,omitempty"` 111 SrcIPFrom NWFilterField `xml:"srcipfrom,attr,omitempty"` 112 SrcIPTo NWFilterField `xml:"srcipto,attr,omitempty"` 113 DstIPFrom NWFilterField `xml:"dstipfrom,attr,omitempty"` 114 DstIPTo NWFilterField `xml:"dstipto,attr,omitempty"` 115 DSCP NWFilterField `xml:"dscp,attr"` 116 ConnLimitAbove NWFilterField `xml:"connlimit-above,attr"` 117 State NWFilterField `xml:"state,attr,omitempty"` 118 IPSet NWFilterField `xml:"ipset,attr,omitempty"` 119 IPSetFlags NWFilterField `xml:"ipsetflags,attr,omitempty"` 120 } 121 122 type NWFilterRuleCommonPort struct { 123 SrcPortStart NWFilterField `xml:"srcportstart,attr"` 124 SrcPortEnd NWFilterField `xml:"srcportend,attr"` 125 DstPortStart NWFilterField `xml:"dstportstart,attr"` 126 DstPortEnd NWFilterField `xml:"dstportend,attr"` 127 } 128 129 type NWFilterRuleARP struct { 130 Match string `xml:"match,attr,omitempty"` 131 NWFilterRuleCommonMAC 132 HWType NWFilterField `xml:"hwtype,attr"` 133 ProtocolType NWFilterField `xml:"protocoltype,attr"` 134 OpCode NWFilterField `xml:"opcode,attr,omitempty"` 135 ARPSrcMACAddr NWFilterField `xml:"arpsrcmacaddr,attr,omitempty"` 136 ARPDstMACAddr NWFilterField `xml:"arpdstmacaddr,attr,omitempty"` 137 ARPSrcIPAddr NWFilterField `xml:"arpsrcipaddr,attr,omitempty"` 138 ARPSrcIPMask NWFilterField `xml:"arpsrcipmask,attr,omitempty"` 139 ARPDstIPAddr NWFilterField `xml:"arpdstipaddr,attr,omitempty"` 140 ARPDstIPMask NWFilterField `xml:"arpdstipmask,attr,omitempty"` 141 Gratuitous NWFilterField `xml:"gratuitous,attr,omitempty"` 142 Comment string `xml:"comment,attr,omitempty"` 143 } 144 145 type NWFilterRuleRARP struct { 146 Match string `xml:"match,attr,omitempty"` 147 NWFilterRuleCommonMAC 148 HWType NWFilterField `xml:"hwtype,attr"` 149 ProtocolType NWFilterField `xml:"protocoltype,attr"` 150 OpCode NWFilterField `xml:"opcode,attr,omitempty"` 151 ARPSrcMACAddr NWFilterField `xml:"arpsrcmacaddr,attr,omitempty"` 152 ARPDstMACAddr NWFilterField `xml:"arpdstmacaddr,attr,omitempty"` 153 ARPSrcIPAddr NWFilterField `xml:"arpsrcipaddr,attr,omitempty"` 154 ARPSrcIPMask NWFilterField `xml:"arpsrcipmask,attr,omitempty"` 155 ARPDstIPAddr NWFilterField `xml:"arpdstipaddr,attr,omitempty"` 156 ARPDstIPMask NWFilterField `xml:"arpdstipmask,attr,omitempty"` 157 Gratuitous NWFilterField `xml:"gratuitous,attr,omitempty"` 158 Comment string `xml:"comment,attr,omitempty"` 159 } 160 161 type NWFilterRuleMAC struct { 162 Match string `xml:"match,attr,omitempty"` 163 NWFilterRuleCommonMAC 164 ProtocolID NWFilterField `xml:"protocolid,attr,omitempty"` 165 Comment string `xml:"comment,attr,omitempty"` 166 } 167 168 type NWFilterRuleVLAN struct { 169 Match string `xml:"match,attr,omitempty"` 170 NWFilterRuleCommonMAC 171 VLANID NWFilterField `xml:"vlanid,attr,omitempty"` 172 EncapProtocol NWFilterField `xml:"encap-protocol,attr,omitempty"` 173 Comment string `xml:"comment,attr,omitempty"` 174 } 175 176 type NWFilterRuleSTP struct { 177 Match NWFilterField `xml:"match,attr,omitempty"` 178 SrcMACAddr NWFilterField `xml:"srcmacaddr,attr,omitempty"` 179 SrcMACMask NWFilterField `xml:"srcmacmask,attr,omitempty"` 180 Type NWFilterField `xml:"type,attr"` 181 Flags NWFilterField `xml:"flags,attr"` 182 RootPriority NWFilterField `xml:"root-priority,attr"` 183 RootPriorityHi NWFilterField `xml:"root-priority-hi,attr"` 184 RootAddress NWFilterField `xml:"root-address,attr,omitempty"` 185 RootAddressMask NWFilterField `xml:"root-address-mask,attr,omitempty"` 186 RootCost NWFilterField `xml:"root-cost,attr"` 187 RootCostHi NWFilterField `xml:"root-cost-hi,attr"` 188 SenderPriority NWFilterField `xml:"sender-priority,attr"` 189 SenderPriorityHi NWFilterField `xml:"sender-priority-hi,attr"` 190 SenderAddress NWFilterField `xml:"sender-address,attr,omitempty"` 191 SenderAddressMask NWFilterField `xml:"sender-address-mask,attr,omitempty"` 192 Port NWFilterField `xml:"port,attr"` 193 PortHi NWFilterField `xml:"port-hi,attr"` 194 Age NWFilterField `xml:"age,attr"` 195 AgeHi NWFilterField `xml:"age-hi,attr"` 196 MaxAge NWFilterField `xml:"max-age,attr"` 197 MaxAgeHi NWFilterField `xml:"max-age-hi,attr"` 198 HelloTime NWFilterField `xml:"hello-time,attr"` 199 HelloTimeHi NWFilterField `xml:"hello-time-hi,attr"` 200 ForwardDelay NWFilterField `xml:"forward-delay,attr"` 201 ForwardDelayHi NWFilterField `xml:"forward-delay-hi,attr"` 202 Comment string `xml:"comment,attr,omitempty"` 203 } 204 205 type NWFilterRuleIP struct { 206 Match string `xml:"match,attr,omitempty"` 207 NWFilterRuleCommonMAC 208 SrcIPAddr NWFilterField `xml:"srcipaddr,attr,omitempty"` 209 SrcIPMask NWFilterField `xml:"srcipmask,attr,omitempty"` 210 DstIPAddr NWFilterField `xml:"dstipaddr,attr,omitempty"` 211 DstIPMask NWFilterField `xml:"dstipmask,attr,omitempty"` 212 Protocol NWFilterField `xml:"protocol,attr,omitempty"` 213 NWFilterRuleCommonPort 214 DSCP NWFilterField `xml:"dscp,attr"` 215 Comment string `xml:"comment,attr,omitempty"` 216 } 217 218 type NWFilterRuleIPv6 struct { 219 Match string `xml:"match,attr,omitempty"` 220 NWFilterRuleCommonMAC 221 SrcIPAddr NWFilterField `xml:"srcipaddr,attr,omitempty"` 222 SrcIPMask NWFilterField `xml:"srcipmask,attr,omitempty"` 223 DstIPAddr NWFilterField `xml:"dstipaddr,attr,omitempty"` 224 DstIPMask NWFilterField `xml:"dstipmask,attr,omitempty"` 225 Protocol NWFilterField `xml:"protocol,attr,omitempty"` 226 NWFilterRuleCommonPort 227 Type NWFilterField `xml:"type,attr"` 228 TypeEnd NWFilterField `xml:"typeend,attr"` 229 Code NWFilterField `xml:"code,attr"` 230 CodeEnd NWFilterField `xml:"codeend,attr"` 231 Comment string `xml:"comment,attr,omitempty"` 232 } 233 234 type NWFilterRuleTCP struct { 235 Match string `xml:"match,attr,omitempty"` 236 NWFilterRuleCommonIP 237 NWFilterRuleCommonPort 238 Option NWFilterField `xml:"option,attr"` 239 Flags NWFilterField `xml:"flags,attr,omitempty"` 240 Comment string `xml:"comment,attr,omitempty"` 241 } 242 243 type NWFilterRuleUDP struct { 244 Match string `xml:"match,attr,omitempty"` 245 NWFilterRuleCommonIP 246 NWFilterRuleCommonPort 247 Comment string `xml:"comment,attr,omitempty"` 248 } 249 250 type NWFilterRuleUDPLite struct { 251 Match string `xml:"match,attr,omitempty"` 252 NWFilterRuleCommonIP 253 Comment string `xml:"comment,attr,omitempty"` 254 } 255 256 type NWFilterRuleESP struct { 257 Match string `xml:"match,attr,omitempty"` 258 NWFilterRuleCommonIP 259 Comment string `xml:"comment,attr,omitempty"` 260 } 261 262 type NWFilterRuleAH struct { 263 Match string `xml:"match,attr,omitempty"` 264 NWFilterRuleCommonIP 265 Comment string `xml:"comment,attr,omitempty"` 266 } 267 268 type NWFilterRuleSCTP struct { 269 Match string `xml:"match,attr,omitempty"` 270 NWFilterRuleCommonIP 271 NWFilterRuleCommonPort 272 Comment string `xml:"comment,attr,omitempty"` 273 } 274 275 type NWFilterRuleICMP struct { 276 Match string `xml:"match,attr,omitempty"` 277 NWFilterRuleCommonIP 278 Type NWFilterField `xml:"type,attr"` 279 Code NWFilterField `xml:"code,attr"` 280 Comment string `xml:"comment,attr,omitempty"` 281 } 282 283 type NWFilterRuleAll struct { 284 Match string `xml:"match,attr,omitempty"` 285 NWFilterRuleCommonIP 286 Comment string `xml:"comment,attr,omitempty"` 287 } 288 289 type NWFilterRuleIGMP struct { 290 Match string `xml:"match,attr,omitempty"` 291 NWFilterRuleCommonIP 292 Comment string `xml:"comment,attr,omitempty"` 293 } 294 295 type NWFilterRuleTCPIPv6 struct { 296 Match string `xml:"match,attr,omitempty"` 297 NWFilterRuleCommonIP 298 NWFilterRuleCommonPort 299 Option NWFilterField `xml:"option,attr"` 300 Comment string `xml:"comment,attr,omitempty"` 301 } 302 303 type NWFilterRuleUDPIPv6 struct { 304 Match string `xml:"match,attr,omitempty"` 305 NWFilterRuleCommonIP 306 NWFilterRuleCommonPort 307 Comment string `xml:"comment,attr,omitempty"` 308 } 309 310 type NWFilterRuleUDPLiteIPv6 struct { 311 Match string `xml:"match,attr,omitempty"` 312 NWFilterRuleCommonIP 313 Comment string `xml:"comment,attr,omitempty"` 314 } 315 316 type NWFilterRuleESPIPv6 struct { 317 Match string `xml:"match,attr,omitempty"` 318 NWFilterRuleCommonIP 319 Comment string `xml:"comment,attr,omitempty"` 320 } 321 322 type NWFilterRuleAHIPv6 struct { 323 Match string `xml:"match,attr,omitempty"` 324 NWFilterRuleCommonIP 325 Comment string `xml:"comment,attr,omitempty"` 326 } 327 328 type NWFilterRuleSCTPIPv6 struct { 329 Match string `xml:"match,attr,omitempty"` 330 NWFilterRuleCommonIP 331 NWFilterRuleCommonPort 332 Comment string `xml:"comment,attr,omitempty"` 333 } 334 335 type NWFilterRuleICMPIPv6 struct { 336 Match string `xml:"match,attr,omitempty"` 337 NWFilterRuleCommonIP 338 Type NWFilterField `xml:"type,attr"` 339 Code NWFilterField `xml:"code,attr"` 340 Comment string `xml:"comment,attr,omitempty"` 341 } 342 343 type NWFilterRuleAllIPv6 struct { 344 Match string `xml:"match,attr,omitempty"` 345 NWFilterRuleCommonIP 346 Comment string `xml:"comment,attr,omitempty"` 347 } 348 349 func (s *NWFilterField) MarshalXMLAttr(name xml.Name) (xml.Attr, error) { 350 if s == nil { 351 return xml.Attr{}, nil 352 } 353 if s.Str != "" { 354 return xml.Attr{ 355 Name: name, 356 Value: s.Str, 357 }, nil 358 } else if s.Var != "" { 359 return xml.Attr{ 360 Name: name, 361 Value: "$" + s.Str, 362 }, nil 363 } else if s.Uint != nil { 364 return xml.Attr{ 365 Name: name, 366 Value: fmt.Sprintf("0x%x", *s.Uint), 367 }, nil 368 } else { 369 return xml.Attr{}, nil 370 } 371 } 372 373 func (s *NWFilterField) UnmarshalXMLAttr(attr xml.Attr) error { 374 if attr.Value == "" { 375 return nil 376 } 377 if attr.Value[0] == '$' { 378 s.Var = attr.Value[1:] 379 } 380 if strings.HasPrefix(attr.Value, "0x") { 381 val, err := strconv.ParseUint(attr.Value[2:], 16, 64) 382 if err != nil { 383 return err 384 } 385 uval := uint(val) 386 s.Uint = &uval 387 } 388 s.Str = attr.Value 389 return nil 390 } 391 392 func (a *NWFilter) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 393 start.Name.Local = "filter" 394 start.Attr = append(start.Attr, xml.Attr{ 395 Name: xml.Name{Local: "name"}, 396 Value: a.Name, 397 }) 398 if a.Chain != "" { 399 start.Attr = append(start.Attr, xml.Attr{ 400 Name: xml.Name{Local: "chain"}, 401 Value: a.Chain, 402 }) 403 } 404 if a.Priority != 0 { 405 start.Attr = append(start.Attr, xml.Attr{ 406 Name: xml.Name{Local: "priority"}, 407 Value: fmt.Sprintf("%d", a.Priority), 408 }) 409 } 410 err := e.EncodeToken(start) 411 if err != nil { 412 return err 413 } 414 if a.UUID != "" { 415 uuid := xml.StartElement{ 416 Name: xml.Name{Local: "uuid"}, 417 } 418 e.EncodeToken(uuid) 419 e.EncodeToken(xml.CharData(a.UUID)) 420 e.EncodeToken(uuid.End()) 421 } 422 423 for _, entry := range a.Entries { 424 if entry.Rule != nil { 425 rule := xml.StartElement{ 426 Name: xml.Name{Local: "rule"}, 427 } 428 e.EncodeElement(entry.Rule, rule) 429 } else if entry.Ref != nil { 430 ref := xml.StartElement{ 431 Name: xml.Name{Local: "filterref"}, 432 } 433 e.EncodeElement(entry.Ref, ref) 434 } 435 } 436 437 err = e.EncodeToken(start.End()) 438 if err != nil { 439 return err 440 } 441 return nil 442 } 443 444 func (a *NWFilter) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 445 name, ok := getAttr(start.Attr, "name") 446 if !ok { 447 return fmt.Errorf("Missing filter name") 448 } 449 a.Name = name 450 a.Chain, _ = getAttr(start.Attr, "chain") 451 prio, ok := getAttr(start.Attr, "priority") 452 if ok { 453 val, err := strconv.ParseInt(prio, 10, 64) 454 if err != nil { 455 return err 456 } 457 a.Priority = int(val) 458 } 459 460 for { 461 tok, err := d.Token() 462 if err == io.EOF { 463 break 464 } 465 466 switch tok := tok.(type) { 467 case xml.StartElement: 468 { 469 if tok.Name.Local == "uuid" { 470 txt, err := d.Token() 471 if err != nil { 472 return err 473 } 474 475 txt2, ok := txt.(xml.CharData) 476 if !ok { 477 return fmt.Errorf("Expected UUID string") 478 } 479 a.UUID = string(txt2) 480 } else if tok.Name.Local == "rule" { 481 entry := NWFilterEntry{ 482 Rule: &NWFilterRule{}, 483 } 484 485 d.DecodeElement(entry.Rule, &tok) 486 487 a.Entries = append(a.Entries, entry) 488 } else if tok.Name.Local == "filterref" { 489 entry := NWFilterEntry{ 490 Ref: &NWFilterRef{}, 491 } 492 493 d.DecodeElement(entry.Ref, &tok) 494 495 a.Entries = append(a.Entries, entry) 496 } 497 } 498 } 499 500 } 501 return nil 502 } 503 504 func (s *NWFilter) Unmarshal(doc string) error { 505 return xml.Unmarshal([]byte(doc), s) 506 } 507 508 func (s *NWFilter) Marshal() (string, error) { 509 doc, err := xml.MarshalIndent(s, "", " ") 510 if err != nil { 511 return "", err 512 } 513 return string(doc), nil 514 }