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 }