...

Source file src/k8s.io/kubernetes/pkg/proxy/util/iptables/traffic.go

Documentation: k8s.io/kubernetes/pkg/proxy/util/iptables

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package iptables
    18  
    19  import (
    20  	"fmt"
    21  
    22  	netutils "k8s.io/utils/net"
    23  )
    24  
    25  // LocalTrafficDetector in a interface to take action (jump) based on whether traffic originated locally
    26  // at the node or not
    27  type LocalTrafficDetector interface {
    28  	// IsImplemented returns true if the implementation does something, false otherwise
    29  	IsImplemented() bool
    30  
    31  	// IfLocal returns iptables arguments that will match traffic from a pod
    32  	IfLocal() []string
    33  
    34  	// IfNotLocal returns iptables arguments that will match traffic that is not from a pod
    35  	IfNotLocal() []string
    36  
    37  	// IfLocalNFT returns nftables arguments that will match traffic from a pod
    38  	IfLocalNFT() []string
    39  
    40  	// IfNotLocalNFT returns nftables arguments that will match traffic that is not from a pod
    41  	IfNotLocalNFT() []string
    42  }
    43  
    44  type noOpLocalDetector struct{}
    45  
    46  // NewNoOpLocalDetector is a no-op implementation of LocalTrafficDetector
    47  func NewNoOpLocalDetector() LocalTrafficDetector {
    48  	return &noOpLocalDetector{}
    49  }
    50  
    51  func (n *noOpLocalDetector) IsImplemented() bool {
    52  	return false
    53  }
    54  
    55  func (n *noOpLocalDetector) IfLocal() []string {
    56  	return nil // no-op; matches all traffic
    57  }
    58  
    59  func (n *noOpLocalDetector) IfNotLocal() []string {
    60  	return nil // no-op; matches all traffic
    61  }
    62  
    63  func (n *noOpLocalDetector) IfLocalNFT() []string {
    64  	return nil // no-op; matches all traffic
    65  }
    66  
    67  func (n *noOpLocalDetector) IfNotLocalNFT() []string {
    68  	return nil // no-op; matches all traffic
    69  }
    70  
    71  type detectLocalByCIDR struct {
    72  	ifLocal       []string
    73  	ifNotLocal    []string
    74  	ifLocalNFT    []string
    75  	ifNotLocalNFT []string
    76  }
    77  
    78  // NewDetectLocalByCIDR implements the LocalTrafficDetector interface using a CIDR. This can be used when a single CIDR
    79  // range can be used to capture the notion of local traffic.
    80  func NewDetectLocalByCIDR(cidr string) (LocalTrafficDetector, error) {
    81  	_, parsed, err := netutils.ParseCIDRSloppy(cidr)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  
    86  	nftFamily := "ip"
    87  	if netutils.IsIPv6CIDR(parsed) {
    88  		nftFamily = "ip6"
    89  	}
    90  
    91  	return &detectLocalByCIDR{
    92  		ifLocal:       []string{"-s", cidr},
    93  		ifNotLocal:    []string{"!", "-s", cidr},
    94  		ifLocalNFT:    []string{nftFamily, "saddr", cidr},
    95  		ifNotLocalNFT: []string{nftFamily, "saddr", "!=", cidr},
    96  	}, nil
    97  }
    98  
    99  func (d *detectLocalByCIDR) IsImplemented() bool {
   100  	return true
   101  }
   102  
   103  func (d *detectLocalByCIDR) IfLocal() []string {
   104  	return d.ifLocal
   105  }
   106  
   107  func (d *detectLocalByCIDR) IfNotLocal() []string {
   108  	return d.ifNotLocal
   109  }
   110  
   111  func (d *detectLocalByCIDR) IfLocalNFT() []string {
   112  	return d.ifLocalNFT
   113  }
   114  
   115  func (d *detectLocalByCIDR) IfNotLocalNFT() []string {
   116  	return d.ifNotLocalNFT
   117  }
   118  
   119  type detectLocalByBridgeInterface struct {
   120  	ifLocal       []string
   121  	ifNotLocal    []string
   122  	ifLocalNFT    []string
   123  	ifNotLocalNFT []string
   124  }
   125  
   126  // NewDetectLocalByBridgeInterface implements the LocalTrafficDetector interface using a bridge interface name.
   127  // This can be used when a bridge can be used to capture the notion of local traffic from pods.
   128  func NewDetectLocalByBridgeInterface(interfaceName string) (LocalTrafficDetector, error) {
   129  	if len(interfaceName) == 0 {
   130  		return nil, fmt.Errorf("no bridge interface name set")
   131  	}
   132  	return &detectLocalByBridgeInterface{
   133  		ifLocal:       []string{"-i", interfaceName},
   134  		ifNotLocal:    []string{"!", "-i", interfaceName},
   135  		ifLocalNFT:    []string{"iif", interfaceName},
   136  		ifNotLocalNFT: []string{"iif", "!=", interfaceName},
   137  	}, nil
   138  }
   139  
   140  func (d *detectLocalByBridgeInterface) IsImplemented() bool {
   141  	return true
   142  }
   143  
   144  func (d *detectLocalByBridgeInterface) IfLocal() []string {
   145  	return d.ifLocal
   146  }
   147  
   148  func (d *detectLocalByBridgeInterface) IfNotLocal() []string {
   149  	return d.ifNotLocal
   150  }
   151  
   152  func (d *detectLocalByBridgeInterface) IfLocalNFT() []string {
   153  	return d.ifLocalNFT
   154  }
   155  
   156  func (d *detectLocalByBridgeInterface) IfNotLocalNFT() []string {
   157  	return d.ifNotLocalNFT
   158  }
   159  
   160  type detectLocalByInterfaceNamePrefix struct {
   161  	ifLocal       []string
   162  	ifNotLocal    []string
   163  	ifLocalNFT    []string
   164  	ifNotLocalNFT []string
   165  }
   166  
   167  // NewDetectLocalByInterfaceNamePrefix implements the LocalTrafficDetector interface using an interface name prefix.
   168  // This can be used when a pod interface name prefix can be used to capture the notion of local traffic. Note
   169  // that this will match on all interfaces that start with the given prefix.
   170  func NewDetectLocalByInterfaceNamePrefix(interfacePrefix string) (LocalTrafficDetector, error) {
   171  	if len(interfacePrefix) == 0 {
   172  		return nil, fmt.Errorf("no interface prefix set")
   173  	}
   174  	return &detectLocalByInterfaceNamePrefix{
   175  		ifLocal:       []string{"-i", interfacePrefix + "+"},
   176  		ifNotLocal:    []string{"!", "-i", interfacePrefix + "+"},
   177  		ifLocalNFT:    []string{"iif", interfacePrefix + "*"},
   178  		ifNotLocalNFT: []string{"iif", "!=", interfacePrefix + "*"},
   179  	}, nil
   180  }
   181  
   182  func (d *detectLocalByInterfaceNamePrefix) IsImplemented() bool {
   183  	return true
   184  }
   185  
   186  func (d *detectLocalByInterfaceNamePrefix) IfLocal() []string {
   187  	return d.ifLocal
   188  }
   189  
   190  func (d *detectLocalByInterfaceNamePrefix) IfNotLocal() []string {
   191  	return d.ifNotLocal
   192  }
   193  
   194  func (d *detectLocalByInterfaceNamePrefix) IfLocalNFT() []string {
   195  	return d.ifLocalNFT
   196  }
   197  
   198  func (d *detectLocalByInterfaceNamePrefix) IfNotLocalNFT() []string {
   199  	return d.ifNotLocalNFT
   200  }
   201  

View as plain text