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  }