github.com/cilium/cilium@v1.16.2/pkg/datapath/linux/routing/info.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package linuxrouting
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"net"
    10  	"strconv"
    11  
    12  	"github.com/cilium/cilium/pkg/mac"
    13  )
    14  
    15  // RoutingInfo represents information that's required to enable
    16  // connectivity via the local rule and route tables while in ENI or Azure IPAM mode.
    17  // The information in this struct is used to create rules and routes which direct
    18  // traffic out of the interface (egress).
    19  //
    20  // This struct is mostly derived from the `ipam.AllocationResult` as the
    21  // information comes from IPAM.
    22  type RoutingInfo struct {
    23  	// IPv4Gateway is the gateway where outbound/egress traffic is directed.
    24  	IPv4Gateway net.IP
    25  
    26  	// IPv4CIDRs is a list of CIDRs which the interface has access to. In most
    27  	// cases, it'll at least contain the CIDR of the IPv4Gateway IP address.
    28  	IPv4CIDRs []net.IPNet
    29  
    30  	// MasterIfMAC is the MAC address of the master interface that egress
    31  	// traffic is directed to. This is the MAC of the interface itself which
    32  	// corresponds to the IPv4Gateway IP addr.
    33  	MasterIfMAC mac.MAC
    34  
    35  	// Masquerade represents whether masquerading is enabled or not.
    36  	Masquerade bool
    37  
    38  	// InterfaceNumber is the generic number of the master interface that
    39  	// egress traffic is directed to. This is used to compute the table ID for
    40  	// the per-ENI tables.
    41  	InterfaceNumber int
    42  
    43  	// IpamMode tells us which IPAM mode is being used (e.g., ENI, AKS).
    44  	IpamMode string
    45  }
    46  
    47  func (info *RoutingInfo) GetIPv4CIDRs() []net.IPNet {
    48  	return info.IPv4CIDRs
    49  }
    50  
    51  // NewRoutingInfo creates a new RoutingInfo struct, from data that will be
    52  // parsed and validated. Note, this code assumes IPv4 values because IPv4
    53  // (on either ENI or Azure interface) is the only supported path currently.
    54  // Azure does not support masquerade yet (subnets CIDRs aren't provided):
    55  // until it does, we forward a masquerade bool to opt out ipam.Cidrs use.
    56  func NewRoutingInfo(gateway string, cidrs []string, mac, ifaceNum, ipamMode string, masquerade bool) (*RoutingInfo, error) {
    57  	return parse(gateway, cidrs, mac, ifaceNum, ipamMode, masquerade)
    58  }
    59  
    60  func parse(gateway string, cidrs []string, macAddr, ifaceNum, ipamMode string, masquerade bool) (*RoutingInfo, error) {
    61  	ip := net.ParseIP(gateway)
    62  	if ip == nil {
    63  		return nil, fmt.Errorf("invalid ip: %s", gateway)
    64  	}
    65  
    66  	if len(cidrs) == 0 && masquerade {
    67  		return nil, errors.New("empty cidrs")
    68  	}
    69  
    70  	parsedCIDRs := make([]net.IPNet, 0, len(cidrs))
    71  	for _, cidr := range cidrs {
    72  		_, c, err := net.ParseCIDR(cidr)
    73  		if err != nil {
    74  			return nil, fmt.Errorf("invalid cidr: %s", cidr)
    75  		}
    76  
    77  		parsedCIDRs = append(parsedCIDRs, *c)
    78  	}
    79  
    80  	parsedMAC, err := mac.ParseMAC(macAddr)
    81  	if err != nil {
    82  		return nil, fmt.Errorf("invalid mac: %s", macAddr)
    83  	}
    84  
    85  	parsedIfaceNum, err := strconv.Atoi(ifaceNum)
    86  	if err != nil {
    87  		return nil, fmt.Errorf("invalid interface number: %s", ifaceNum)
    88  	}
    89  
    90  	return &RoutingInfo{
    91  		IPv4Gateway:     ip,
    92  		IPv4CIDRs:       parsedCIDRs,
    93  		MasterIfMAC:     parsedMAC,
    94  		Masquerade:      masquerade,
    95  		InterfaceNumber: parsedIfaceNum,
    96  		IpamMode:        ipamMode,
    97  	}, nil
    98  }