mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +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 {
|
func (d *detectLocalByCIDR) IfNotLocal() []string {
|
||||||
return d.ifNotLocal
|
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