go.ligato.io/vpp-agent/v3@v3.5.0/plugins/configurator/dump.go (about) 1 // Copyright (c) 2019 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package configurator 16 17 import ( 18 "context" 19 "errors" 20 "sync" 21 22 "go.ligato.io/cn-infra/v2/logging" 23 24 iflinuxcalls "go.ligato.io/vpp-agent/v3/plugins/linux/ifplugin/linuxcalls" 25 l3linuxcalls "go.ligato.io/vpp-agent/v3/plugins/linux/l3plugin/linuxcalls" 26 abfvppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/abfplugin/vppcalls" 27 aclvppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/aclplugin/vppcalls" 28 ifvppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls" 29 ipsecvppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/vppcalls" 30 l2vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/l2plugin/vppcalls" 31 l3vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls" 32 natvppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/natplugin/vppcalls" 33 "go.ligato.io/vpp-agent/v3/plugins/vpp/puntplugin/vppcalls" 34 wireguardvppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/wireguardplugin/vppcalls" 35 rpc "go.ligato.io/vpp-agent/v3/proto/ligato/configurator" 36 linux_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces" 37 linux_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/linux/l3" 38 vpp_abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf" 39 vpp_acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" 40 vpp_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 41 vpp_ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" 42 vpp_l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2" 43 vpp_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" 44 vpp_nat "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/nat" 45 vpp_punt "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/punt" 46 vpp_wg "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/wireguard" 47 ) 48 49 type dumpService struct { 50 log logging.Logger 51 52 mux sync.Mutex 53 54 // VPP Handlers 55 ifHandler ifvppcalls.InterfaceVppRead 56 l2Handler l2vppcalls.L2VppAPI 57 l3Handler l3vppcalls.L3VppAPI 58 ipsecHandler ipsecvppcalls.IPSecVPPRead 59 // plugins 60 aclHandler aclvppcalls.ACLVppRead 61 abfHandler abfvppcalls.ABFVppRead 62 natHandler natvppcalls.NatVppRead 63 puntHandler vppcalls.PuntVPPRead 64 wireguardHandler wireguardvppcalls.WgVppRead 65 66 // Linux handlers 67 linuxIfHandler iflinuxcalls.NetlinkAPIRead 68 linuxL3Handler l3linuxcalls.NetlinkAPIRead 69 } 70 71 // Dump implements Dump method for Configurator 72 func (svc *dumpService) Dump(ctx context.Context, req *rpc.DumpRequest) (*rpc.DumpResponse, error) { 73 defer trackOperation("Dump")() 74 75 svc.mux.Lock() 76 defer svc.mux.Unlock() 77 78 svc.log.Debugf("Received Dump request..") 79 80 dump := newConfig() 81 82 var err error 83 84 // ----- 85 // VPP 86 // ----- 87 dump.VppConfig.Interfaces, err = svc.DumpInterfaces(ctx) 88 if err != nil { 89 svc.log.Errorf("DumpInterfaces failed: %v", err) 90 return nil, err 91 } 92 dump.VppConfig.BridgeDomains, err = svc.DumpBDs() 93 if err != nil { 94 svc.log.Errorf("DumpBDs failed: %v", err) 95 return nil, err 96 } 97 dump.VppConfig.Fibs, err = svc.DumpFIBs() 98 if err != nil { 99 svc.log.Errorf("DumpFIBs failed: %v", err) 100 return nil, err 101 } 102 dump.VppConfig.XconnectPairs, err = svc.DumpXConnects() 103 if err != nil { 104 svc.log.Errorf("DumpXConnects failed: %v", err) 105 return nil, err 106 } 107 dump.VppConfig.Routes, err = svc.DumpRoutes() 108 if err != nil { 109 svc.log.Errorf("DumpRoutes failed: %v", err) 110 return nil, err 111 } 112 dump.VppConfig.Arps, err = svc.DumpARPs() 113 if err != nil { 114 svc.log.Errorf("DumpARPs failed: %v", err) 115 return nil, err 116 } 117 dump.VppConfig.IpsecSpds, err = svc.DumpIPSecSPDs() 118 if err != nil { 119 svc.log.Errorf("DumpIPSecSPDs failed: %v", err) 120 return nil, err 121 } 122 dump.VppConfig.IpsecSps, err = svc.DumpIPSecSPs() 123 if err != nil { 124 svc.log.Errorf("DumpIPSecSPs failed: %v", err) 125 return nil, err 126 } 127 dump.VppConfig.IpsecSas, err = svc.DumpIPSecSAs() 128 if err != nil { 129 svc.log.Errorf("DumpIPSecSAs failed: %v", err) 130 return nil, err 131 } 132 dump.VppConfig.Acls, err = svc.DumpACLs() 133 if err != nil { 134 svc.log.Errorf("DumpACLs failed: %v", err) 135 return nil, err 136 } 137 dump.VppConfig.Abfs, err = svc.DumpABFs() 138 if err != nil { 139 svc.log.Errorf("DumpABFs failed: %v", err) 140 return nil, err 141 } 142 dump.VppConfig.Nat44Global, err = svc.DumpNAT44Global() 143 if err != nil { 144 svc.log.Errorf("DumpNAT44Global failed: %v", err) 145 return nil, err 146 } 147 dump.VppConfig.Dnat44S, err = svc.DumpDNAT44s() 148 if err != nil { 149 svc.log.Errorf("DumpDNAT44s failed: %v", err) 150 return nil, err 151 } 152 dump.VppConfig.Nat44Interfaces, err = svc.DumpNAT44Interfaces() 153 if err != nil { 154 svc.log.Errorf("DumpNAT44Interfaces failed: %v", err) 155 return nil, err 156 } 157 dump.VppConfig.Nat44Pools, err = svc.DumpNAT44AddressPools() 158 if err != nil { 159 svc.log.Errorf("DumpNAT44AddressPools failed: %v", err) 160 return nil, err 161 } 162 dump.VppConfig.PuntTohosts, err = svc.DumpPunt() 163 if err != nil { 164 svc.log.Errorf("DumpPunt failed: %v", err) 165 return nil, err 166 } 167 dump.VppConfig.PuntExceptions, err = svc.DumpPuntExceptions() 168 if err != nil { 169 svc.log.Errorf("DumpPuntExceptions failed: %v", err) 170 return nil, err 171 } 172 dump.VppConfig.WgPeers, err = svc.DumpWgPeers() 173 if err != nil { 174 svc.log.Errorf("DumpWgPeers failed: %v", err) 175 return nil, err 176 } 177 178 // ----- 179 // Linux 180 // ----- 181 dump.LinuxConfig.Interfaces, err = svc.DumpLinuxInterfaces() 182 if err != nil { 183 svc.log.Errorf("DumpLinuxInterfaces failed: %v", err) 184 return nil, err 185 } 186 187 dump.LinuxConfig.ArpEntries, err = svc.DumpLinuxARPs() 188 if err != nil { 189 svc.log.Errorf("DumpLinuxARPs failed: %v", err) 190 return nil, err 191 } 192 193 dump.LinuxConfig.Routes, err = svc.DumpLinuxRoutes() 194 if err != nil { 195 svc.log.Errorf("DumpLinuxRoutes failed: %v", err) 196 return nil, err 197 } 198 199 return &rpc.DumpResponse{Dump: dump}, nil 200 } 201 202 // DumpInterfaces reads interfaces and returns them as an *InterfaceResponse. If reading ends up with error, 203 // only error is send back in response 204 func (svc *dumpService) DumpInterfaces(ctx context.Context) (ifs []*vpp_interfaces.Interface, err error) { 205 if svc.ifHandler == nil { 206 // handler is not available 207 return nil, nil 208 } 209 210 ifDetails, err := svc.ifHandler.DumpInterfaces(ctx) 211 if err != nil { 212 return nil, err 213 } 214 for _, iface := range ifDetails { 215 ifs = append(ifs, iface.Interface) 216 } 217 return ifs, nil 218 } 219 220 // DumpIPSecSPDs reads IPSec SPD and returns them as an *IPSecSPDResponse. If reading ends up with error, 221 // only error is send back in response 222 func (svc *dumpService) DumpIPSecSPDs() (spds []*vpp_ipsec.SecurityPolicyDatabase, err error) { 223 if svc.ipsecHandler == nil { 224 // handler is not available 225 return nil, nil 226 } 227 228 return svc.ipsecHandler.DumpIPSecSPD() 229 } 230 231 // DumpIPSecSPs dumps IPSec security policies. 232 func (svc *dumpService) DumpIPSecSPs() (spds []*vpp_ipsec.SecurityPolicy, err error) { 233 if svc.ipsecHandler == nil { 234 // handler is not available 235 return nil, nil 236 } 237 238 return svc.ipsecHandler.DumpIPSecSP() 239 } 240 241 // DumpIPSecSAs reads IPSec SA and returns them as an *IPSecSAResponse. If reading ends up with error, 242 // only error is send back in response 243 func (svc *dumpService) DumpIPSecSAs() (sas []*vpp_ipsec.SecurityAssociation, err error) { 244 if svc.ipsecHandler == nil { 245 // handler is not available 246 return nil, nil 247 } 248 249 saDetails, err := svc.ipsecHandler.DumpIPSecSA() 250 if err != nil { 251 return nil, err 252 } 253 for _, sa := range saDetails { 254 sas = append(sas, sa.Sa) 255 } 256 return sas, nil 257 } 258 259 // DumpBDs reads bridge domains and returns them as an *BDResponse. If reading ends up with error, 260 // only error is send back in response 261 func (svc *dumpService) DumpBDs() (bds []*vpp_l2.BridgeDomain, err error) { 262 if svc.l2Handler == nil { 263 // handler is not available 264 return nil, nil 265 } 266 267 bdDetails, err := svc.l2Handler.DumpBridgeDomains() 268 if err != nil { 269 return nil, err 270 } 271 for _, bd := range bdDetails { 272 bds = append(bds, bd.Bd) 273 } 274 return bds, nil 275 } 276 277 // DumpFIBs reads FIBs and returns them as an *FibResponse. If reading ends up with error, 278 // only error is send back in response 279 func (svc *dumpService) DumpFIBs() (fibs []*vpp_l2.FIBEntry, err error) { 280 if svc.l2Handler == nil { 281 // handler is not available 282 return nil, nil 283 } 284 285 fibDetails, err := svc.l2Handler.DumpL2FIBs() 286 if err != nil { 287 return nil, err 288 } 289 for _, fib := range fibDetails { 290 fibs = append(fibs, fib.Fib) 291 } 292 return fibs, nil 293 } 294 295 // DumpXConnects reads cross connects and returns them as an *XcResponse. If reading ends up with error, 296 // only error is send back in response 297 func (svc *dumpService) DumpXConnects() (xcs []*vpp_l2.XConnectPair, err error) { 298 if svc.l2Handler == nil { 299 // handler is not available 300 return nil, nil 301 } 302 303 xcDetails, err := svc.l2Handler.DumpXConnectPairs() 304 if err != nil { 305 return nil, err 306 } 307 for _, xc := range xcDetails { 308 xcs = append(xcs, xc.Xc) 309 } 310 return xcs, nil 311 } 312 313 // DumpRoutes reads VPP routes and returns them as an *RoutesResponse. If reading ends up with error, 314 // only error is send back in response 315 func (svc *dumpService) DumpRoutes() (routes []*vpp_l3.Route, err error) { 316 if svc.l3Handler == nil { 317 // handler is not available 318 return nil, nil 319 } 320 321 rtDetails, err := svc.l3Handler.DumpRoutes() 322 if err != nil { 323 return nil, err 324 } 325 for _, rt := range rtDetails { 326 routes = append(routes, rt.Route) 327 } 328 return routes, nil 329 } 330 331 // DumpARPs reads VPP ARPs and returns them as an *ARPsResponse. If reading ends up with error, 332 // only error is send back in response 333 func (svc *dumpService) DumpARPs() (arps []*vpp_l3.ARPEntry, err error) { 334 if svc.l3Handler == nil { 335 // handler is not available 336 return nil, nil 337 } 338 339 arpDetails, err := svc.l3Handler.DumpArpEntries() 340 if err != nil { 341 return nil, err 342 } 343 for _, arp := range arpDetails { 344 arps = append(arps, arp.Arp) 345 } 346 return arps, nil 347 } 348 349 // DumpACLs reads IP/MACIP access lists and returns them as an *AclResponse. If reading ends up with error, 350 // only error is send back in response 351 func (svc *dumpService) DumpACLs() (acls []*vpp_acl.ACL, err error) { 352 if svc.aclHandler == nil { 353 // handler is not available 354 return nil, nil 355 } 356 357 ipACLs, err := svc.aclHandler.DumpACL() 358 if err != nil { 359 return nil, err 360 } 361 macIPACLs, err := svc.aclHandler.DumpMACIPACL() 362 if err != nil { 363 return nil, err 364 } 365 for _, aclDetails := range ipACLs { 366 acls = append(acls, aclDetails.ACL) 367 } 368 for _, aclDetails := range macIPACLs { 369 acls = append(acls, aclDetails.ACL) 370 } 371 return acls, nil 372 } 373 374 // DumpABFs reads the ACL-based forwarding and returns data read as an *AbfResponse. If the reading ends up with 375 // an error, only the error is send back in the response 376 func (svc *dumpService) DumpABFs() (abfs []*vpp_abf.ABF, err error) { 377 if svc.abfHandler == nil { 378 // handler is not available 379 return nil, nil 380 } 381 382 abfPolicy, err := svc.abfHandler.DumpABFPolicy() 383 if err != nil { 384 return nil, err 385 } 386 for _, abfDetails := range abfPolicy { 387 abfs = append(abfs, abfDetails.ABF) 388 } 389 return abfs, nil 390 } 391 392 // DumpNAT44Global dumps NAT44Global 393 func (svc *dumpService) DumpNAT44Global() (glob *vpp_nat.Nat44Global, err error) { 394 if svc.natHandler == nil { 395 // handler is not available 396 return nil, nil 397 } 398 399 glob, err = svc.natHandler.Nat44GlobalConfigDump(false) 400 if err != nil { 401 return nil, err 402 } 403 return glob, nil 404 } 405 406 // DumpDNAT44s dumps DNat44 407 func (svc *dumpService) DumpDNAT44s() (dnats []*vpp_nat.DNat44, err error) { 408 if svc.natHandler == nil { 409 // handler is not available 410 return nil, nil 411 } 412 413 dnats, err = svc.natHandler.DNat44Dump() 414 if err != nil { 415 return nil, err 416 } 417 return dnats, nil 418 } 419 420 // DumpNAT44Interfaces dumps NAT44Interfaces 421 func (svc *dumpService) DumpNAT44Interfaces() (natIfs []*vpp_nat.Nat44Interface, err error) { 422 if svc.natHandler == nil { 423 // handler is not available 424 return nil, nil 425 } 426 427 natIfs, err = svc.natHandler.Nat44InterfacesDump() 428 if err != nil { 429 return nil, err 430 } 431 return natIfs, nil 432 } 433 434 // DumpNAT44AddressPools dumps NAT44AddressPools 435 func (svc *dumpService) DumpNAT44AddressPools() (natPools []*vpp_nat.Nat44AddressPool, err error) { 436 if svc.natHandler == nil { 437 // handler is not available 438 return nil, nil 439 } 440 441 natPools, err = svc.natHandler.Nat44AddressPoolsDump() 442 if err != nil { 443 return nil, err 444 } 445 return natPools, nil 446 } 447 448 // DumpPunt reads VPP Punt socket registrations and returns them as an *PuntResponse. 449 func (svc *dumpService) DumpPunt() (punts []*vpp_punt.ToHost, err error) { 450 if svc.puntHandler == nil { 451 // handler is not available 452 return nil, nil 453 } 454 dump, err := svc.puntHandler.DumpRegisteredPuntSockets() 455 if err != nil { 456 return nil, err 457 } 458 for _, puntDetails := range dump { 459 punts = append(punts, puntDetails.PuntData) 460 } 461 462 return punts, nil 463 } 464 465 // DumpPuntExceptions reads VPP Punt exceptions and returns them as an *PuntResponse. 466 func (svc *dumpService) DumpPuntExceptions() (punts []*vpp_punt.Exception, err error) { 467 if svc.puntHandler == nil { 468 return nil, errors.New("puntHandler is not available") 469 } 470 dump, err := svc.puntHandler.DumpExceptions() 471 if err != nil { 472 return nil, err 473 } 474 for _, puntDetails := range dump { 475 punts = append(punts, puntDetails.Exception) 476 } 477 478 return punts, nil 479 } 480 481 func (svc *dumpService) DumpWgPeers() (peers []*vpp_wg.Peer, err error) { 482 if svc.wireguardHandler == nil { 483 // handler is not available 484 return nil, nil 485 } 486 487 _peers, err := svc.wireguardHandler.DumpWgPeers() 488 if err != nil { 489 return nil, err 490 } 491 peers = append(peers, _peers...) 492 return 493 } 494 495 // DumpLinuxInterfaces reads linux interfaces and returns them as an *LinuxInterfaceResponse. If reading ends up with error, 496 // only error is send back in response 497 func (svc *dumpService) DumpLinuxInterfaces() (linuxIfs []*linux_interfaces.Interface, err error) { 498 if svc.linuxIfHandler == nil { 499 return nil, errors.New("linuxIfHandler is not available") 500 } 501 502 ifDetails, err := svc.linuxIfHandler.DumpInterfaces() 503 if err != nil { 504 return nil, err 505 } 506 for _, ifDetail := range ifDetails { 507 linuxIfs = append(linuxIfs, ifDetail.Interface) 508 } 509 510 return linuxIfs, nil 511 } 512 513 // DumpLinuxARPs reads linux ARPs and returns them as an *LinuxARPsResponse. If reading ends up with error, 514 // only error is send back in response 515 func (svc *dumpService) DumpLinuxARPs() (linuxARPs []*linux_l3.ARPEntry, err error) { 516 if svc.linuxL3Handler == nil { 517 return nil, errors.New("linuxL3Handler is not available") 518 } 519 520 arpDetails, err := svc.linuxL3Handler.DumpARPEntries() 521 if err != nil { 522 return nil, err 523 } 524 for _, arpDetail := range arpDetails { 525 linuxARPs = append(linuxARPs, arpDetail.ARP) 526 } 527 528 return linuxARPs, nil 529 } 530 531 // DumpLinuxRoutes reads linux routes and returns them as an *LinuxRoutesResponse. If reading ends up with error, 532 // only error is send back in response 533 func (svc *dumpService) DumpLinuxRoutes() (linuxRoutes []*linux_l3.Route, err error) { 534 if svc.linuxL3Handler == nil { 535 return nil, errors.New("linuxL3Handler is not available") 536 } 537 538 rtDetails, err := svc.linuxL3Handler.DumpRoutes() 539 if err != nil { 540 return nil, err 541 } 542 for _, rt := range rtDetails { 543 linuxRoutes = append(linuxRoutes, rt.Route) 544 } 545 546 return linuxRoutes, nil 547 }