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 }