go.ligato.io/vpp-agent/v3@v3.5.0/clientv2/linux/dbadapter/data_resync_db.go (about)

     1  // Copyright (c) 2018 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 dbadapter
    16  
    17  import (
    18  	"go.ligato.io/cn-infra/v2/db/keyval"
    19  
    20  	linuxclient "go.ligato.io/vpp-agent/v3/clientv2/linux"
    21  	vppclient "go.ligato.io/vpp-agent/v3/clientv2/vpp"
    22  	"go.ligato.io/vpp-agent/v3/clientv2/vpp/dbadapter"
    23  	"go.ligato.io/vpp-agent/v3/pkg/models"
    24  	linux_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces"
    25  	linux_iptables "go.ligato.io/vpp-agent/v3/proto/ligato/linux/iptables"
    26  	linux_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/linux/l3"
    27  	abf "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/abf"
    28  	acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl"
    29  	interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    30  	ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix"
    31  	ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec"
    32  	l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2"
    33  	l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3"
    34  	nat "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/nat"
    35  	punt "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/punt"
    36  	stn "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/stn"
    37  )
    38  
    39  // NewDataResyncDSL returns a new instance of DataResyncDSL which implements
    40  // the data RESYNC DSL for both Linux and VPP config (inherits dbadapter
    41  // from vppplugin).
    42  // Transaction <txn> is used to propagate changes to plugins.
    43  // Function <listKeys> is used to list keys with already existing configuration.
    44  func NewDataResyncDSL(txn keyval.ProtoTxn, listKeys func(prefix string) (keyval.ProtoKeyIterator, error)) *DataResyncDSL {
    45  	vppDataResync := dbadapter.NewDataResyncDSL(txn, listKeys)
    46  	return &DataResyncDSL{txn, []string{}, listKeys, vppDataResync}
    47  }
    48  
    49  // DataResyncDSL is an implementation of Domain Specific Language (DSL) for data
    50  // RESYNC of both Linux and VPP configuration.
    51  type DataResyncDSL struct {
    52  	txn      keyval.ProtoTxn
    53  	txnKeys  []string
    54  	listKeys func(prefix string) (keyval.ProtoKeyIterator, error)
    55  
    56  	vppDataResync vppclient.DataResyncDSL
    57  }
    58  
    59  // LinuxInterface adds Linux interface to the RESYNC request.
    60  func (dsl *DataResyncDSL) LinuxInterface(val *linux_interfaces.Interface) linuxclient.DataResyncDSL {
    61  	key := linux_interfaces.InterfaceKey(val.Name)
    62  	dsl.txn.Put(key, val)
    63  	dsl.txnKeys = append(dsl.txnKeys, key)
    64  
    65  	return dsl
    66  }
    67  
    68  // LinuxArpEntry adds Linux ARP entry to the RESYNC request.
    69  func (dsl *DataResyncDSL) LinuxArpEntry(val *linux_l3.ARPEntry) linuxclient.DataResyncDSL {
    70  	key := linux_l3.ArpKey(val.Interface, val.IpAddress)
    71  	dsl.txn.Put(key, val)
    72  	dsl.txnKeys = append(dsl.txnKeys, key)
    73  
    74  	return dsl
    75  }
    76  
    77  // LinuxRoute adds Linux route to the RESYNC request.
    78  func (dsl *DataResyncDSL) LinuxRoute(val *linux_l3.Route) linuxclient.DataResyncDSL {
    79  	key := linux_l3.RouteKey(val.DstNetwork, val.OutgoingInterface)
    80  	dsl.txn.Put(key, val)
    81  	dsl.txnKeys = append(dsl.txnKeys, key)
    82  
    83  	return dsl
    84  }
    85  
    86  // IptablesRuleChain adds iptables rule chain to the RESYNC request.
    87  func (dsl *DataResyncDSL) IptablesRuleChain(val *linux_iptables.RuleChain) linuxclient.DataResyncDSL {
    88  	key := linux_iptables.RuleChainKey(val.Name)
    89  	dsl.txn.Put(key, val)
    90  	dsl.txnKeys = append(dsl.txnKeys, key)
    91  
    92  	return dsl
    93  }
    94  
    95  // VppInterface adds VPP interface to the RESYNC request.
    96  func (dsl *DataResyncDSL) VppInterface(intf *interfaces.Interface) linuxclient.DataResyncDSL {
    97  	dsl.vppDataResync.Interface(intf)
    98  	return dsl
    99  }
   100  
   101  // Span adds VPP span to the RESYNC request.
   102  func (dsl *DataResyncDSL) Span(span *interfaces.Span) linuxclient.DataResyncDSL {
   103  	dsl.vppDataResync.Span(span)
   104  	return dsl
   105  }
   106  
   107  // ACL adds VPP Access Control List to the RESYNC request.
   108  func (dsl *DataResyncDSL) ACL(acl *acl.ACL) linuxclient.DataResyncDSL {
   109  	dsl.vppDataResync.ACL(acl)
   110  	return dsl
   111  }
   112  
   113  // ABF adds ACL-based forwarding to the RESYNC request.
   114  func (dsl *DataResyncDSL) ABF(abf *abf.ABF) linuxclient.DataResyncDSL {
   115  	dsl.vppDataResync.ABF(abf)
   116  	return dsl
   117  }
   118  
   119  /*// BfdSession adds VPP bidirectional forwarding detection session
   120  // to the RESYNC request.
   121  func (dsl *DataResyncDSL) BfdSession(val *bfd.SingleHopBFD_Session) linuxclient.DataResyncDSL {
   122  	dsl.vppDataResync.BfdSession(val)
   123  	return dsl
   124  }
   125  
   126  // BfdAuthKeys adds VPP bidirectional forwarding detection key to the RESYNC
   127  // request.
   128  func (dsl *DataResyncDSL) BfdAuthKeys(val *bfd.SingleHopBFD_Key) linuxclient.DataResyncDSL {
   129  	dsl.vppDataResync.BfdAuthKeys(val)
   130  	return dsl
   131  }
   132  
   133  // BfdEchoFunction adds VPP bidirectional forwarding detection echo function
   134  // to the RESYNC request.
   135  func (dsl *DataResyncDSL) BfdEchoFunction(val *bfd.SingleHopBFD_EchoFunction) linuxclient.DataResyncDSL {
   136  	dsl.vppDataResync.BfdEchoFunction(val)
   137  	return dsl
   138  }*/
   139  
   140  // BD adds VPP Bridge Domain to the RESYNC request.
   141  func (dsl *DataResyncDSL) BD(bd *l2.BridgeDomain) linuxclient.DataResyncDSL {
   142  	dsl.vppDataResync.BD(bd)
   143  	return dsl
   144  }
   145  
   146  // BDFIB adds VPP L2 FIB to the RESYNC request.
   147  func (dsl *DataResyncDSL) BDFIB(fib *l2.FIBEntry) linuxclient.DataResyncDSL {
   148  	dsl.vppDataResync.BDFIB(fib)
   149  	return dsl
   150  }
   151  
   152  // XConnect adds VPP Cross Connect to the RESYNC request.
   153  func (dsl *DataResyncDSL) XConnect(xcon *l2.XConnectPair) linuxclient.DataResyncDSL {
   154  	dsl.vppDataResync.XConnect(xcon)
   155  	return dsl
   156  }
   157  
   158  // VrfTable adds VPP VRF table to the RESYNC request.
   159  func (dsl *DataResyncDSL) VrfTable(vrfTable *l3.VrfTable) linuxclient.DataResyncDSL {
   160  	dsl.vppDataResync.VrfTable(vrfTable)
   161  	return dsl
   162  }
   163  
   164  // StaticRoute adds VPP L3 Static Route to the RESYNC request.
   165  func (dsl *DataResyncDSL) StaticRoute(staticRoute *l3.Route) linuxclient.DataResyncDSL {
   166  	dsl.vppDataResync.StaticRoute(staticRoute)
   167  	return dsl
   168  }
   169  
   170  // Arp adds VPP L3 ARP to the RESYNC request.
   171  func (dsl *DataResyncDSL) Arp(arp *l3.ARPEntry) linuxclient.DataResyncDSL {
   172  	dsl.vppDataResync.Arp(arp)
   173  	return dsl
   174  }
   175  
   176  // ProxyArp adds L3 proxy ARP to the RESYNC request.
   177  func (dsl *DataResyncDSL) ProxyArp(proxyArp *l3.ProxyARP) linuxclient.DataResyncDSL {
   178  	dsl.vppDataResync.ProxyArp(proxyArp)
   179  	return dsl
   180  }
   181  
   182  // IPScanNeighbor adds L3 IP Scan Neighbor to the RESYNC request.
   183  func (dsl *DataResyncDSL) IPScanNeighbor(ipScanNeigh *l3.IPScanNeighbor) linuxclient.DataResyncDSL {
   184  	dsl.vppDataResync.IPScanNeighbor(ipScanNeigh)
   185  
   186  	return dsl
   187  }
   188  
   189  /*// L4Features adds L4 features to the RESYNC request
   190  func (dsl *DataResyncDSL) L4Features(val *l4.L4Features) linuxclient.DataResyncDSL {
   191  	dsl.vppDataResync.L4Features(val)
   192  	return dsl
   193  }
   194  
   195  // AppNamespace adds VPP Application namespaces to the RESYNC request
   196  func (dsl *DataResyncDSL) AppNamespace(appNs *l4.AppNamespaces_AppNamespace) linuxclient.DataResyncDSL {
   197  	dsl.vppDataResync.AppNamespace(appNs)
   198  	return dsl
   199  }*/
   200  
   201  // StnRule adds Stn rule to the RESYNC request.
   202  func (dsl *DataResyncDSL) StnRule(stn *stn.Rule) linuxclient.DataResyncDSL {
   203  	dsl.vppDataResync.StnRule(stn)
   204  	return dsl
   205  }
   206  
   207  // NAT44Global adds global NAT44 configuration to the RESYNC request.
   208  func (dsl *DataResyncDSL) NAT44Global(nat44 *nat.Nat44Global) linuxclient.DataResyncDSL {
   209  	dsl.vppDataResync.NAT44Global(nat44)
   210  	return dsl
   211  }
   212  
   213  // DNAT44 adds DNAT44 configuration to the RESYNC request
   214  func (dsl *DataResyncDSL) DNAT44(nat44 *nat.DNat44) linuxclient.DataResyncDSL {
   215  	dsl.vppDataResync.DNAT44(nat44)
   216  	return dsl
   217  }
   218  
   219  // NAT44Interface adds NAT44 interface configuration to the RESYNC request.
   220  func (dsl *DataResyncDSL) NAT44Interface(natIf *nat.Nat44Interface) linuxclient.DataResyncDSL {
   221  	key := models.Key(natIf)
   222  	dsl.txn.Put(key, natIf)
   223  	dsl.txnKeys = append(dsl.txnKeys, key)
   224  
   225  	return dsl
   226  }
   227  
   228  // NAT44AddressPool adds NAT44 address pool configuration to the RESYNC request.
   229  func (dsl *DataResyncDSL) NAT44AddressPool(pool *nat.Nat44AddressPool) linuxclient.DataResyncDSL {
   230  	key := models.Key(pool)
   231  	dsl.txn.Put(key, pool)
   232  	dsl.txnKeys = append(dsl.txnKeys, key)
   233  
   234  	return dsl
   235  }
   236  
   237  // IPSecSA adds request to RESYNC a new Security Association
   238  func (dsl *DataResyncDSL) IPSecSA(sa *ipsec.SecurityAssociation) linuxclient.DataResyncDSL {
   239  	dsl.vppDataResync.IPSecSA(sa)
   240  	return dsl
   241  }
   242  
   243  // IPSecSPD adds request to RESYNC a new Security Policy Database
   244  func (dsl *DataResyncDSL) IPSecSPD(spd *ipsec.SecurityPolicyDatabase) linuxclient.DataResyncDSL {
   245  	dsl.vppDataResync.IPSecSPD(spd)
   246  	return dsl
   247  }
   248  
   249  // IPSecSP adds Security Policy into the RESYNC request
   250  func (dsl *DataResyncDSL) IPSecSP(sp *ipsec.SecurityPolicy) linuxclient.DataResyncDSL {
   251  	dsl.vppDataResync.IPSecSP(sp)
   252  	return dsl
   253  }
   254  
   255  // IPSecTunnelProtection adds request to RESYNC an IPSec tunnel protection
   256  func (dsl *DataResyncDSL) IPSecTunnelProtection(tp *ipsec.TunnelProtection) linuxclient.DataResyncDSL {
   257  	dsl.vppDataResync.IPSecTunnelProtection(tp)
   258  	return dsl
   259  }
   260  
   261  // PuntIPRedirect adds request to RESYNC a rule used to punt L3 traffic via interface.
   262  func (dsl *DataResyncDSL) PuntIPRedirect(val *punt.IPRedirect) linuxclient.DataResyncDSL {
   263  	dsl.vppDataResync.PuntIPRedirect(val)
   264  	return dsl
   265  }
   266  
   267  // PuntToHost adds request to RESYNC a rule used to punt L4 traffic to a host.
   268  func (dsl *DataResyncDSL) PuntToHost(val *punt.ToHost) linuxclient.DataResyncDSL {
   269  	dsl.vppDataResync.PuntToHost(val)
   270  	return dsl
   271  }
   272  
   273  // PuntException adds request to create or update exception to punt specific packets.
   274  func (dsl *DataResyncDSL) PuntException(val *punt.Exception) linuxclient.DataResyncDSL {
   275  	key := models.Key(val)
   276  	dsl.txn.Put(key, val)
   277  	dsl.txnKeys = append(dsl.txnKeys, key)
   278  
   279  	return dsl
   280  }
   281  
   282  // IPFIX adds IPFIX configuration to the RESYNC request.
   283  func (dsl *DataResyncDSL) IPFIX(val *ipfix.IPFIX) linuxclient.DataResyncDSL {
   284  	key := models.Key(val)
   285  	dsl.txn.Put(key, val)
   286  	dsl.txnKeys = append(dsl.txnKeys, key)
   287  
   288  	return dsl
   289  }
   290  
   291  // FlowprobeParams adds Flowprobe Params configuration to the RESYNC request.
   292  func (dsl *DataResyncDSL) FlowprobeParams(val *ipfix.FlowProbeParams) linuxclient.DataResyncDSL {
   293  	key := models.Key(val)
   294  	dsl.txn.Put(key, val)
   295  	dsl.txnKeys = append(dsl.txnKeys, key)
   296  
   297  	return dsl
   298  }
   299  
   300  // FlowprobeFeature adds Flowprobe Feature configuration to the RESYNC request.
   301  func (dsl *DataResyncDSL) FlowprobeFeature(val *ipfix.FlowProbeFeature) linuxclient.DataResyncDSL {
   302  	key := models.Key(val)
   303  	dsl.txn.Put(key, val)
   304  	dsl.txnKeys = append(dsl.txnKeys, key)
   305  
   306  	return dsl
   307  }
   308  
   309  // VRRP adds VRRP entry to the RESYNC request.
   310  func (dsl *DataResyncDSL) VRRP(val *l3.VRRPEntry) linuxclient.DataResyncDSL {
   311  	dsl.vppDataResync.VRRP(val)
   312  	return dsl
   313  }
   314  
   315  // AppendKeys is a helper function that fills the keySet <keys> with values
   316  // pointed to by the iterator <it>.
   317  func appendKeys(keys *keySet, it keyval.ProtoKeyIterator) {
   318  	for {
   319  		k, _, stop := it.GetNext()
   320  		if stop {
   321  			break
   322  		}
   323  
   324  		(*keys)[k] = nil
   325  	}
   326  }
   327  
   328  // KeySet is a helper type that reuses map keys to store values as a set.
   329  // The values of the map are nil.
   330  type keySet map[string] /*key*/ interface{} /*nil*/
   331  
   332  // Send propagates the request to the plugins.
   333  // It deletes obsolete keys if listKeys() (from constructor) function is not nil.
   334  func (dsl *DataResyncDSL) Send() vppclient.Reply {
   335  
   336  	if dsl.listKeys != nil {
   337  		toBeDeleted := keySet{}
   338  
   339  		// fill all known keys associated with the Linux network configuration:
   340  		keys, err := dsl.listKeys(interfaces.ModelInterface.KeyPrefix())
   341  		if err != nil {
   342  			return dsl.vppDataResync.Send()
   343  		}
   344  		appendKeys(&toBeDeleted, keys)
   345  
   346  		// remove keys that are part of the transaction
   347  		for _, txnKey := range dsl.txnKeys {
   348  			delete(toBeDeleted, txnKey)
   349  		}
   350  
   351  		for delKey := range toBeDeleted {
   352  			dsl.txn.Delete(delKey)
   353  		}
   354  	}
   355  
   356  	return dsl.vppDataResync.Send()
   357  }