github.com/fafucoder/cilium@v1.6.11/cilium/cmd/bpf_ipcache_get_test.go (about)

     1  // Copyright 2018 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // +build privileged_tests
    16  
    17  package cmd
    18  
    19  import (
    20  	"fmt"
    21  	"net"
    22  
    23  	"github.com/cilium/cilium/pkg/checker"
    24  
    25  	. "gopkg.in/check.v1"
    26  )
    27  
    28  type BPFIPCacheGetSuite struct{}
    29  
    30  var _ = Suite(&BPFIPCacheGetSuite{})
    31  
    32  func (s *BPFIPCacheGetSuite) TestGetPrefix(c *C) {
    33  	tests := []struct {
    34  		ip     net.IP
    35  		prefix []byte
    36  		length int
    37  	}{
    38  		{
    39  			ip:     mustParseIP("213.234.255.89"),
    40  			prefix: []byte{0xD5, 0xEA, 0xFF, 0x59},
    41  			length: 8 * net.IPv4len,
    42  		},
    43  		{
    44  			ip:     mustParseIP("f0ed:0db8:cafe:0000:0000:beef:0042:8329"),
    45  			prefix: []byte{0xf0, 0xed, 0x0d, 0xb8, 0xca, 0xfe, 0, 0, 0, 0, 0xbe, 0xef, 0x00, 0x42, 0x83, 0x29},
    46  			length: 8 * net.IPv6len,
    47  		},
    48  	}
    49  
    50  	for _, tt := range tests {
    51  		prefix := toBits(tt.prefix)
    52  		for maskSize := 0; maskSize <= tt.length; maskSize++ {
    53  			c.Assert(getPrefix(tt.ip, maskSize), checker.DeepEquals, prefix[:maskSize], Commentf("invalid prefix for %v/%v", tt.ip, maskSize))
    54  		}
    55  	}
    56  }
    57  
    58  func (s *BPFIPCacheGetSuite) TestGetLPMValue(c *C) {
    59  	entries := map[string][]string{}
    60  	entries["10.0.0.0/8"] = []string{"2"}
    61  	entries["10.0.0.0/16"] = []string{"9"}
    62  	entries["10.0.0.0/32"] = []string{"8"}
    63  	entries["10.128.0.0/9"] = []string{"4", "20"}
    64  	entries["feed::ed/112"] = []string{"3"}
    65  	entries["feed::feed/128"] = []string{"5", "17"}
    66  
    67  	tests := []struct {
    68  		ip          string   // Input ip address.
    69  		hasIdentity bool     // true if a match should be found.
    70  		identity    []string // Expected identity if match should be found.
    71  	}{
    72  		{"10.1.0.0", true, entries["10.0.0.0/8"]},
    73  		{"10.1.0.255", true, entries["10.0.0.0/8"]},
    74  		{"10.0.1.0", true, entries["10.0.0.0/16"]},
    75  		{"10.0.0.0", true, entries["10.0.0.0/32"]},
    76  		{"10.127.255.255", true, entries["10.0.0.0/8"]},
    77  		{"10.128.255.255", true, entries["10.128.0.0/9"]},
    78  		{"10.255.255.255", true, entries["10.128.0.0/9"]},
    79  		{ip: "12.0.0.1", hasIdentity: false},
    80  		{"feed::ffed", true, entries["feed::ed/112"]},
    81  		{"feed::feed", true, entries["feed::feed/128"]},
    82  	}
    83  
    84  	for _, tt := range tests {
    85  		v, exists := getLPMValue(mustParseIP(tt.ip), entries)
    86  
    87  		c.Assert(exists, Equals, tt.hasIdentity, Commentf("No identity was found for ip '%s': wanted '%s'", tt.ip, tt.identity))
    88  
    89  		if exists {
    90  			identity := v.([]string)
    91  			c.Assert(identity, checker.DeepEquals, tt.identity, Commentf("Wrong identity was retrieved for ip %s", tt.ip))
    92  		}
    93  	}
    94  }
    95  
    96  func mustParseIP(s string) net.IP {
    97  	ip := net.ParseIP(s)
    98  
    99  	if ip == nil {
   100  		panic(fmt.Errorf("%s is not a valid ip", s))
   101  	}
   102  
   103  	if isIPV4(ip) {
   104  		ip = ip.To4()
   105  	}
   106  
   107  	return ip
   108  }
   109  
   110  func toBits(bytes []byte) []byte {
   111  	var bits []byte
   112  
   113  	for _, b := range bytes {
   114  		for j := 0; j < 8; j++ {
   115  			mask := uint8(128) >> uint8(j)
   116  
   117  			if mask&b == 0 {
   118  				bits = append(bits, 0x0)
   119  			} else {
   120  				bits = append(bits, 0x1)
   121  			}
   122  		}
   123  	}
   124  
   125  	return bits
   126  }