mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Local Traffic Detector: Add two new modes
This PR introduces two new modes for detecting local traffic in a cluster. 1) detectLocalByBridgeInterface: This takes a bridge name as argument and decides all traffic that match on their originating interface being that of this bridge, shall be considered as local pod traffic. 2) detectLocalByInterfaceNamePrefix: This takes an interface prefix name as argument and decides all traffic that match on their originating interface names having a prefix that matches this argument shall be considered as local pod traffic. Signed-off-by: Surya Seetharaman <suryaseetharaman.9@gmail.com>
This commit is contained in:
parent
e7845861a5
commit
5632991115
@ -87,3 +87,62 @@ func (d *detectLocalByCIDR) IfLocal() []string {
|
||||
func (d *detectLocalByCIDR) IfNotLocal() []string {
|
||||
return d.ifNotLocal
|
||||
}
|
||||
|
||||
type detectLocalByBridgeInterface struct {
|
||||
ifLocal []string
|
||||
ifNotLocal []string
|
||||
}
|
||||
|
||||
// NewDetectLocalByBridgeInterface implements the LocalTrafficDetector interface using a bridge interface name.
|
||||
// This can be used when a bridge can be used to capture the notion of local traffic from pods.
|
||||
func NewDetectLocalByBridgeInterface(interfaceName string) (LocalTrafficDetector, error) {
|
||||
if len(interfaceName) == 0 {
|
||||
return nil, fmt.Errorf("no bridge interface name set")
|
||||
}
|
||||
return &detectLocalByBridgeInterface{
|
||||
ifLocal: []string{"-i", interfaceName},
|
||||
ifNotLocal: []string{"!", "-i", interfaceName},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *detectLocalByBridgeInterface) IsImplemented() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (d *detectLocalByBridgeInterface) IfLocal() []string {
|
||||
return d.ifLocal
|
||||
}
|
||||
|
||||
func (d *detectLocalByBridgeInterface) IfNotLocal() []string {
|
||||
return d.ifNotLocal
|
||||
}
|
||||
|
||||
type detectLocalByInterfaceNamePrefix struct {
|
||||
ifLocal []string
|
||||
ifNotLocal []string
|
||||
}
|
||||
|
||||
// NewDetectLocalByInterfaceNamePrefix implements the LocalTrafficDetector interface using an interface name prefix.
|
||||
// This can be used when a pod interface name prefix can be used to capture the notion of local traffic. Note
|
||||
// that this will match on all interfaces that start with the given prefix.
|
||||
func NewDetectLocalByInterfaceNamePrefix(interfacePrefix string) (LocalTrafficDetector, error) {
|
||||
if len(interfacePrefix) == 0 {
|
||||
return nil, fmt.Errorf("no interface prefix set")
|
||||
}
|
||||
return &detectLocalByInterfaceNamePrefix{
|
||||
ifLocal: []string{"-i", interfacePrefix + "+"},
|
||||
ifNotLocal: []string{"!", "-i", interfacePrefix + "+"},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *detectLocalByInterfaceNamePrefix) IsImplemented() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (d *detectLocalByInterfaceNamePrefix) IfLocal() []string {
|
||||
return d.ifLocal
|
||||
}
|
||||
|
||||
func (d *detectLocalByInterfaceNamePrefix) IfNotLocal() []string {
|
||||
return d.ifNotLocal
|
||||
}
|
||||
|
@ -144,3 +144,135 @@ func TestDetectLocalByCIDR(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDetectLocalByBridgeInterface(t *testing.T) {
|
||||
cases := []struct {
|
||||
ifaceName string
|
||||
errExpected bool
|
||||
}{
|
||||
{
|
||||
ifaceName: "avz",
|
||||
errExpected: false,
|
||||
},
|
||||
{
|
||||
ifaceName: "",
|
||||
errExpected: true,
|
||||
},
|
||||
}
|
||||
for i, c := range cases {
|
||||
r, err := NewDetectLocalByBridgeInterface(c.ifaceName)
|
||||
if c.errExpected {
|
||||
if err == nil {
|
||||
t.Errorf("Case[%d] expected error, but succeeded with: %q", i, r)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("Case[%d] failed with error: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDetectLocalByInterfaceNamePrefix(t *testing.T) {
|
||||
cases := []struct {
|
||||
ifacePrefix string
|
||||
errExpected bool
|
||||
}{
|
||||
{
|
||||
ifacePrefix: "veth",
|
||||
errExpected: false,
|
||||
},
|
||||
{
|
||||
ifacePrefix: "cbr0",
|
||||
errExpected: false,
|
||||
},
|
||||
{
|
||||
ifacePrefix: "",
|
||||
errExpected: true,
|
||||
},
|
||||
}
|
||||
for i, c := range cases {
|
||||
r, err := NewDetectLocalByInterfaceNamePrefix(c.ifacePrefix)
|
||||
if c.errExpected {
|
||||
if err == nil {
|
||||
t.Errorf("Case[%d] expected error, but succeeded with: %q", i, r)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("Case[%d] failed with error: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectLocalByBridgeInterface(t *testing.T) {
|
||||
cases := []struct {
|
||||
ifaceName string
|
||||
expectedJumpIfOutput []string
|
||||
expectedJumpIfNotOutput []string
|
||||
}{
|
||||
{
|
||||
ifaceName: "eth0",
|
||||
expectedJumpIfOutput: []string{"-i", "eth0"},
|
||||
expectedJumpIfNotOutput: []string{"!", "-i", "eth0"},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
localDetector, err := NewDetectLocalByBridgeInterface(c.ifaceName)
|
||||
if err != nil {
|
||||
t.Errorf("Error initializing localDetector: %v", err)
|
||||
continue
|
||||
}
|
||||
if !localDetector.IsImplemented() {
|
||||
t.Error("DetectLocalByBridgeInterface returns false for IsImplemented")
|
||||
}
|
||||
|
||||
ifLocal := localDetector.IfLocal()
|
||||
ifNotLocal := localDetector.IfNotLocal()
|
||||
|
||||
if !reflect.DeepEqual(ifLocal, c.expectedJumpIfOutput) {
|
||||
t.Errorf("IfLocal, expected: '%v', but got: '%v'", c.expectedJumpIfOutput, ifLocal)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(ifNotLocal, c.expectedJumpIfNotOutput) {
|
||||
t.Errorf("IfNotLocal, expected: '%v', but got: '%v'", c.expectedJumpIfNotOutput, ifNotLocal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectLocalByInterfaceNamePrefix(t *testing.T) {
|
||||
cases := []struct {
|
||||
ifacePrefix string
|
||||
chain string
|
||||
args []string
|
||||
expectedJumpIfOutput []string
|
||||
expectedJumpIfNotOutput []string
|
||||
}{
|
||||
{
|
||||
ifacePrefix: "eth0",
|
||||
expectedJumpIfOutput: []string{"-i", "eth0+"},
|
||||
expectedJumpIfNotOutput: []string{"!", "-i", "eth0+"},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
localDetector, err := NewDetectLocalByInterfaceNamePrefix(c.ifacePrefix)
|
||||
if err != nil {
|
||||
t.Errorf("Error initializing localDetector: %v", err)
|
||||
continue
|
||||
}
|
||||
if !localDetector.IsImplemented() {
|
||||
t.Error("DetectLocalByInterfaceNamePrefix returns false for IsImplemented")
|
||||
}
|
||||
|
||||
ifLocal := localDetector.IfLocal()
|
||||
ifNotLocal := localDetector.IfNotLocal()
|
||||
|
||||
if !reflect.DeepEqual(ifLocal, c.expectedJumpIfOutput) {
|
||||
t.Errorf("IfLocal, expected: '%v', but got: '%v'", c.expectedJumpIfOutput, ifLocal)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(ifNotLocal, c.expectedJumpIfNotOutput) {
|
||||
t.Errorf("IfNotLocal, expected: '%v', but got: '%v'", c.expectedJumpIfNotOutput, ifNotLocal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user