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 }