github.com/cilium/cilium@v1.16.2/pkg/types/portmap_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package types
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/cilium/cilium/pkg/u8proto"
    12  )
    13  
    14  func TestPolicyValidateName(t *testing.T) {
    15  	name, err := ValidatePortName("Http")
    16  	require.Nil(t, err)
    17  	require.Equal(t, "http", name)
    18  
    19  	name, err = ValidatePortName("dns-tcp")
    20  	require.Nil(t, err)
    21  	require.Equal(t, "dns-tcp", name)
    22  
    23  	_, err = ValidatePortName("-http")
    24  	require.NotNil(t, err)
    25  
    26  	_, err = ValidatePortName("http-")
    27  	require.NotNil(t, err)
    28  
    29  	name, err = ValidatePortName("http-80")
    30  	require.Nil(t, err)
    31  	require.Equal(t, "http-80", name)
    32  
    33  	_, err = ValidatePortName("http--s")
    34  	require.NotNil(t, err)
    35  }
    36  
    37  func TestPolicyNewPortProto(t *testing.T) {
    38  	np, err := newPortProto(80, "tcp")
    39  	require.Nil(t, err)
    40  	require.Equal(t, PortProto{Port: uint16(80), Proto: uint8(6)}, np)
    41  
    42  	_, err = newPortProto(88888, "tcp")
    43  	require.NotNil(t, err)
    44  	require.Equal(t, "Port number 88888 out of 16-bit range", err.Error())
    45  
    46  	_, err = newPortProto(80, "cccp")
    47  	require.NotNil(t, err)
    48  	require.Equal(t, "unknown protocol 'cccp'", err.Error())
    49  
    50  	np, err = newPortProto(88, "")
    51  	require.Nil(t, err)
    52  	require.Equal(t, PortProto{Port: uint16(88), Proto: uint8(6)}, np)
    53  }
    54  
    55  func TestPolicyNamedPortMap(t *testing.T) {
    56  	npm := make(NamedPortMap)
    57  
    58  	err := npm.AddPort("http", 80, "tcp")
    59  	require.Nil(t, err)
    60  	require.Len(t, npm, 1)
    61  
    62  	err = npm.AddPort("dns", 53, "UDP")
    63  	require.Nil(t, err)
    64  	require.Len(t, npm, 2)
    65  
    66  	err = npm.AddPort("zero", 0, "TCP")
    67  	require.Equal(t, ErrNamedPortIsZero, err)
    68  	require.Len(t, npm, 2)
    69  
    70  	proto, err := u8proto.ParseProtocol("UDP")
    71  	require.Nil(t, err)
    72  	require.Equal(t, uint8(17), uint8(proto))
    73  
    74  	port, err := npm.GetNamedPort("dns", uint8(proto))
    75  	require.Nil(t, err)
    76  	require.Equal(t, uint16(53), port)
    77  
    78  	port, err = npm.GetNamedPort("dns", uint8(6))
    79  	require.Equal(t, ErrIncompatibleProtocol, err)
    80  	require.Equal(t, uint16(0), port)
    81  
    82  	port, err = npm.GetNamedPort("unknown", uint8(proto))
    83  	require.Equal(t, ErrUnknownNamedPort, err)
    84  	require.Equal(t, uint16(0), port)
    85  }
    86  
    87  func TestPolicyPortProtoSet(t *testing.T) {
    88  	a := PortProtoSet{
    89  		PortProto{Port: 80, Proto: 6}:  1,
    90  		PortProto{Port: 443, Proto: 6}: 1,
    91  		PortProto{Port: 53, Proto: 17}: 1,
    92  	}
    93  	b := PortProtoSet{
    94  		PortProto{Port: 80, Proto: 6}:  1,
    95  		PortProto{Port: 443, Proto: 6}: 1,
    96  		PortProto{Port: 53, Proto: 6}:  1,
    97  	}
    98  	require.Equal(t, true, a.Equal(a))
    99  	require.Equal(t, false, a.Equal(b))
   100  	require.Equal(t, true, b.Equal(b))
   101  }
   102  
   103  func TestPolicyNamedPortMultiMap(t *testing.T) {
   104  	a := &namedPortMultiMap{
   105  		m: map[string]PortProtoSet{
   106  			"http": {
   107  				PortProto{Port: 80, Proto: 6}:   1,
   108  				PortProto{Port: 8080, Proto: 6}: 1,
   109  			},
   110  			"https": {
   111  				PortProto{Port: 443, Proto: 6}: 1,
   112  			},
   113  			"zero": {
   114  				PortProto{Port: 0, Proto: 6}: 1,
   115  			},
   116  			"none": {},
   117  			"dns": {
   118  				PortProto{Port: 53, Proto: 17}: 1,
   119  				PortProto{Port: 53, Proto: 6}:  1,
   120  			},
   121  		},
   122  	}
   123  	b := &namedPortMultiMap{
   124  		m: map[string]PortProtoSet{
   125  			"http": {
   126  				PortProto{Port: 80, Proto: 6}:   1,
   127  				PortProto{Port: 8080, Proto: 6}: 1,
   128  			},
   129  			"https": {
   130  				PortProto{Port: 443, Proto: 6}: 1,
   131  			},
   132  			"zero": {
   133  				PortProto{Port: 0, Proto: 6}: 1,
   134  			},
   135  			"none": {},
   136  			"dns": {
   137  				PortProto{Port: 53, Proto: 0}: 1,
   138  			},
   139  		},
   140  	}
   141  
   142  	port, err := a.GetNamedPort("http", 6)
   143  	require.Equal(t, ErrDuplicateNamedPorts, err)
   144  	require.Equal(t, uint16(0), port)
   145  
   146  	port, err = a.GetNamedPort("http", 17)
   147  	require.Equal(t, ErrIncompatibleProtocol, err)
   148  	require.Equal(t, uint16(0), port)
   149  
   150  	port, err = a.GetNamedPort("zero", 6)
   151  	require.Equal(t, ErrNamedPortIsZero, err)
   152  	require.Equal(t, uint16(0), port)
   153  
   154  	port, err = a.GetNamedPort("none", 6)
   155  	require.Equal(t, ErrUnknownNamedPort, err)
   156  	require.Equal(t, uint16(0), port)
   157  
   158  	port, err = a.GetNamedPort("unknown", 6)
   159  	require.Equal(t, ErrUnknownNamedPort, err)
   160  	require.Equal(t, uint16(0), port)
   161  
   162  	var nilvalued *namedPortMultiMap
   163  	port, err = NamedPortMultiMap(nilvalued).GetNamedPort("unknown", 6)
   164  	require.Equal(t, ErrNilMap, err)
   165  	require.Equal(t, uint16(0), port)
   166  
   167  	port, err = a.GetNamedPort("https", 6)
   168  	require.Nil(t, err)
   169  	require.Equal(t, uint16(443), port)
   170  
   171  	port, err = a.GetNamedPort("dns", 6)
   172  	require.Nil(t, err)
   173  	require.Equal(t, uint16(53), port)
   174  
   175  	port, err = b.GetNamedPort("dns", 6)
   176  	require.Nil(t, err)
   177  	require.Equal(t, uint16(53), port)
   178  
   179  	port, err = a.GetNamedPort("dns", 17)
   180  	require.Nil(t, err)
   181  	require.Equal(t, uint16(53), port)
   182  
   183  	port, err = b.GetNamedPort("dns", 17)
   184  	require.Nil(t, err)
   185  	require.Equal(t, uint16(53), port)
   186  }
   187  
   188  func TestPolicyNamedPortMultiMapUpdate(t *testing.T) {
   189  	npm := NewNamedPortMultiMap()
   190  
   191  	pod1PortsOld := map[string]PortProto{}
   192  	pod1PortsNew := map[string]PortProto{
   193  		"http": {80, uint8(u8proto.TCP)},
   194  	}
   195  
   196  	// Insert http=80/TCP from pod1
   197  	changed := npm.Update(pod1PortsOld, pod1PortsNew)
   198  	require.Equal(t, true, changed)
   199  
   200  	// No changes
   201  	changed = npm.Update(pod1PortsNew, pod1PortsNew)
   202  	require.Equal(t, false, changed)
   203  
   204  	// Assert http=80/TCP
   205  	port, err := npm.GetNamedPort("http", uint8(u8proto.TCP))
   206  	require.Nil(t, err)
   207  	require.Equal(t, uint16(80), port)
   208  
   209  	pod2PortsOld := map[string]PortProto{}
   210  	pod2PortsNew := map[string]PortProto{
   211  		"http": {8080, uint8(u8proto.UDP)},
   212  	}
   213  
   214  	// Insert http=8080/UDP from pod2, retain http=80/TCP from pod1
   215  	changed = npm.Update(pod2PortsOld, pod2PortsNew)
   216  	require.Equal(t, true, changed)
   217  
   218  	port, err = npm.GetNamedPort("http", uint8(u8proto.TCP))
   219  	require.Nil(t, err)
   220  	require.Equal(t, uint16(80), port)
   221  	port, err = npm.GetNamedPort("http", uint8(u8proto.UDP))
   222  	require.Nil(t, err)
   223  	require.Equal(t, uint16(8080), port)
   224  
   225  	// Delete http=80/TCP from pod1, retain http=8080/UDP from pod2
   226  	pod1PortsOld = pod1PortsNew
   227  	pod1PortsNew = map[string]PortProto{}
   228  
   229  	// Delete http=80/TCP from pod1
   230  	changed = npm.Update(pod1PortsOld, pod1PortsNew)
   231  	require.Equal(t, true, changed)
   232  
   233  	port, err = npm.GetNamedPort("http", uint8(u8proto.UDP))
   234  	require.Nil(t, err)
   235  	require.Equal(t, uint16(8080), port)
   236  }