go.ligato.io/vpp-agent/v3@v3.5.0/proto/ligato/vpp/l3/models.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 vpp_l3
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"go.ligato.io/vpp-agent/v3/pkg/models"
    22  )
    23  
    24  // ModuleName is the module name used for models.
    25  const ModuleName = "vpp"
    26  
    27  var (
    28  	ModelARPEntry = models.Register(&ARPEntry{}, models.Spec{
    29  		Module:  ModuleName,
    30  		Type:    "arp",
    31  		Version: "v2",
    32  	}, models.WithNameTemplate(
    33  		"{{.Interface}}/{{.IpAddress}}",
    34  	))
    35  
    36  	ModelRoute = models.Register(&Route{}, models.Spec{
    37  		Module:  ModuleName,
    38  		Type:    "route",
    39  		Version: "v2",
    40  	}, models.WithNameTemplate(
    41  		`{{if .OutgoingInterface}}{{printf "if/%s/" .OutgoingInterface}}{{end}}`+
    42  			`vrf/{{.VrfId}}/`+
    43  			`{{with ipnet .DstNetwork}}{{printf "dst/%s/%d/" .IP .MaskSize}}`+
    44  			`{{else}}{{printf "dst/%s/" .DstNetwork}}{{end}}`+
    45  			`{{if .NextHopAddr}}gw/{{.NextHopAddr}}{{end}}`,
    46  	))
    47  
    48  	ModelProxyARP = models.Register(&ProxyARP{}, models.Spec{
    49  		Module:  ModuleName,
    50  		Type:    "proxyarp-global",
    51  		Version: "v2",
    52  	})
    53  
    54  	ModelIPScanNeighbor = models.Register(&IPScanNeighbor{}, models.Spec{
    55  		Module:  ModuleName,
    56  		Type:    "ipscanneigh-global",
    57  		Version: "v2",
    58  	})
    59  
    60  	ModelVrfTable = models.Register(&VrfTable{}, models.Spec{
    61  		Module:  ModuleName,
    62  		Type:    "vrf-table",
    63  		Version: "v2",
    64  	}, models.WithNameTemplate(
    65  		`id/{{.Id}}/protocol/{{.Protocol}}`,
    66  	))
    67  
    68  	ModelDHCPProxy = models.Register(&DHCPProxy{}, models.Spec{
    69  		Module:  ModuleName,
    70  		Type:    "dhcp-proxy",
    71  		Version: "v2",
    72  	}, models.WithNameTemplate(
    73  		`{{ protoip .SourceIpAddress}}/rx-vrf/{{.RxVrfId}}`,
    74  	))
    75  
    76  	ModelL3XC = models.Register(&L3XConnect{}, models.Spec{
    77  		Module:  ModuleName,
    78  		Type:    "l3xconnect",
    79  		Version: "v2",
    80  	}, models.WithNameTemplate(
    81  		`{{.Interface}}/protocol/{{.Protocol}}`,
    82  	))
    83  
    84  	ModelTeib = models.Register(&TeibEntry{}, models.Spec{
    85  		Module:  ModuleName,
    86  		Type:    "teib",
    87  		Version: "v2",
    88  	}, models.WithNameTemplate(
    89  		`{{.Interface}}/peer/{{.PeerAddr}}`,
    90  	))
    91  
    92  	ModelVRRPEntry = models.Register(&VRRPEntry{}, models.Spec{
    93  		Module:  ModuleName,
    94  		Type:    "vrrp",
    95  		Version: "v2",
    96  	}, models.WithNameTemplate(
    97  		"{{.Interface}}/vrid/{{.VrId}}",
    98  	))
    99  )
   100  
   101  // ProxyARPKey returns key for global proxy arp
   102  func ProxyARPKey() string {
   103  	return models.Key(&ProxyARP{})
   104  }
   105  
   106  // IPScanNeighborKey returns key for global ip scan neighbor
   107  func IPScanNeighborKey() string {
   108  	return models.Key(&IPScanNeighbor{})
   109  }
   110  
   111  // RouteKey returns the key used in ETCD to store vpp route for vpp instance.
   112  func RouteKey(iface string, vrf uint32, dstNet string, nextHopAddr string) string {
   113  	return models.Key(&Route{
   114  		OutgoingInterface: iface,
   115  		VrfId:             vrf,
   116  		DstNetwork:        dstNet,
   117  		NextHopAddr:       nextHopAddr,
   118  	})
   119  }
   120  
   121  // ArpEntryKey returns the key to store ARP entry
   122  func ArpEntryKey(iface, ipAddr string) string {
   123  	return models.Key(&ARPEntry{
   124  		Interface: iface,
   125  		IpAddress: ipAddr,
   126  	})
   127  }
   128  
   129  // VrfTableKey returns the key used to represent configuration for VPP VRF table.
   130  func VrfTableKey(id uint32, protocol VrfTable_Protocol) string {
   131  	return models.Key(&VrfTable{
   132  		Id:       id,
   133  		Protocol: protocol,
   134  	})
   135  }
   136  
   137  // DHCPProxyKey returns key for DHCP proxy
   138  func DHCPProxyKey(srcIP string, rxVrf uint32) string {
   139  	return models.Key(&DHCPProxy{
   140  		SourceIpAddress: srcIP,
   141  		RxVrfId:         rxVrf,
   142  	})
   143  }
   144  
   145  // L3XCKey returns key for L3XC
   146  func L3XCKey(iface string, protocol L3XConnect_Protocol) string {
   147  	return models.Key(&L3XConnect{
   148  		Interface: iface,
   149  		Protocol:  protocol,
   150  	})
   151  }
   152  
   153  const (
   154  	proxyARPInterfacePrefix   = "vpp/proxyarp/interface/"
   155  	proxyARPInterfaceTemplate = proxyARPInterfacePrefix + "{iface}"
   156  )
   157  
   158  // ProxyARPInterfaceKey returns the key used to represent binding for interface with enabled proxy ARP.
   159  func ProxyARPInterfaceKey(iface string) string {
   160  	key := proxyARPInterfaceTemplate
   161  	key = strings.Replace(key, "{iface}", iface, 1)
   162  	return key
   163  }
   164  
   165  // ParseProxyARPInterfaceKey parses key representing binding for interface with enabled proxy ARP.
   166  func ParseProxyARPInterfaceKey(key string) (iface string, isProxyARPInterfaceKey bool) {
   167  	suffix := strings.TrimPrefix(key, proxyARPInterfacePrefix)
   168  	if suffix != key && suffix != "" {
   169  		return suffix, true
   170  	}
   171  	return "", false
   172  }
   173  
   174  // RouteVrfPrefix returns longest-common prefix of keys representing route that is written to given vrf table.
   175  func RouteVrfPrefix(vrf uint32) string {
   176  	return ModelRoute.KeyPrefix() + "vrf/" + fmt.Sprint(vrf) + "/"
   177  }
   178  
   179  // ParseRouteKey parses VRF label and route address from a route key.
   180  func ParseRouteKey(key string) (outIface, vrfIndex, dstNet, nextHopAddr string, isRouteKey bool) {
   181  	if routeKey := strings.TrimPrefix(key, ModelRoute.KeyPrefix()); routeKey != key {
   182  		var foundVrf, foundDst bool
   183  		keyParts := strings.Split(routeKey, "/")
   184  		outIface, _ = getRouteKeyItem(keyParts, "if", "vrf")
   185  		vrfIndex, foundVrf = getRouteKeyItem(keyParts, "vrf", "dst")
   186  		dstNet, foundDst = getRouteKeyItem(keyParts, "dst", "gw")
   187  		nextHopAddr, _ = getRouteKeyItem(keyParts, "gw", "")
   188  		if foundDst && foundVrf {
   189  			isRouteKey = true
   190  			return
   191  		}
   192  	}
   193  	return "", "", "", "", false
   194  }
   195  
   196  // VrrpEntryKey returns the key to store VRRP entry
   197  func VrrpEntryKey(iface string, vrId uint32) string {
   198  	return models.Key(&VRRPEntry{
   199  		Interface: iface,
   200  		VrId:      vrId,
   201  	})
   202  }
   203  
   204  func getRouteKeyItem(items []string, itemLabel, nextItemLabel string) (value string, found bool) {
   205  	begin := len(items)
   206  	end := len(items)
   207  	for i, item := range items {
   208  		if item == itemLabel {
   209  			begin = i + 1
   210  		}
   211  		if nextItemLabel != "" && item == nextItemLabel {
   212  			end = i
   213  			break
   214  		}
   215  	}
   216  	if begin < end {
   217  		value = strings.Join(items[begin:end], "/")
   218  		value = strings.TrimSuffix(value, "/")
   219  		return value, true
   220  	}
   221  	return "", false
   222  }