go.ligato.io/vpp-agent/v3@v3.5.0/proto/ligato/vpp/nat/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_nat
    16  
    17  import (
    18  	"fmt"
    19  	"strconv"
    20  	"strings"
    21  
    22  	"go.ligato.io/vpp-agent/v3/pkg/models"
    23  )
    24  
    25  // ModuleName is the module name used for models.
    26  const ModuleName = "vpp.nat"
    27  
    28  var (
    29  	ModelNat44Global = models.Register(&Nat44Global{}, models.Spec{
    30  		Module:  ModuleName,
    31  		Type:    "nat44-global",
    32  		Version: "v2",
    33  	})
    34  
    35  	ModelDNat44 = models.Register(&DNat44{}, models.Spec{
    36  		Module:  ModuleName,
    37  		Type:    "dnat44",
    38  		Version: "v2",
    39  	}, models.WithNameTemplate("{{.Label}}"))
    40  
    41  	ModelNat44Interface = models.Register(&Nat44Interface{}, models.Spec{
    42  		Module:  ModuleName,
    43  		Type:    "nat44-interface",
    44  		Version: "v2",
    45  	}, models.WithNameTemplate("{{.Name}}"))
    46  
    47  	ModelNat44AddressPool = models.Register(&Nat44AddressPool{}, models.Spec{
    48  		Module:  ModuleName,
    49  		Type:    "nat44-pool",
    50  		Version: "v2",
    51  	}, models.WithNameTemplate(
    52  		"{{if .Name}}"+
    53  			"{{.Name}}"+
    54  			"{{else}}"+
    55  			"vrf/{{.VrfId}}"+
    56  			"/address/{{.FirstIp}}"+
    57  			"{{if and .LastIp (ne .FirstIp .LastIp)}}-{{.LastIp}}{{end}}"+
    58  			"{{end}}",
    59  	))
    60  )
    61  
    62  // GlobalNAT44Key returns key for Nat44Global.
    63  func GlobalNAT44Key() string {
    64  	return models.Key(&Nat44Global{})
    65  }
    66  
    67  // DNAT44Key returns the key used in NB DB to store the configuration of the
    68  // given DNAT-44 configuration.
    69  func DNAT44Key(label string) string {
    70  	return models.Key(&DNat44{
    71  		Label: label,
    72  	})
    73  }
    74  
    75  // Nat44InterfaceKey returns the key used in NB DB to store the configuration of the
    76  // given NAT44 interface.
    77  func Nat44InterfaceKey(name string) string {
    78  	return models.Key(&Nat44Interface{
    79  		Name: name,
    80  	})
    81  }
    82  
    83  /* NAT44 mode (derived) */
    84  
    85  const (
    86  	// key derived when NAT44 is configured in the endpoint-dependent mode
    87  	Nat44EndpointDepKey = "vpp/nat44/endpoint-dependent"
    88  )
    89  
    90  /* NAT44 interface (derived) */
    91  
    92  const (
    93  	// interfaceNAT44KeyPrefix is a common prefix for (derived) keys each representing
    94  	// NAT44 configuration for a single interface.
    95  	interfaceNAT44KeyPrefix = "vpp/nat44/interface/"
    96  
    97  	// interfaceNAT44KeyTemplate is a template for (derived) key representing
    98  	// NAT44 configuration for a single interface.
    99  	interfaceNAT44KeyTemplate = interfaceNAT44KeyPrefix + "{iface}/feature/{feature}"
   100  
   101  	// NAT interface features
   102  	inFeature  = "in"
   103  	outFeature = "out"
   104  )
   105  
   106  /* NAT44 address (derived) */
   107  
   108  const (
   109  	// addressNAT44KeyPrefix is a common prefix for (derived) keys each representing
   110  	// single address from the NAT44 address pool.
   111  	addressNAT44KeyPrefix = "vpp/nat44/address/"
   112  
   113  	// addressNAT44KeyTemplate is a template for (derived) key representing
   114  	// single address from the NAT44 address pool.
   115  	addressNAT44KeyTemplate = addressNAT44KeyPrefix + "{address}/twice-nat/{twice-nat}"
   116  
   117  	// twice-NAT switch
   118  	twiceNatOn  = "on"
   119  	twiceNatOff = "off"
   120  
   121  	// TwiceNATDerivedKeyPrefix is common prefix for (derived) keys each representing twiceNAT address pool
   122  	TwiceNATDerivedKeyPrefix = "vpp/nat44/twiceNAT-pool/"
   123  
   124  	// twiceNATKeyTemplate is a template for (derived) key
   125  	// representing twiceNAT address pool with single IP range.
   126  	twiceNATKeyTemplate = TwiceNATDerivedKeyPrefix + "vrf/{vrfID}/addresses/{firstIP}"
   127  
   128  	// twiceNATWithMultipeAddressesKeyTemplate is a template for (derived) key
   129  	// representing twiceNAT address pool with multiple IP range.
   130  	twiceNATWithMultipeAddressesKeyTemplate = TwiceNATDerivedKeyPrefix + "vrf/{vrfID}/addresses/{firstIP}-{lastIP}"
   131  )
   132  
   133  const (
   134  	// InvalidKeyPart is used in key for parts which are invalid
   135  	InvalidKeyPart = "<invalid>"
   136  )
   137  
   138  /* NAT44 interface (derived) */
   139  
   140  // DerivedInterfaceNAT44Key returns (derived) key representing NAT44 configuration
   141  // for a given interface.
   142  func DerivedInterfaceNAT44Key(iface string, isInside bool) string {
   143  	if iface == "" {
   144  		iface = InvalidKeyPart
   145  	}
   146  	key := strings.Replace(interfaceNAT44KeyTemplate, "{iface}", iface, 1)
   147  	feature := inFeature
   148  	if !isInside {
   149  		feature = outFeature
   150  	}
   151  	key = strings.Replace(key, "{feature}", feature, 1)
   152  	return key
   153  }
   154  
   155  // ParseDerivedInterfaceNAT44Key parses interface name and the assigned NAT44 feature
   156  // from Interface-NAT44 key.
   157  func ParseDerivedInterfaceNAT44Key(key string) (iface string, isInside bool, isInterfaceNAT44Key bool) {
   158  	trim := strings.TrimPrefix(key, interfaceNAT44KeyPrefix)
   159  	if trim != key && trim != "" {
   160  		fibComps := strings.Split(trim, "/")
   161  		if len(fibComps) >= 3 && fibComps[len(fibComps)-2] == "feature" {
   162  			isInside := true
   163  			if fibComps[len(fibComps)-1] == outFeature {
   164  				isInside = false
   165  			}
   166  			iface := strings.Join(fibComps[:len(fibComps)-2], "/")
   167  			return iface, isInside, true
   168  		}
   169  	}
   170  	return "", false, false
   171  }
   172  
   173  /* NAT44 address (derived) */
   174  
   175  // DerivedAddressNAT44Key returns (derived) key representing NAT44 configuration
   176  // for a single IP address from the NAT44 address pool.
   177  // Address is inserted into the key without validation!
   178  func DerivedAddressNAT44Key(address string, twiceNat bool) string {
   179  	key := strings.Replace(addressNAT44KeyTemplate, "{address}", address, 1)
   180  	twiceNatFlag := twiceNatOff
   181  	if twiceNat {
   182  		twiceNatFlag = twiceNatOn
   183  	}
   184  	key = strings.Replace(key, "{twice-nat}", twiceNatFlag, 1)
   185  	return key
   186  }
   187  
   188  // ParseDerivedAddressNAT44Key parses configuration of a single NAT44 address from a key
   189  // returned by DerivedAddressNAT44Key().
   190  func ParseDerivedAddressNAT44Key(key string) (address string, twiceNat bool, isAddressNAT44Key bool) {
   191  	trim := strings.TrimPrefix(key, addressNAT44KeyPrefix)
   192  	if trim != key && trim != "" {
   193  		fibComps := strings.Split(trim, "/")
   194  		if len(fibComps) >= 3 && fibComps[len(fibComps)-2] == "twice-nat" {
   195  			if fibComps[len(fibComps)-1] == twiceNatOn {
   196  				twiceNat = true
   197  			}
   198  			address = strings.Join(fibComps[:len(fibComps)-2], "/")
   199  			isAddressNAT44Key = true
   200  			return
   201  		}
   202  	}
   203  	return
   204  }
   205  
   206  // DerivedTwiceNATAddressPoolKey returns (derived) key representing TwiceNAT address pool configuration.
   207  func DerivedTwiceNATAddressPoolKey(firstIP, lastIP string, vrfID uint32) (key string) {
   208  	if lastIP == "" {
   209  		key = strings.Replace(twiceNATKeyTemplate, "{vrfID}", fmt.Sprint(vrfID), 1)
   210  		key = strings.Replace(key, "{firstIP}", firstIP, 1)
   211  	} else {
   212  		key = strings.Replace(twiceNATWithMultipeAddressesKeyTemplate, "{vrfID}", fmt.Sprint(vrfID), 1)
   213  		key = strings.Replace(key, "{firstIP}", firstIP, 1)
   214  		key = strings.Replace(key, "{lastIP}", lastIP, 1)
   215  	}
   216  	return key
   217  }
   218  
   219  // ParseDerivedTwiceNATAddressPoolKey parses configuration of a twiceNAT address pool from a key
   220  // returned by DerivedTwiceNATAddressPoolKey().
   221  func ParseDerivedTwiceNATAddressPoolKey(key string) (firstIP, lastIP string, vrfID uint32, isTwiceNatKey bool) {
   222  	trim := strings.TrimPrefix(key, TwiceNATDerivedKeyPrefix)
   223  	if trim != key && trim != "" {
   224  		comps := strings.Split(trim, "/")
   225  		if len(comps) == 4 && comps[0] == "vrf" && comps[2] == "addresses" {
   226  			vrfID64, err := strconv.ParseUint(comps[1], 10, 32)
   227  			if err != nil {
   228  				return
   229  			}
   230  			vrfID = uint32(vrfID64)
   231  			addrComps := strings.Split(comps[3], "-")
   232  			firstIP = addrComps[0]
   233  			if len(addrComps) > 1 {
   234  				lastIP = addrComps[1]
   235  			}
   236  			isTwiceNatKey = true
   237  			return
   238  		}
   239  	}
   240  	return
   241  }