github.phpd.cn/cilium/cilium@v1.6.12/pkg/tuple/ipv4.go (about)

     1  // Copyright 2016-2019 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  package tuple
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"unsafe"
    21  
    22  	"github.com/cilium/cilium/common/types"
    23  	"github.com/cilium/cilium/pkg/bpf"
    24  	"github.com/cilium/cilium/pkg/byteorder"
    25  	"github.com/cilium/cilium/pkg/u8proto"
    26  )
    27  
    28  // TupleKey4 represents the key for IPv4 entries in the local BPF conntrack map.
    29  // Address field names are correct for return traffic, i.e., they are reversed
    30  // compared to the original direction traffic.
    31  // +k8s:deepcopy-gen=true
    32  // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapKey
    33  type TupleKey4 struct {
    34  	DestAddr   types.IPv4      `align:"daddr"`
    35  	SourceAddr types.IPv4      `align:"saddr"`
    36  	DestPort   uint16          `align:"dport"`
    37  	SourcePort uint16          `align:"sport"`
    38  	NextHeader u8proto.U8proto `align:"nexthdr"`
    39  	Flags      uint8           `align:"flags"`
    40  }
    41  
    42  // GetKeyPtr returns the unsafe.Pointer for k.
    43  func (k *TupleKey4) GetKeyPtr() unsafe.Pointer { return unsafe.Pointer(k) }
    44  
    45  // NewValue creates a new bpf.MapValue.
    46  func (k *TupleKey4) NewValue() bpf.MapValue { return &TupleValStub{} }
    47  
    48  // ToNetwork converts TupleKey4 ports to network byte order.
    49  func (k *TupleKey4) ToNetwork() TupleKey {
    50  	n := *k
    51  	n.SourcePort = byteorder.HostToNetwork(n.SourcePort).(uint16)
    52  	n.DestPort = byteorder.HostToNetwork(n.DestPort).(uint16)
    53  	return &n
    54  }
    55  
    56  // ToHost converts TupleKey4 ports to host byte order.
    57  func (k *TupleKey4) ToHost() TupleKey {
    58  	n := *k
    59  	n.SourcePort = byteorder.NetworkToHost(n.SourcePort).(uint16)
    60  	n.DestPort = byteorder.NetworkToHost(n.DestPort).(uint16)
    61  	return &n
    62  }
    63  
    64  // GetFlags returns the tuple's flags.
    65  func (k *TupleKey4) GetFlags() uint8 {
    66  	return k.Flags
    67  }
    68  
    69  // String returns the tuple's string representation, doh.
    70  func (k *TupleKey4) String() string {
    71  	return fmt.Sprintf("%s:%d, %d, %d, %d", k.DestAddr, k.SourcePort, k.DestPort, k.NextHeader, k.Flags)
    72  }
    73  
    74  // Dump writes the contents of key to buffer and returns true if the value for
    75  // next header in the key is nonzero.
    76  func (k TupleKey4) Dump(buffer *bytes.Buffer, reverse bool) bool {
    77  	var addrDest string
    78  
    79  	if k.NextHeader == 0 {
    80  		return false
    81  	}
    82  
    83  	// Addresses swapped, see issue #5848
    84  	if reverse {
    85  		addrDest = k.SourceAddr.IP().String()
    86  	} else {
    87  		addrDest = k.DestAddr.IP().String()
    88  	}
    89  
    90  	if k.Flags&TUPLE_F_IN != 0 {
    91  		buffer.WriteString(fmt.Sprintf("%s IN %s %d:%d ",
    92  			k.NextHeader.String(), addrDest, k.SourcePort,
    93  			k.DestPort),
    94  		)
    95  	} else {
    96  		buffer.WriteString(fmt.Sprintf("%s OUT %s %d:%d ",
    97  			k.NextHeader.String(), addrDest, k.DestPort,
    98  			k.SourcePort),
    99  		)
   100  	}
   101  
   102  	if k.Flags&TUPLE_F_RELATED != 0 {
   103  		buffer.WriteString("related ")
   104  	}
   105  
   106  	if k.Flags&TUPLE_F_SERVICE != 0 {
   107  		buffer.WriteString("service ")
   108  	}
   109  
   110  	return true
   111  }
   112  
   113  // TupleKey4Global represents the key for IPv4 entries in the global BPF
   114  // conntrack map.
   115  // +k8s:deepcopy-gen=true
   116  // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapKey
   117  type TupleKey4Global struct {
   118  	TupleKey4
   119  }
   120  
   121  // GetFlags returns the tuple's flags.
   122  func (k *TupleKey4Global) GetFlags() uint8 {
   123  	return k.Flags
   124  }
   125  
   126  // String returns the tuple's string representation, doh.
   127  func (k *TupleKey4Global) String() string {
   128  	return fmt.Sprintf("%s:%d --> %s:%d, %d, %d", k.SourceAddr, k.SourcePort, k.DestAddr, k.DestPort, k.NextHeader, k.Flags)
   129  }
   130  
   131  // ToNetwork converts ports to network byte order.
   132  //
   133  // This is necessary to prevent callers from implicitly converting
   134  // the TupleKey4Global type here into a local key type in the nested
   135  // TupleKey4 field.
   136  func (k *TupleKey4Global) ToNetwork() TupleKey {
   137  	return &TupleKey4Global{
   138  		TupleKey4: *k.TupleKey4.ToNetwork().(*TupleKey4),
   139  	}
   140  }
   141  
   142  // ToHost converts ports to host byte order.
   143  //
   144  // This is necessary to prevent callers from implicitly converting
   145  // the TupleKey4Global type here into a local key type in the nested
   146  // TupleKey4 field.
   147  func (k *TupleKey4Global) ToHost() TupleKey {
   148  	return &TupleKey4Global{
   149  		TupleKey4: *k.TupleKey4.ToHost().(*TupleKey4),
   150  	}
   151  }
   152  
   153  // Dump writes the contents of key to buffer and returns true if the
   154  // value for next header in the key is nonzero.
   155  func (k TupleKey4Global) Dump(buffer *bytes.Buffer, reverse bool) bool {
   156  	var addrSource, addrDest string
   157  
   158  	if k.NextHeader == 0 {
   159  		return false
   160  	}
   161  
   162  	// Addresses swapped, see issue #5848
   163  	if reverse {
   164  		addrSource = k.DestAddr.IP().String()
   165  		addrDest = k.SourceAddr.IP().String()
   166  	} else {
   167  		addrSource = k.SourceAddr.IP().String()
   168  		addrDest = k.DestAddr.IP().String()
   169  	}
   170  
   171  	if k.Flags&TUPLE_F_IN != 0 {
   172  		buffer.WriteString(fmt.Sprintf("%s IN %s:%d -> %s:%d ",
   173  			k.NextHeader.String(), addrSource, k.SourcePort,
   174  			addrDest, k.DestPort),
   175  		)
   176  	} else {
   177  		buffer.WriteString(fmt.Sprintf("%s OUT %s:%d -> %s:%d ",
   178  			k.NextHeader.String(), addrSource, k.SourcePort,
   179  			addrDest, k.DestPort),
   180  		)
   181  	}
   182  
   183  	if k.Flags&TUPLE_F_RELATED != 0 {
   184  		buffer.WriteString("related ")
   185  	}
   186  
   187  	if k.Flags&TUPLE_F_SERVICE != 0 {
   188  		buffer.WriteString("service ")
   189  	}
   190  
   191  	return true
   192  }