github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/operators/ebpf/params.go (about)

     1  // Copyright 2024 The Inspektor Gadget authors
     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 ebpfoperator
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/cilium/ebpf/btf"
    21  
    22  	"github.com/inspektor-gadget/inspektor-gadget/pkg/btfhelpers"
    23  	"github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-service/api"
    24  	"github.com/inspektor-gadget/inspektor-gadget/pkg/params"
    25  )
    26  
    27  func getTypeHint(typ btf.Type) params.TypeHint {
    28  	switch typedMember := typ.(type) {
    29  	case *btf.Int:
    30  		switch typedMember.Encoding {
    31  		case btf.Signed:
    32  			switch typedMember.Size {
    33  			case 1:
    34  				return params.TypeInt8
    35  			case 2:
    36  				return params.TypeInt16
    37  			case 4:
    38  				return params.TypeInt32
    39  			case 8:
    40  				return params.TypeInt64
    41  			}
    42  		case btf.Unsigned:
    43  			switch typedMember.Size {
    44  			case 1:
    45  				return params.TypeUint8
    46  			case 2:
    47  				return params.TypeUint16
    48  			case 4:
    49  				return params.TypeUint32
    50  			case 8:
    51  				return params.TypeUint64
    52  			}
    53  		case btf.Bool:
    54  			return params.TypeBool
    55  		case btf.Char:
    56  			return params.TypeUint8
    57  		}
    58  	case *btf.Float:
    59  		switch typedMember.Size {
    60  		case 4:
    61  			return params.TypeFloat32
    62  		case 8:
    63  			return params.TypeFloat64
    64  		}
    65  	case *btf.Typedef:
    66  		typ := btfhelpers.GetUnderlyingType(typedMember)
    67  		if typ == nil {
    68  			return params.TypeUnknown
    69  		}
    70  		return getTypeHint(typ)
    71  	case *btf.Volatile:
    72  		return getTypeHint(typedMember.Type)
    73  	}
    74  
    75  	return params.TypeUnknown
    76  }
    77  
    78  func (i *ebpfInstance) populateParam(t btf.Type, varName string) error {
    79  	if _, found := i.params[varName]; found {
    80  		i.logger.Debugf("param %q already defined, skipping", varName)
    81  		return nil
    82  	}
    83  
    84  	var btfVar *btf.Var
    85  	err := i.collectionSpec.Types.TypeByName(varName, &btfVar)
    86  	if err != nil {
    87  		return fmt.Errorf("no BTF type found for: %s: %w", varName, err)
    88  	}
    89  
    90  	btfConst, ok := btfVar.Type.(*btf.Const)
    91  	if !ok {
    92  		return fmt.Errorf("type for %s is not a constant, got %s", varName, btfVar.Type)
    93  	}
    94  
    95  	th := getTypeHint(btfConst.Type)
    96  
    97  	i.logger.Debugf("adding param %q (%v)", btfVar.Name, th)
    98  
    99  	newParam := &api.Param{
   100  		Key:      varName,
   101  		TypeHint: string(th),
   102  	}
   103  
   104  	// Fill additional information from metadata
   105  	paramInfo := i.config.Sub("params." + varName)
   106  	if paramInfo == nil {
   107  		// Backward compatibility
   108  		paramInfo = i.config.Sub("ebpfParams." + varName)
   109  	}
   110  	if paramInfo != nil {
   111  		i.logger.Debugf(" filling additional information from metadata")
   112  		if s := paramInfo.GetString("key"); s != "" {
   113  			newParam.Key = s
   114  		}
   115  		if s := paramInfo.GetString("defaultValue"); s != "" {
   116  			newParam.DefaultValue = s
   117  		}
   118  		if s := paramInfo.GetString("description"); s != "" {
   119  			newParam.Description = s
   120  		}
   121  	}
   122  
   123  	i.params[varName] = &param{
   124  		Param:    newParam,
   125  		fromEbpf: true,
   126  	}
   127  	return nil
   128  }